This page provides acts as the software requirement specification for the OpenLMIS and OpenSRP integration for the minimum viable product integration for stock management.

Overview

We will focus on a server side integration between OpenSRP server and OpenLMIS. OpenSRP Server acts as a mobile workforce management tool for the mobile deployment, independently managing the health workforce, patient information and stock card information. The core integration will focus on exchanging information on the server side and making an easy-to-configure mobile application. This allows us to leverage the full capabilities of the OpenSRP server and exchange only the pertinent information with OpenLMIS.

The integration will be mediated by Apache Nifi, which is a core component of the OpenLMIS technology stack. Nifi will maintain a metadata map for a number of items that need to be cross referenced between OpenSRP and OpenLMIS. This includes locations, users, commodity types, trade items and programs. Nifi will query the OpenLMIS system for changes to metadata on a regular basis and alert system administrators if there are changes that need to be reflected in OpenSRP. Nifi will also maintain user credentials for numerous users to be able to read metadata and post stock events from the OpenSRP server. Nifi will query OpenSRP on a regular schedule for stock events and post them to OpenLMIS.

Definition of Done

The minimum viable product will be complete when the following features are developed and tested.

Target User Profile - Immunization Nurse

The user profile for the current OpenSRP stock control module focuses on frontline health workers who receive immunizations based on the commodity Type (BCG, OPV, Rota, etc.). This light stock control module contains core features for stock management, but is not robust enough to meet the needs of the supply chain.

The target user for this integration is the Immunization Nurse and Health facility supervisor. Both of these level 1 employees have similar needs to locally manage stock.

Definitions

Commodity Type: Classification of commodity. An example in OpenLMIS is product code BCG20. BCG20 is a 20 dose vial of BCG. When we order items in OpenLMIS, we don't care which trade item is sent, we just need the specific commodity type.
Dispensing Unit: A dispensing unit is the basic unit that a patient receives when the clinician or pharmacist provides them a product. Product inventory and usage is generally tallied and reported in dispensing units, as part of the requisitioning process.
Lot:
A collection of trade items of the same type that were all manufactured at the same time from a single manufacturer. Each lot has an identification number and expiration date. Each lot has passed laboratory to test composition before release to the market.
Net Content: The amount of dispensing units contained in each pack
Program:
A program is an independently funded project that is implemented in OpenLMIS and OpenSRP. Each Program has a specific set of Orderables, a complex configuration including Requisition Form settings and Program-specific user permissions, and a network of Facilities that are participating in the Program.
Trade item: An item meant for trade that commonly has a specific manufacturer and are defined outside of OpenLMIS. An example of a trade item in OpenLMIS is product code Intervax BCG 20. This is a trade item that is branded by Intervax and fulfills the BCG20 commodity type that would be ordered.

Information Hierarchy

OpenLMIS allows users to assign multiple programs. Each program provides a list of commodity types that are available to the program. Each commodity type can be fulfilled by any number of trade items. Each trade item can have any number of lots.

Program > (many) Commodity Type > (many) Trade Item > (many) Lots

The "Orderable" domain object underlies the core Commodity Type and Trade Item data model. It's appropriate to model OpenSRP's stock management data in this way. More information on the Orderable domain object and relationship can be found in this document and this class.

Assumptions

Out of Scope

The following items are out of scope for the minimum viable product.

Core Workflows

As an Immunization Nurse I need to...

1.0 View Stock On Hand (Trade Items grouped by Commodity Type)

This workflow focuses on viewing the stock on hand for all items that are in stock.

2.0 Make an Individual Trade Item Issue/Receive

This workflow focuses on issuing or receiving a single trade item to/from a different facility or sub-location within an existing facility. This is different from a bulk action that allows a user to issue or receive any number of items.

3.0 Create an Individual Trade Item Adjustment

This workflow focuses on creating an adjustment for a single trade item. This is different from a bulk action that allows a user to make an adjustment to any number of items.

4.0 Perform Physical Inventory by Program (Trade Items grouped by Commodity Type)

This workflow focuses on allowing a store manager to perform a stock take effectively modifying a bulk number of trade items in a single transaction. The user should have the ability to save a physical inventory in the event they are interrupted while in progress.

Nifi Integration Points

OpenLMIS Authentication

Nifi will authenticate with OpenLMIS using OAuth credentials. Mobile app users will not directly interact with OpenLMIS.

Feature Nifi OpenLMIS Auth-1: Nifi will authenticate with OpenLMIS for all transactions. The user must have the ability to create stock events across large geographic hierarchies. The user roles must match 

OpenSRP Server Authentication

Nifi will authenticate with the OpenSRP server and be able to access stock events across all facilities in the geographic hierarchy.

Feature Nifi OpenSRP Auth-1: Nifi will authenticate with OpenSRP server and have access to extract stock events for all facilities in the system.

Note: This may require a change in the OpenSRP server, or the creation of a team in OpenMRS that has access to all locations.

Reference Data Mapping

Nifi will be responsible for aligning OpenSRP and OpenLMIS metadata. Neither system will have an understanding of information in the other. OpenSRP has an internal mechanism for dynamically defining views without having to update the application (originally developed for the TB Reach application). We intend to use this feature to inform a number of touch points in the mobile client. OpenLMIS is the clear source of truth for programs, commodity types, trade items, lots, and reasons.

Facility Information

OpenSRP server has a representation of a facility within the health system. A facility is a physical location. OpenSRP inherits the facility list from OpenMRS, which is able to pull the facility lists from DHIS2 using the DHIS2 location sync module. OpenSRP also has a sub-location, where a frontline health worker can be assigned to a sub-location.

OpenLMIS has an internal representation of a facility as well. Though the supply chain hierarchy is different from the geographic hierarchy in many areas, the bottom unit of the facility is the common unit. Stock events need to be mapped at the facility level.

Feature Nifi Facility-1: Map facility codes between OpenSRP and OpenLMIS.

Nifi needs to maintain a map of locations between both systems. This map will include the lowest level facilities in the health system. There must be a one-to-one map between each location in OpenSRP and OpenLMIS. If the facility does not exist in one of the other systems, we will need to create it in the other system. Sub-locations can be mapped as well in each system. For example, if OpenSRP has a catchment area represented, we will need to add another geographic level to OpenLMIS and load in these catchment areas.

Feature Nifi Facility-2: Nifi will need to regularly poll the OpenLMIS and OpenMRS servers for new locations, deletions and updates to facility list IDs and notify an administrator if there are changes that have not been updated in the other system.

It's possible that a transaction will happen in OpenSRP that doesn't have an appropriate mapped location in OpenLMIS. In this event, we need to create a flow that queues failed transactions until the location is created in OpenLMIS.

Programs, Trade Items and Commodity Types (Orderables)

The core integration focuses on immunization workflows. The LMIS domain includes a concept of Programs,Trade Items and Commodity Types, which are defined in the Information Hierarchy section of this document. The OpenSRP stock management system doesn't include a concept of trade items. Instead, stock is managed by the commodity type and the system assumes the health care worker is able to link the commodity type against the trade item. The OpenSRP child health module will retain the commodity type assignment, but the stock management module will focus on trade items.

OPV Trade Item and Commodity Type Illustrative Example

OPV stands for Oral Polio Vaccine. It's commodity type that comes in a 20 dose vial in many areas. OPV can also come in a 10 dose vial in different geographic regions. The OpenSRP child health module records that a child was given a dose of OPV (OPV-1 or OPV-2) at a specific time. The stock management module tracks the vial. Ultimately, we aim to link the 20 children who were given an OPV dose on a particular day to the trade item that was issued to the child clinic. In order to achieve this, we need to link the medical and commodity domains at the point of service.

Orderable Nifi Feature-1: Map Programs, Trade Items and Commodity Types between OpenSRP server and OpenLMIS.

OpenSRP will maintain a list of programs, trade items and commodity types independent of OpenLMIS. These programs, trade items and commodity types will be defined in JSON configuration on OpenSRP server and synchronized down to the OpenSRP Android client. Note that each facility may have a different list of commodity types, trade items and programs where, so OpenSRP server will need to maintain a list of these available items at the appropriate level of the . We anticipate that these values will be mapped using the same data model that's defined in OpenLMIS API. Nifi will be responsible for mapping these values between the OpenSRP server and OpenLMIS.

Orderable Nifi Feature-2: Update OpenSRP server when a trade item, commodity type or program is added or updated at a facility in OpenLMIS.

When there is an additive change or update to an existing Program, Commodity Type, or Trade Item in OpenLMIS, Nifi will update OpenSRP server with the appropriate information. This will then be synced to the Android client. The program code is the key for programs and the product code is the key for commodity types and trade items.

Orderable Nifi Feature-3: Notify an administrator when a Program, Commodity Type or Trade Item is removed from OpenLMIS.

We must be able to cover the times when a program, commodity type or trade item is removed from OpenLMIS at the facility level. These deletion events will have consequences in the OpenSRP server and Android client and often requires human intervention. Nifi must notify an administrator by email using a templated message.

Nifi API Endpoint Mapping

The reference data mentioned above will serve as the core information model that allows OpenSRP server to interact with OpenLMIS. The reference data defines "what" is exchanged and this section focuses on "how" information will be exchanged. The core architecture will feature a server-side service between the OpenSRP server and OpenLMIS mediated by Apache Nifi. Nifi will be responsible for executing server-side business logic, ensuring changes in both systems are appropriately mapped and information is exchanged as defined above. It will also be able to notify system administrators where there are errors in the information exchange process.

Below is a list of core information and API endpoints in each system:

There are a number of resources that may need to be created in OpenSRP server. Below is a list of items that may need to be created:

Android Client Stock Management

This section includes the functional requirements and views to be developed in the OpenSRP Android client Stock Management Module. The current stock management views focus on presenting a simplified "stock card" system, where the high level landing page lists the stock cards available and subsequent screens focus on tracking the stock related transactions for that immunization. The core development in the Android client focuses on building dynamic views of the main screen to support grouping by commodity type and trade item based on the information in OpenLMIS as well as supporting stock ledger views down to the lot level. Additionally, we will introduce a new physical inventory screen that allows us to perform a physical inventory in the stock management module.

The views in this section are for illustrative purposes and are not final. This information box will be removed when they are finalized.

Server Side Configurable Fields

A number of items will need to be configured in the OpenSRP server  and made dynamic in the Android client. This section lists those features:

Introducing Commodity Types and Trade Items (Orderables) to the Android Client

The OpenSRP Android client currently has the ability to track stock issues and wastage from the perspective of the nurse giving the immunizations. The stock cards are currently hardcoded based on the immunization type, not the commodity type or trade item. This interface will be reworked to allow for dynamic population of trade items grouped by commodity types.

Stock Control Landing View - List of available Trade Items grouped by Program and Commodity Type

This view presents the list of available stock cards that can be managed in the system. The user touches a particular card to view, transact and plan for the use of that single trade item. The OpenSRP stockType (i.e. OPV) will be converted to a trade item on the stock management landing view. The current view includes the immunization type as you can see below. This view will now be populated with a list of trade items grouped by commodity type. The items in this view will be configured from the OpenSRP server and updated when there is a sync.

This page will also include a program toggle in the top right corner that allows the user to choose the program to manage for this particular view. If no programs exist, this toggle does not display. If the user toggles to a different program, the list of available items in this view changes.


Feature Stock Management-1: Allow for the dynamic population of the stock landing view based on server side configuration of programs, commodity types and trade items (Workflow 1).

Stock Card View

Once a user touches the trade item from the landing view, they are directed to the Stock Card View. This view is the primary area where stock is managed for a particular trade item. This view will not change significantly but the information on it will be populated from the trade item and lot metadata that is imported from OpenLMIS (Workflow 1).

Changes to be made:

Navigation:

The navigation buttons of Received, Issued and Loss/Adj will not be changed

Stock Card View - Received

When the user touches the "received" button on the screen above, they will be redirected to a page to enter a stock event that receives an individual trade item, crediting the stock on hand (Workflow 2).

Changes to be made:

Navigation:

We will not change the navigation on this view.

Stock Card View - Issued

When the user touches the "Issued" button from the Stock Card View - Current Stock View, they will be redirected to a page to enter a new stock event that debits the stock on hand (Workflow 2).

Changes to be made:

Navigation:

We will not change the navigation on this view.

Stock Card View - Loss/Adjustment

When the user touches the "Loss/Adjustment" button from the Stock Card View - Current Stock View, they will be redirected to a page to enter an adjustment stock event which is either a debit or credit (Workflow 3).

Changes to be made:

Navigation:

We will not change the navigation on this view.

Stock Card View - Stock Planning

When the user touches the "Stock Planning" tab from the Stock Card View - Current Stock View, the following tab will open.

This view needs to be reviewed for value to the end user. We're not sure if it adds value at the trade item and lot level. It would be a much better view at the commodity type level.

Changes to be made:

Navigation:

We will not change the navigation on this view.

Underlying Business Logic Changes

Currently, the business logic involved in consumption, wastage and prediction are all hardcoded based on the stockType. We will need to add the feature to dynamically define the stock card business logic that's run on the Android client based on the number of doses per vial for each trade item. This business logic needs to be scoped for each commodity type that is part of the vaccine program. This business logic can be defined based on the information we get from the OpenLMIS APIs.

Physical Inventory

This action allows a store manager to perform a stock take or physical inventory of all items they have in their store. The view includes a list of all trade items that are available to the facility sorted by program and commodity type. The list of available programs, commodity types and trade items are defined by OpenLMIS and maintained in the OpenSRP server. The end user will not have the ability to add programs, commodity types or trade items that have not already been added in the OpenSRP server. Note that the Android client will need to sync if the system administrator has updated the list of available programs, commodity types or trade items.

Start Inventory Screen

---START HERE---

Data Entry Screen:

Form Save Android Client Business Logic

Discussion:


OpenSRP Server Side Configurable Views, Business Logic and Data Model

OpenSRP Server has a mechanism for defining configurable views and data models for the Android Client and syncing those from the server down to the client. This feature allows system administrators to define a view and data model in JSON. Every time the Android client syncs, the view and data model is able to update. This feature is essential for the dynamic list of orderables and associated business logic in OpenLMIS.

These configurable views and data model will remain manually configurable in the OpenSRP server. They will not be dynamically updated based on changes in OpenLMIS. This allows the OpenSRP system administrators to carefully consider the impact of changing the view and data model, thoroughly test the change and implement it.

Below is a running list of views, business logic and data models that need to be configured from the server:

Feature Configurable Views-1: Upgrade the stock management module to work with configurable views

Currently, the stock management module is static. We need to update this module to be able to work with configurable views that are synced from the server.

Feature Configurable Views-2: Add the ability to sync business logic as a server configuration for each orderable.

Currently, the views and data model are configurable in Enketo forms. Each orderable will require specific business logic and calculations. We will need to define a way to systematically sync business logic and calculations so we can guarantee that the calculations in the user interface and on the tablet are appropriately calculated when there are updates to an orderable from the server.

FROM ABOVE:

We need to develop a data model and REST API to store orderables in OpenSRP to be able to track the orderable products on the server side. This will allow us to populate the fields in the android client, map orderables to immunizations and interact with the OpenLMIS server. Note: We only need to store a subset of orderables in the OpenSRP server, not the entire OpenLMIS orderable list.

This data model needs to be based off of the following data models in OpenLMIS:


DO WE NEED TO CREATE A REST API OR CAN'T THIS JUST BE STORED AS A STATIC JSON OBJECT.  WE WOULD ONLY NEED AN API IF WE ARE GOING TO BE DISTRIBUTING DIFFERENT ORDERABLES TO DIFFERENT WORKERS.  IT MIGHT BE EASIER TO JUST A FILE PER PROGRAM.  WE COULD THEN JUST HAVE OPENSRP LOOK FOR THE FILE FOR WHATEVER PROGRAMS ARE REFERENCED.  THIS MIGHT BE A LOT EASIER THEN TRYING TO MANAGE AN API.  WE COULD ALSO POTENTIALLY GENERATE THE FILE IN AN EXTERNAL MIDDLEWARE OR VIA SOMETHING LIKE NIFI.

ON APP SIDE WE NEED TO FIGURE OUT WHAT WE DO WHEN WE HAVE TWO DIFFERENT PROGRAMS.  IE) ONE OPENSRP APP WITH SAY CHILD HEALTH AND FAMILY PLANNING.  WE PROBABLY ONLY WANT TO HAVE ONE STOCK MODULE BUT THEN ALLOW SWITCHING BETWEEN PROGRAMS FOR THAT HEALTH WORKER WITH THE STOCK APP. 


Orderable Feature-2: Allow system administrators to configure the list of orderables that will be stored in OpenSRP and link them to the immunization schedule

OpenSRP server only needs to 'know' about a subset of orderables and link them to the immunization schedule concept in the health domain. This definition will need to be defined in the OpenSRP server by a system administrator. This list of orderables will be used to create views in the android client.

Sample ZEIR Vaccine Schedule JSON

Sample Orderable map:

OpenSRP marks all vaccines with a "name" and "type" in the vaccine schedule. The "name" represents the type and sequence for multi-sequence vaccines (OPV 1, OPV 2, etc.). The "type" does not include sequence information (OPV). The OpenSRP_Stock_Type should map to the vaccine type in the immunization schedule and the Orderable_productCode should map to the OpenLMIS orderable productCode. This productCode links back to the data model setup in Orderable Feature-1.

OpenSRP_Stock_TypeOrderable_productCode
OPVOPV20
OPVOPV50
OPVoralSyringe5ml

INSTEAD OF SAYING OPENSRP_STOCK_TYPE WOULD IT MAKE MORE SENSE TO SAY HEALTH EVENT OR SOMETHING LIKE THAT? 


\Discussion:

Program Information

OpenLMIS has a representation of a program, which is tightly linked to requisitions, funding and orderables. The current scope of work focuses on supporting one program in OpenSRP and we must ensure that we represent the core program information within the OpenSRP server.

Program Feature-1: Store program metadata in OpenSRP server so it can be used in transactions with OpenLMIS

We must store the following program information in OpenSRP Server:

Both of the above are needed when sending information to the OpenLMIS API?

We need to store Program specific Stock Adjustment Reasons (Named Stock Card Line Item Reasons). This allows us to track the adjustment reasons that need to be collected in the client.