openboxes-docs Documentation
Release 0.7.18
Justin Miranda
Jan 18, 2020
Overview
1 Getting Started 3
2 Features 5
3 Benefits 7
4 Considerations 9
5 Support 11
6 Release Notes 15
7 Installation Guide 17
8 Configuration 23
9 User Guide 29
10 Developer Guide 31
i
ii
openboxes-docs Documentation, Release 0.7.18
OpenBoxes is an open-source supply chain management system designed to manage supplies and medications for
healthcare facilities and disaster response operations.
Overview 1
openboxes-docs Documentation, Release 0.7.18
2 Overview
CHAPTER 1
Getting Started
3
openboxes-docs Documentation, Release 0.7.18
4 Chapter 1. Getting Started
CHAPTER 2
Features
5
openboxes-docs Documentation, Release 0.7.18
6 Chapter 2. Features
CHAPTER 3
Benefits
3.1 Free, open-source software
OpenBoxes is entirely free to use. This can be a significant advantage in the face of limited operational resources.
3.2 Inventory Visibility & Tracking
Not only does OpenBoxes allow you to view your inventory at a glance, it provides a historical record of
inventory transactions. This data is invaluable to accurately understand and forecast demand for future planning
periods.
OpenBoxes allows you to set inventory max, min, and reorder points — this allows the user to quickly assess if
supplies are overstocked, at appropriate stock levels, or in danger of being out of stock if not reordered soon.
OpenBoxes allows you to record the movement of goods from multiple sources and across different levels of
the organization:
From central warehouses to your facility depot
From other hospital facilities to your facility depot
From vendor warehouses to your facility depot
From one warehouse to other warehouses within your network
From your facility depot to pharmacies and wards within your facility
Record lot numbers for items that have an expiry date to help identify stock that has expired or is about to expire.
Lot numbers also provide a means to locate stock when a manufacturer recalls a certain item.
Record serial numbers for items that require lifecycle management (including assets such as computers, routers,
hospital beds).
Upload and manage documents for each product (e.g. data sheets, product manuals, hazardous material handling
requirements).
7
openboxes-docs Documentation, Release 0.7.18
3.3 Shipping Documents
OpenBoxes offers the user the ability to produce Certificates of Donation, Packing Lists, and other documents
required for shipping with just a few mouse clicks.
Documents can also be uploaded to OpenBoxes to allow operational leadership to save all the relevant shipping
documents to a particular shipment within the system.
3.4 Grant Compliance
Certain grants require that inventory be tracked in very specific ways. Using OpenBoxes comprehensively would
allow a site to account for the movement of goods bought with grant monies from vendor, to country, to facility
— and the consumption of those items at a facility level.
3.5 Integration with Demand & Forecasting software
While the OpenBoxes stock usage history can provide a high-level picture of future demand for any particu-
lar item, integrating with demand forecasting software will allow those processes to be automated and more
accurate.
3.6 Integration with Data Replication software
While OpenBoxes supports a hierachy of locations, sometimes it’s not possible for all locations to access a
centralized server due to power and Internet limitations at that site. In this case, you can manage multiple server
installations (a central OpenBoxes server for most locations with good Internet) and separate OB server for each
location that does not have a reliable connection to the Internet. Using SymmetricDS, you can bi-directionally
sync all data changes between each of these servers.
8 Chapter 3. Benefits
CHAPTER 4
Considerations
While open-source software is free to download and use, there are costs and limitations that should be taken into
consideration before you begin the adoption process.
4.1 System Administration
An OpenBoxes installation requires a system administrator to install, monitor, maintain, and upgrade the software and
server components throughout the software lifecycle. These tasks require competent IT personnel.
4.2 Time
While OpenBoxes has been streamlined considerably since its creation, there may be significant time costs associated
with using this inventory management system.
Examples of potentially time-intensive tasks include, but are not limited to:
Master Data Management e.g. creating products to track within the system
Periodic Reviews e.g. stock counts, min/max/reorder review, fast moving vs. obsolete inventory
Data Entry e.g. recording and adjusting inventory
Forecasting e.g. period review of demand/consumption data, disease incidence, population growth, service
expansion within the hospital
4.3 Training
While OpenBoxes is a relatively simple inventory management tool, some training is required to allow users to suc-
cessfully utilize all of the functionality offered by the system.
9
openboxes-docs Documentation, Release 0.7.18
4.4 Hospital-Centric
While OpenBoxes could be used by small-to-medium-sized enterprises (SME) in most industries, there are some
limitations that might make it difficult to use:
1) OpenBoxes does not have a Sales Order feature yet. There’s not an overwhleming need for such a feature within
the hospital. For now, you can create a new location to represent a customer, generate a PO for that location
(customer) against your facility depot, and fulfill that PO in order to approximate a Sales Order. This feature
will eventually be implemented as pharmacists would like to generate a sales order when filling a prescription
for a patient.
2) The Requisition feature (i.e. Pull Replenishment) which is used to move stock from a facility depot to a point-
of-service location (e.g. ward, pharmacy) is primarily used within the depot. In other words, Requisitions are
created by a warehouse manager within the hospital depot instead of by the requesting party (i.e. a nurse or
pharmacist).
This was a decision made in order to save time and avoid the need for adding time-intensive processes for nurses and
pharmacists. In the use case at Mirebalis Hospital, nurses and pharmacists will send a paper requisitions to the hospital
depot, warehouse staff will enter the requisition into the system and proceed to fulfill that requisition. OpenBoxes will
eventually have a point-of-service (POS) client for nurses and pharmacists to request stock from the depot, but that
feature is not currently in development.
4.5 Static Role-based Authorization
The OpenBoxes authorization mechanism currently only provides three roles (Admin, Manager, and Browser). This
limits the ability for an administrator to create roles based on fine-grained permissions. For example, all Manager
users have the ability to perform CRUD actions (create, retrieve, update, delete) on most objects within the system.
However, I cannot create a new role (e.g. Shift Manager) that allows a user to create a Product, but not a Purchase
Order. A more fine-grained approach will be implemented in a future version of OpenBoxes.
10 Chapter 4. Considerations
CHAPTER 5
Support
If you have questions, concerns, or issues with the software, documentation, or anything else (excluding complaints
about POTUS) contact our Support Team through the various support channels. Or safe yourself the extra click and
just email us at [email protected].
11
openboxes-docs Documentation, Release 0.7.18
12 Chapter 5. Support
openboxes-docs Documentation, Release 0.7.18
5.1 Community Support
5.1.1 Bug Reports & Feature Requests
You can file bug reports on our GitHub issue tracker, and they will be addressed as soon as possible. Support is a
volunteer effort, and there is no guaranteed response time.
If you need answers quickly, you can contact us about commercial support (see below).
5.1.2 Reporting Issues
When reporting a bug or requesting a feature, please include as much information as possible, including but not limited
to:
Summary
Steps to reproduce
Screenshot(s)
5.2 Commercial Support
We offer commercial support, hosting, and consulting. Please email us at support@openboxes.com for more informa-
tion.
Oliver
5.1. Community Support 13
openboxes-docs Documentation, Release 0.7.18
14 Chapter 5. Support
CHAPTER 6
Release Notes
See GitHub for Release Notes.
15
openboxes-docs Documentation, Release 0.7.18
16 Chapter 6. Release Notes
CHAPTER 7
Installation Guide
7.1 Ubuntu 14.04
7.1.1 1. Watch the Video
NOTE: If the video does not render properly above you can watch it directly on YouTube.
7.1.2 2. Choose a cloud provider
Here are a few options for cheapish cloud hosting providers.
RimuHosting - Customizable VPS (~20/month)
Amazon Web Services EC2 - t2.small 2GB (~$20/month)
Google Compute Engine - g1-small 1.7GB (~$20/month)
Digital Ocean droplet - Droplet 2GB ($20/month)
Linode - Linode 2GB ($10/month)
NOTE: AWS has a free-tier that includes a free year of 750 hours per month for t2.micro EC2 instances (as well as
other services). It’s a great deal it if you’re not going to be using OpenBoxes too heavily. Unfortunately, keeping a
Java-based web application like OpenBoxes happy on a t2.micro (1GB of RAM) is not easy. You may need to reduce
the heap size and perm generation memory allocated to Tomcat to something minimal (see step 5 for more details).
7.1.3 3. Install dependencies
Required
Ubuntu 14.04 LTS (your cloud provider should allow you to choose this as the base image for your server)
Tomcat 7 (sudo apt-get install tomcat7)
17
openboxes-docs Documentation, Release 0.7.18
MySQL 5.5+ (sudo apt-get install mysql-server)
JRE 7 (sudo apt-get install openjdk-7-jre)
Optional dependencies
SMTP Server (runs over localhost:25 by default)
Chrome Browser (currently using Version 29.0.1547.57)
7.1.4 4. Create database
$ mysql -u root -p -e 'create database openboxes default charset utf8;'
Grant permissions to new new database user
mysql -u root -p -e 'grant all on openboxes.
*
to 'openboxes'@'localhost' identified
˓by "<password>";'
NOTE: For security reasons, you will want to set a decent password. These values should be used in the
dataSource.username and dataSource.password configuration properties in openboxes-config.
properties.
7.1.5 5. Configure application properties
Download the sample external configuration properties file (openboxes-config.properties) and save it under /usr/
share/tomcat7/.grails/openboxes-config.properties.
REMINDER: Change dataSource.password to the password you set in the grant all command above.
Here’s another example of the openboxes-config.properties file:
# Database connection settings
dataSource.username=openboxes
dataSource.password=<password>
# Example of a simple JDBC URL (not to be used in production)
dataSource.url=jdbc:mysql://localhost:3306/openboxes
# Example of a more complex JDBC URL (used in our ccurent production environment)
#dataSource.url=jdbc:mysql://localhost:3306/openboxes?autoReconnect=true&
˓zeroDateTimeBehavior=convertToNull&sessionVariables=storage_engine=InnoDB
# Used primarily with g:link when absoluteUrl is true (e.g. links in emails)
grails.serverURL=http://localhost:8080/openboxes
# OpenBoxes mail settings - disabled by default (unless you set up an SMTP server)
grails.mail.enabled=false
# SMTP error appender type
mail.error.appender=dynamic
# Miscellaneous application settings
inventoryBrowser.quickCategories=ARVs,MEDICAL SUPPLIES,FOOD,EQUIPMENT,MEDICINE
(continues on next page)
18 Chapter 7. Installation Guide
openboxes-docs Documentation, Release 0.7.18
(continued from previous page)
# The following property seems to be causing issues, so comment it out to use the
˓system default
#openboxes.loginLocation.requiredActivities = ["MANAGE_INVENTORY"]
# Google Product Search
#google.api.key=<Google API key>
# Hipaaspace.com API (NDC Lookup)
#hipaaspace.api.key=<hipaaspace API key>
# RXNorm API
#rxnorm.api.key=<RxNorm API key>
# Google analytics
#google.analytics.enabled = false
#google.analytics.webPropertyID = <Google Analytics Key>
NOTE: Documentation for each available configuration will be provided in the Configuration section.
7.1.6 6. Configure Tomcat
You will likely encounter OutOfMemoryErrors with Tomcat’s default memory settings. Therefore, I usually add a file
(/usr/share/tomcat7/bin/setenv.sh) that is invoked by the Tomcat startup script and is used to control
the amount of memory allocated to your instance of Tomcat.
A basic setenv.sh script will look like this:
export CATALINA_OPTS="$CATALINA_OPTS -server -Xms512m -Xmx1024m -XX:MaxPermSize=256m -
˓Djava.security.egd=file:/dev/./urandom"
Make the script executable.
$ sudo chmod +x /usr/share/tomcat7/bin/setenv.sh
You may be able to get away with using 256m as the max heap size, but 512m is a good setting, even for production
environments. Using more memory will allow you to cache more data, but does not always result in a better performing
application. So there’s no need in getting carried away. We’ve been using about 1024m in production for over a year
and that suits us fine.
If you are in a limited memory environment (like an EC2 t2.micro which only has 1GB of memory) you will need to
tune these command line arguments a little more.
export CATALINA_OPTS="$CATALINA_OPTS -Xms128m -Xmx256m -XX:MaxPermSize=128m -Djava.
˓security.egd=file:/dev/./urandom"
Unfortunately you will probably run into several types of memory issues when running OpenBoxes in a short amount
of memory. Here are a few examples to look out for.
Java OutOfMemoryError
The following errors are related to the -Xms (min heap), -Xmx (max heap) , and -XX:MaxPermSize=256m (max
perm gen space) memory settings. These errors indicate that the heap / permgen memory spaces are not allocated
appropriately and/or there’s a memory leak in the application.
Heap space (OutOfMemoryError: Java heap space)
7.1. Ubuntu 14.04 19
openboxes-docs Documentation, Release 0.7.18
PermGen (OutOfMemoryError: PermGen space)
See [this article] (https://plumbr.eu/outofmemoryerror/java-heap-space) for a good description of the problem. Contact
[email protected] if you have further questions.
Out of Memory: Killed process 31088 (java)
In this case, the Linux kernel has killed your Tomcat instance because it over stepped the OS bounds on memory. At
this point, you may have increased the max heap size as much as you can. This probably means you need to upgrade
to a larger instance type (i.e. as we mentioned above, an instance type that has 2GB of memory is a good start).
7.1.7 7. Deploy the application to Tomcat
Stop tomcat
$ sudo service tomcat7 stop
Download latest release
Go to the the latest release page on GitHub.
Download the WAR file (openboxes.war) associated with the latest release.
If you wanted to do this from the shell use wget with the following URL to get the latest WAR file.
$ wget https://github.com/openboxes/openboxes/releases/download/<version>/openboxes.
˓war
Copy WAR file to Tomcat
$ sudo cp openboxes.war /var/lib/tomcat7/webapps/openboxes.war
NOTE: If you’d like to deploy the application to the root context (to avoid having /openboxes) in every URL, you can
copy the
$ sudo cp openboxes.war /var/lib/tomcat7/webapps/ROOT.war
Restart Tomcat
$ sudo service tomcat7 start
Tail Tomcat logs
Keep an eye out for any errors/exceptions that pop up in the catalina.out log file.
$ tail -f /var/log/tomcat7/catalina.out
20 Chapter 7. Installation Guide
openboxes-docs Documentation, Release 0.7.18
7.2 Mac OS
7.2.1 Looking to contribute?
We would love if someone with a Mac could create a pull request to add installation instructions for the Mac.
7.3 Windows
7.3.1 Looking to contribute?
We would love for someone running Windows to create a pull request to add installation instructions for Windows.
7.4 Supported Platforms
Ubuntu 14.04 (recommended)
Mac 10.6+
Windows (whatever)
7.5 System Requirements
Java 7 (required)
Tomcat 7 or 8 (required)
MySQL 5.5+ (required)
SMTP server (optional)
Chrome or Firefox (required)
7.6 Basic Instructions
1. Install pre-requisites
2. Download latest release
3. Create new database in MySQL
4. Grant permissions to new database user
5. Configure runtime properties (openboxes-config.properties)
6. Copy WAR file to Tomcat
7. Configure Tomcat
8. Start Tomcat
9. Watch the Tomcat logs during startup
10. Open application using Chrome browser
7.2. Mac OS 21
openboxes-docs Documentation, Release 0.7.18
22 Chapter 7. Installation Guide
CHAPTER 8
Configuration
8.1 Configuration file location
As mentioned in the installation instructions, you can override application configuration properties by creating a file
called $USER_HOME/.grails/openboxes-config.properties. If you are a developer, $USER_HOME
should resolve to your home directory (e.g. /home/jmiranda on Ubuntu). If you are deploying the application to
Tomcat, the file is usually located under the TOMCAT_HOME/.grails/openboxes-config.properties.
If you are having trouble locating where the application is looking for the file you can determine the path by deploying
the application to Tomcat and checking the log file. The first few lines of the Tomcat catalina.out file display the
path(s) being used. You can safely ignore the “Unable to load specified config location” for the locations that you
are not using. Notice below that there are 4 configuration locations and only 3 Unable to load specified
config location lines. That means that there was a file found at one of the locations (namely, file:/usr/
local/tomcat6/.grails/openboxes-config.properties.
INFO: Deploying web application archive openboxes.war
Using configuration locations [classpath:openboxes-config.groovy, classpath:openboxes-
˓config.properties,
file:/usr/local/tomcat6/.grails/openboxes-config.groovy, file:/usr/local/tomcat6/.
˓grails/openboxes-
config.properties] [staging]
Unable to load specified config location classpath:openboxes-config.groovy : class
˓path resource
[openboxes-config.groovy] cannot be opened because it does not exist
Unable to load specified config location classpath:openboxes-config.properties :
˓class path resource
[openboxes-config.properties] cannot be opened because it does not exist
Unable to load specified config location file:/usr/local/tomcat6/.grails/openboxes-
˓config.groovy :
/usr/local/tomcat6/.grails/openboxes-config.groovy (No such file or directory)
23
openboxes-docs Documentation, Release 0.7.18
8.2 Configuration properties
8.2.1 Database connection properties
Setting Required Description
dataSource.url Yes JDBC connection string
dataSource.username Yes JDBC username
dataSource.password Yes JDBC password
Example
dataSource.url=jdbc:mysql://localhost:3306/openboxes
dataSource.username=<username>
dataSource.password=<password>
8.2.2 Application properties
Setting Re-
quired
Description
openboxes.
signup.
defaultRoles
No Used to specify default roles assigned to newly registered users (implies automatic acti-
vation). Should only be used in cases where you either trust your registered users e.g. app
is running on local LAN or you don’t care who is allowed to access your server (e.g. a
demo server).
openboxes.
system.
defaultTimezone
No Not currently supported
openboxes.system.defaultTimezone | No | Not currently supported |
Example
#openboxes.fixtures.enabled=false
openboxes.signup.defaultRoles=ROLE_MANAGER,ROLE_ASSISTANT
openboxes.system.defaultTimezone=America/Chicago
8.2.3 Email Configuration
Default
The default email configuration properties.
grails.mail.host=localhost
grails.mail.port=25
24 Chapter 8. Configuration
openboxes-docs Documentation, Release 0.7.18
Mandrill
Add the following properties if you want to use a service like Mandrill as your SMTP server.
grails.mail.enabled=true
grails.mail.debug=true
grails.mail.from=<from-email>
grails.mail.host=smtp.mandrillapp.com
grails.mail.port=587
grails.mail.username=<username>
grails.mail.password=<password>
GMail
Add the following properties if you want to use Gmail as your SMTP server.
grails.mail.enabled=true
grails.mail.debug=true
grails.mail.from=<from-email>
grails.mail.host=smtp.gmail.com
grails.mail.port=465
grails.mail.username=<your-username>
grails.mail.password=<password-generated-from-google-accounts>
grails.mail.props = ["mail.smtp.auth":"true", "mail.smtp.socketFactory.port":"465",
˓"mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory", "mail.smtp.
˓socketFactory.fallback":"false"]
NOTE: I have not been able to able to get the Gmail configuration to work, but I’m sure someone with more time and
intelligence will have no trouble figuring it out.
8.2.4 Identifier Formats
You can configure all of the identifiers according to your specifications (N = Numeric, L = Letter, A = Alphanumeric).
The default configuration looks like the following, but feel free to configure identifiers however you’d like. Once the
format has been choosen, values for these identifiers are randomly generated when an item is created. There’s also
a Quartz process that runs in the background that generates a unique identifier for any object that does not currently
have one.
openboxes.identifier.order.format = NNNLLL
openboxes.identifier.product.format = LLNN
openboxes.identifier.requisition.format = NNNLLL
openboxes.identifier.shipment.format = NNNLLL
openboxes.identifier.transaction.format = AAA-AAA-AAA
8.3 Configuration Example (openboxes-config.properties)
This is an example configuration file.
# Database connection settings
dataSource.url=jdbc:mysql://localhost:3306/openboxes
dataSource.username=openboxes
dataSource.password=openboxes
(continues on next page)
8.3. Configuration Example (openboxes-config.properties) 25
openboxes-docs Documentation, Release 0.7.18
(continued from previous page)
# OpenBoxes administrator emails
openboxes.admin.email=justin.miranda@gmail.com,jmiranda@pih.org
# Only used on local machines when dataSource.url is overriden
openboxes.fixtures.enabled=false
# OpenBoxes Identifier Formats
# N: Numeric, L: Letter, A: Alphanumeric
# For example, NNNLLL might lead to the following random identifier being generated
˓123ABC.
openboxes.identifier.order.format = NNNLLL
openboxes.identifier.product.format = LLNN
openboxes.identifier.requisition.format = NNNLLL
openboxes.identifier.shipment.format = NNNLLL
openboxes.identifier.transaction.format = AAA-AAA-AAA
# OpenBoxes Identifier Characters
openboxes.identifier.numeric = 0123456789
openboxes.identifier.alphabetic = ABCDEFGHJKMNPQRSTUVXYZ
openboxes.identifier.alphanumeric = 0123456789ABCDEFGHJKMNPQRSTUVWXYZ
# Report logo header (not supported yet)
# openboxes.report.header.logo = file:///home/jmiranda/Desktop/images.jpg
openboxes.report.header.logo = http://localhost:8080/openboxes/images/hands.jpg
openboxes.report.header.title = OpenBoxes
# OpenBoxes Error Email feature (bug report)
# Use your own address if you want to handle bug reports yourself. Otherwise leave as-
˓is and OpenBoxes
# support these support requests.
openboxes.mail.errors.enabled = true
openboxes.mail.errors.recipients = support@openboxes.com
# OpenBoxes Barcode Scanner detection
# NOTE: This feature is an experimentation. If enabled you can scan barcode on any
˓page and the app will
# try to locate an object (product, shipment, etc) that is associated with that
˓barcode. If an object is
# found, the app just redirects to the details page for that database object. In the
˓future, I'm hoping to
# improve the barcode scanner to integrate with workflows (e.g. add item to purchase
˓order).
openboxes.scannerDetection.enabled = true
# Used to specify default roles for newly registered users (implies automatic
˓activation)
#openboxes.signup.defaultRoles=ROLE_MANAGER,ROLE_ASSISTANT
# General mail settings
grails.mail.enabled=true
grails.mail.host=<smtp server>
grails.mail.port=<smtp port>
grails.mail.username=<username>
grails.mail.password=<password>
grails.mail.from=<from address>
(continues on next page)
26 Chapter 8. Configuration
openboxes-docs Documentation, Release 0.7.18
(continued from previous page)
# Example of general mail settings
#grails.mail.host=smtp.gmail.com
#grails.mail.port=465
#grails.mail.password=password
#grails.mail.props = ["mail.smtp.auth":"true", "mail.smtp.socketFactory.port":"465",
˓"mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory", "mail.smtp.
˓socketFactory.fallback":"false"]
# Error email properties
mail.error.debug=true
mail.error.server=<smtp server>
mail.error.username=<smtp username>
mail.error.password=<smtp password>
mail.error.port=<smtp port>
mail.error.to=<to address>
# Example of error email properties
#mail.error.server=localhost
#mail.error.server=smtp.pih.org
#mail.error.username=openboxes
#mail.error.password=password
#Possible values: default|dynamic|alternate
mail.error.appender=dynamic
# OpenBoxes > Choose Location > Required Activities
# The supported activities required in order for a location a location to show up on
˓Choose Location page.
# Possible values: MANAGE_INVENTORY, PLACE_ORDER, PLACE_REQUEST, FULFILL_ORDER,
˓FULFILL_REQUEST, SEND_STOCK, RECEIVE_STOCK, EXTERNAL
openboxes.chooseLocation.requiredActivities = MANAGE_INVENTORY
# Amazon web service (not supported yet)
aws.s3.domain=s3.amazonaws.com
aws.s3.accessKey=0123456789ABCDEFG
aws.s3.secretKey=0123456789ABCDEFGHIJKLMNOPQRS
aws.s3.bucketName=files
# Google Product Search (no longer supported -- Google deprecated API)
# URL: https://www.googleapis.com/shopping/search/v1/public/products?key=${google.
˓productSearch.key}&country=US&q=${q}&alt=scp&crowdBy=brand:1
google.api.key=<no longer supported>
# Hipaaspace.com NDC Lookup (not supported yet)
hipaaspace.api.key=<not supported yet>
# RXNorm (not supported yet)
# URL: http://rxnav.nlm.nih.gov/REST/
rxnorm.api.key=<not supported yet>
# Google analytics
google.analytics.enabled = false
google.analytics.webPropertyID = <enter your google analytics property ID>
8.3. Configuration Example (openboxes-config.properties) 27
openboxes-docs Documentation, Release 0.7.18
28 Chapter 8. Configuration
CHAPTER 9
User Guide
Please be patient as our documentation expert (a.k.a our lead developer) is busy making the software not suck so he’s
had some trouble finding time to update these guides. If you would like to contribute to this User Guide, please refer
to the Contributing section of the Developer Guide.
If you would prefer to submit documentation updates as Word docs or collaborate with us using Google Docs, please
share the docs or links with our Support Team [email protected].
If you’re impatient, not good at words & stuff, and/or would prefer to see User Guide completed pronto, please feel
free to light a fire under our documentation expert. The most effective way to do that would be to shame him through
any of the public support channels (i.e. Twitter, Slack, Google Groups, highway billboards, etc).
29
openboxes-docs Documentation, Release 0.7.18
30 Chapter 9. User Guide
CHAPTER 10
Developer Guide
10.1 Getting Started
10.1.1 Dependencies
Required
Java 7
MySQL 5.5+
[SDK Man] (http://sdkman.io/install.html)
Grails 1.3.9
NOTE: We are in the process of upgrading to Grails 2.5.5 (see this feature branch). Once that is complete you will be
able to use Java 8.
Optional, but recommended
[IntelliJ IDEA] (https://www.jetbrains.com/idea/download/)
10.1.2 Instructions
These instructions are for developers only. If you are a system administrator looking to install OpenBoxes on your
own server, please check out our Installation page.
1. Install Dependencies
Install dependencies above
31
openboxes-docs Documentation, Release 0.7.18
sudo apt-get install openjdk7
sudo apt-get install mysql-server
2. Install Grails
Check that you have SDK Man installed properly (otherwise follow instructions on the skdman install page).
$ sdk version
SDKMAN 3.1.0
To install Grails 1.3.9
$ sdk install grails 1.3.9
3. Clone repository
If you are a core contributor:
git clone git@github.com:openboxes/openboxes.git
If you are a not core contributor, fork the openboxes GitHub repository, then replace git url with the one of your forked
repository
git clone git@github.com:<username>/openboxes.git
4. Create database
Create openboxes database
mysql -u root -p -e 'create database openboxes default charset utf8;'
Create openboxes user
mysql -u root -p -e 'grant all on openboxes.
*
to "openboxes"@"localhost" identified
˓by "openboxes";'
5. Create configuration file(s)
Create or edit a file called $HOME/.grails/openboxes-config.properties.
# Database connection settings
# You can use dataSource.url when you are using a non-dev/non-test database (test-app
˓may not run properly).
# If you want to run $ grails test-app you should comment out the dataSource.url
˓below and create a new
# openboxes_test database. Eventually, we will move to an in-memory H2 database for
˓testing, but we're
# currently stuck with MySQL because I'm using some MySQL-specific statements in the
˓Liquibase changesets. My bad.
dataSource.url=jdbc:mysql://localhost:3306/openboxes?autoReconnect=true&
˓zeroDateTimeBehavior=convertToNull&sessionVariables=storage_engine=InnoDB
(continues on next page)
32 Chapter 10. Developer Guide
openboxes-docs Documentation, Release 0.7.18
(continued from previous page)
dataSource.username=openboxes
dataSource.password=openboxes
# OpenBoxes mail settings - disabled by default
grails.mail.enabled=false
# OpenBoxes > Inventory Browser > Quick categories
#openboxes.inventoryBrowser.quickCategories=ARVs,MEDICAL SUPPLIES,FOOD,EQUIPMENT,
˓MEDICINE
# OpenBoxes > Choose Location > Required Activities
# The supported activities required in order for a location a location to show up on
˓Choose Location page.
# Possible values: MANAGE_INVENTORY, PLACE_ORDER, PLACE_REQUEST, FULFILL_ORDER,
˓FULFILL_REQUEST, SEND_STOCK, RECEIVE_STOCK, EXTERNAL
#openboxes.chooseLocation.requiredActivities = MANAGE_INVENTORY
# If you wish to not set up any test data, you can indicate this per the below
# (eg. if you are running from a copy of a production db)
# openboxes.fixtures.enabled=false
# If you want to track users via Google analytics
#google.analytics.enabled = false
#google.analytics.webPropertyID = <Google Analytics Key>
NOTE: If you are running in development mode with a copy of an existing database, you may want to instruct the
application to bypass the test data fixtures automatically. You can achieve this by commenting out the openboxes.
fixtures.enabled property. Unfortunately, the .properties files DO NOT deal well with boolean values so com-
menting out is the only way to set this property. If you want a more elegant approach, you can add all boolean
properties to openboxes-config.groovy.
#openboxes.fixtures.enabled=true
6. Grails Upgrade or Grails Compile
Either of the following actions (upgrade, compile, run-app) should generate the all important Spring configuration
(/WEB-INF/applicationContext.xml) and start the dependency resolution process.
grails upgrade
OR
grails compile
The grails compile step is not necessary since grails run-app will invoke the compilation step, but it
doesn’t hurt anything.
If you see any errors, run the command again.
IMPORTANT That last line is important. Because of some quirkiness with the way older versions of Grails resolve
dependencies and generates config files, you may need to run either of these commands multiple times in order to
resolve all dependencies and generate the config files.
Once the dependency resolution phase has completed, all dependencies will be stored in a local ivy cache (usually
under $USER_HOME/.grails/ivy-cache). You do not have to worry about this, just know that the dependen-
10.1. Getting Started 33
openboxes-docs Documentation, Release 0.7.18
cies are now on your machine and Grails will attempt to find them there before it tries to resolve them in a remote
repository.
7. Start application in development mode
The application can be run in development mode. This starts the application running in an instance of Tomcat within
the Grails console. You may need to run ‘grails run-app’ several times in order to download all dependencies.
grails run-app
8. Open application in Google Chrome
http://localhost:8080/openboxes
9. Log into OpenBoxes
You can use the default accounts (manager:password OR admin:password). Once you are logged in as an admin, you
can create own account. Or you can use the signup form to create a new account.
10.2 Contributing
There are many ways to contribute to OpenBoxes, and not just through making changes to the source code. Here are
a few examples of areas we need a considerable amount of help.
Develop a new feature
Patch a bug / hotfix
Improve translations
Improve documentation
Write unit, integration, functional tests
10.2.1 Resources
GitHub Guide on Forking
10.2.2 Procedure
1. Find or create an issue for the feature or bug in GitHub Issues.
34 Chapter 10. Developer Guide
openboxes-docs Documentation, Release 0.7.18
2. Fork the openboxes/openboxes GitHub repository.
3. Create a branch for your changes (create a hotfix for bugs if working off master or a feature branch for
features if working off develop). NOTE: The use of the hotfix or develop prefix will help us identify
which branch we need to merge your changes into.
git checkout -b hotfix/123-short-summary-of-issue
git checkout -b feature/123-short-summary-of-issue
4. Implement your feature or hotfix in your new branch.
5. Write a test for your changes (if you have trouble with this step please comment in your ticket that you’d like
some help). NOTE: Tests are required for features and bug fixes, but not for documentation and translation
changes.
6. Run tests.
grails test-app unit:
grails test-app integration:
7. Commit your changes
git commit -m "Implemented feature #123"
8. Push to your fork.
git push
9. Submit a pull request.
10.3 Syncing your fork
10.3.1 Resources
Configuring a Remote for a Fork
10.3. Syncing your fork 35
openboxes-docs Documentation, Release 0.7.18
Syncing a Fork
10.3.2 List your remote repositories
$ git remote -v
origin https://github.com/YOUR_USERNAME/openboxes.git (fetch)
origin https://github.com/YOUR_USERNAME/openboxes.git (push)
10.3.3 Add the upstream remote
$ git remote add upstream https://github.com/openboxes/openboxes.git
10.3.4 Verify upstream remote
$ git remote -v
origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch)
origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (push)
upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (fetch)
upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (push)
10.3.5 Pull changes into your fork as upstream/master
$ git fetch upstream
remote: Counting objects: 4165, done.
remote: Compressing objects: 100% (22/22), done.
remote: Total 4165 (delta 1920), reused 1928 (delta 1918), pack-reused 2225
Receiving objects: 100% (4165/4165), 1.83 MiB | 329.00 KiB/s, done.
Resolving deltas: 100% (2728/2728), completed with 583 local objects.
From https://github.com/openboxes/openboxes
*
[new branch] develop -> upstream/develop
*
[new branch] feature/94-upgrade-to-grails-2.5.x -> upstream/feature/94-
˓upgrade-to-grails-2.5.x
*
[new branch] hotfix/100-improve-performance-qoh-calculation -> upstream/
˓hotfix/100-improve-performance-qoh-calculation
*
[new branch] hotfix/161-support-additional-languages -> upstream/hotfix/161-
˓support-additional-languages
*
[new branch] hotfix/163-add-health-endpoint-for-monitoring -> upstream/hotfix/
˓163-add-health-endpoint-for-monitoring
*
[new branch] hotfix/165-replace-inventory-with-adjustment -> upstream/hotfix/
˓165-replace-inventory-with-adjustment
*
[new branch] hotfix/22-override-grails-config-locations -> upstream/hotfix/22-
˓override-grails-config-locations
*
[new branch] master -> upstream/master
*
[new branch] user-guide-docs -> upstream/user-guide-docs
10.3.6 Checkout the branch you want to sync
This will likely either be develop or master.
36 Chapter 10. Developer Guide
openboxes-docs Documentation, Release 0.7.18
$ git checkout master
10.3.7 Merge upstream/master into you local master
$ git merge upstream/master
10.3.8 Push changes up to your repository
$ git push
10.3.9 Profit
Fig. 1: Profit
10.4 Tagging a release
10.4.1 Find the current build number in the footer of the page for the desired ver-
sion of the application:
Build Number: v0.5.0-329-gc1b3544
10.4. Tagging a release 37
openboxes-docs Documentation, Release 0.7.18
In this case, the tag v0.5.0 is out-of-date, so we want to update this to v0.5.1. We first need to find the commit related
to this build number (e.g. c1b3544). You can view the commit log to view the history or you might need to browse
through old commits on github to double check that it’s correct.
$ git log --pretty=oneline | grep c1b3544
10.4.2 Create tag release
Once you’ve determined that this is the correct commit and you’re ready to create a new tag, run the following
command:
$ git tag -a v0.5.1 -m 'Release 0.5.1' c1b3544
10.4.3 Push tags to git remote repo
Then you can push this (and all other tags) to your repository to share:
$ git push --tags
10.4.4 Additional reading
See the following article for more informaton http://git-scm.com/book/en/Git-Basics-Tagging
10.5 Troubleshooting
10.5.1 Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
Problem
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/
˓WEB-INF/applicationContext.xml]
Solution
Execute the grails upgrade command in order to generate the files nece
$ grails upgrade
See the following stackoverflow article: http://stackoverflow.com/questions/24243027/
grails-spring-security-sample-application-not-working
38 Chapter 10. Developer Guide