Mobile Stock Management Integration Design Spec
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.
- The OpenSRP Android client is able to manage the stock independently while offline. Stock management will include managing programs, commodity types, trade items and lots (including expiration dates).
- Individual stock events (issues, receipts and adjustments) that are generated in the OpenSRP Android client are synced bidirectionally with OpenLMIS for the past N months. Stock events are appropriately tagged with geographic information and reasons so they show up in OpenLMIS.
- Users are able to perform a physical inventory in the OpenSRP Android client for their facility. This physical inventory generates stock events for each item in the inventory, which are subsequently pushed into OpenLMIS.
- The OpenSRP Android client stock management module is able to be run independently in an APK of it's own.
- The OpenSRP Android client stock management module is able to estimate the total number of vials consumed by commodity type based on the number of children immunized on a particular day. This is aligned with the current functionality based on immunization, but modified for commodity type.
- Documentation has been created to support end user functioning, demonstration and development.
- A child immunization with stock management APK is released that integrates with an online OpenSRP, Nifi and OpenLMIS demonstration environment. This demonstration environment is able to be reset on a regular schedule so the OpenLMIS team is able to demo the features to end users and implementers.
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
- End users will not interact directly with the OpenLMIS system. Instead, OpenSRP server will have a single connection that will mitigate all transactions.
- This integration focuses on vaccines.
- Features are targeted to function on an Android Tablet that have screen sizes of 7 inches and greater as the primary input device. We are not currently targeting screen sizes that are smaller than 7 inches, such as smartphones.
- Only stock events from the past 12 months will be synchronized from the OpenSRP server to the Android client. All stock events from the Android client will be pushed to the OpenSRP server and OpenLMIS.
- We assume OpenLMIS is the program, trade item and commodity type system of record. Any changes in OpenLMIS must be reflected in OpenSRP for these items. OpenSRP retains a level of abstraction for these items, but implementers will not make changes in OpenSRP without first making changes in OpenLMIS.
Out of Scope
The following items are out of scope for the minimum viable product.
- Make a Bulk Trade Item Issue/Receive - This is a feature in OpenLMIS, but not in SIGLUS.
- Make a Bulk Trade Item Adjustment - This is a feature in OpenLMIS, but not in SIGLUS.
- Automatic receive at a location that was generated from an issue. We will require each health worker to enter the appropriate stock event on their device, if a trade item is issued to another location. This includes sub locations.
- Adding trade items or commodity types from the OpenSRP Android client.
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.
- Assumptions:
- The list of commodity types, programs and trade items have been set in the OpenSRP server and have a corresponding map in the OpenLMIS system
- The user will have synced with the server at least once to download the metadata
- Steps:
- Open the OpenSRP App and login
- Touch the menu> Stock Management
- The user is presented with a list of all available trade items that are downloaded from the OpenSRP server
- This list is filterable by program and commodity type
- Includes the following fields:
- Product Code
- Product
- Lot Code
- Expiry Date
- Last Update
- Stock on Hand
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.
- Assumptions:
- The list of commodity types, programs and trade items have been set in the OpenSRP server and have a corresponding map in the OpenLMIS system
- The user will have synced with the server at least once to download the metadata
- Steps:
- Open the OpenSRP App and login
- Touch the menu> Stock Management
- Filter the stock on hand list for the appropriate program
- Filter the stock on hand list for the appropriate trade item or commodity type
- Touch the appropriate trade item to enter the stock card view
- Touch the Received or Issued button
- If touched the Received Button, Complete the Received form
- Date
- Received from:
- This is a dynamic field configurable in the OpenSRP server. It can include the geographic hierarchy as well as lower level clinics
- Reason:
- This is a dynamic field configurable in the OpenSRP server and linked to a reason in the OpenLMIS server
- Quantity of units (vials, packs, etc.)
- VVM Status
- Stage 1
- Stage 2
- Read Only Automatic Calculation:
- We will perform an automatic calculation defining the number of sub-units that are issued (doses, pills, etc.)
- Touch Save
- If touched the Issued Button, Complete the Issued form
- Date
- Issued to:
- This is a dynamic field configurable in the OpenSRP server. It can include the geographic hierarchy as well as lower level clinics
- Reason:
- This is a dynamic field configurable in the OpenSRP server and linked to a reason in the OpenLMIS server
- Quantity of units (vials, packs, etc.)
- VVM Status
- Stage 1
- Stage 2
- Read Only Automatic Calculation:
- We will perform an automatic calculation defining the number of sub-units that are issued (doses, pills, etc.)
- We will perform an automatic calculation based on the number of children immunized on the date selected.
- Touch Save
- If touched the Issued Button, Complete the Issued form
- If touched the Received Button, Complete the Received form
- The stock event is added to the trade item and the user is redirected back to the stock card view.
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.
- Assumptions:
- The list of commodity types, programs and trade items have been set in the OpenSRP server and have a corresponding map in the OpenLMIS system
- The user will have synced with the server at least once to download the metadata
- Steps:
- Open the OpenSRP App and login
- Touch the menu> Stock Management
- Filter the stock on hand list for the appropriate program
- Filter the stock on hand list for the appropriate trade item or commodity type
- Touch the appropriate trade item to enter the stock card view
- Touch the Adjustment +/- button
- Complete the Adjustment form
- Date
- Reason:
- This is a dynamic field configurable in the OpenSRP server and linked to a reason in the OpenLMIS server
- Quantity of units (vials, packs, etc.)
- VVM Status
- Stage 1
- Stage 2
- Read Only Automatic Calculation:
- We will perform an automatic calculation defining the number of sub-units that are issued (doses, pills, etc.)
- Complete the Adjustment form
- The stock event is added to the trade item and the user is redirected back to the stock card view.
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.
- Assumptions:
- The list of commodity types, programs and trade items have been set in the OpenSRP server and have a corresponding map in the OpenLMIS system
- The user will have synced with the server at least once to download the metadata
- Only one inventory is able to be saved in draft at a time
- Steps:
- Open the OpenSRP App and login
- Touch the menu> Stock Management
- Touch the Inventory button
- Choose the Program for this inventory
- The list of program specific trade items will be displayed on a screen sorted alphabetically by product code
- Each trade item will have lots that need to be displayed below the trade item so the user can count the number of each lot item
- The calculated stock on hand is presented on the screen and there is a field to enter the stock on hand value.
- If the stock on hand value that's entered in each trade item or lot does not match the calculated quantity, the user must enter a reason for the discrepancy.
- (At any time, the user can save a draft of the current inventory and exit the screen)
- Once the user has completed all fields, the user can "submit" the inventory
- Once "submitted" the stock on hand for each trade item is adjusted in the app and each stock event is synced to the OpenSRP server with the appropriate event Type "Physical Inventory".
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:
- OpenLMIS GET Endpoints:
- Reference Data Service
- CommodityTypes - Returns an array of all commodityTypes in the system
- CommodityTypes/{id} - Returns a specific commodity type
- facilities/minimal - Returns an array of facilities with id and name only
- facilities/{id} - Returns a specific facility
- geographicLevels - Returns an array of geographicLevels
- programs - Returns an array of all programs
- programs/{id} - Returns a specific program
- stockAdjustmentReasons - Returns an array of stockAdjustmentReasons
- stockAdjustmentReasons/{id} - Returns a specific stock adjustment reason
- tradeItems - Returns an array of tradeItems
- tradeItems/{id} - Returns a specific tradeItem
- Stock Management Service
- stockCardLineItemReasons - Returns an array of stockCardLineItemReasons
- stockCardLineItemReasons/{id} - Returns a specific stock card line item reason
- stockCards - Returns an array of stock cards, result is an intersection of user rights and request parameters.
- stockCards/{id} - Returns a specific stock card
- validDestinations - Get a list of valid destinations of a program and a facility type.
- validReasons - Return a list of valid reasons based on program and facility type.
- Reference Data Service
- OpenLMIS POST Endpoints:
- Stock Management Service
- stockEvents - Create a new stock event with one or more orderables
- Stock Management Service
- OpenSRP GET Endpoints:
- stockresource/getall - Returns a list of stock events
- OpenSRP POST Endpoints:
- stockresource/add - Add a stock event to the OpenSRP server
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:
- GET a list of locations by geographic hierarchy
- GET a list of programs, trade items and commodity types
- GET a list of reasons
- POST additions and updates to programs, trade items and commodity types
- POST additions and updates to reasons
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.
Views are not final
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:
- programs - Programs will be configured in the OpenSRP server down to the facility level. A facility can have 0 to N programs. If a facility has 0 programs, no program information will be displayed
- commodity types - Commodity types will be configured in the OpenSRP server down to the facility level. If a program is active, there will be a list of available commodity types by program.
- trade items - Trade items grouped by program and commodity types will be defined in the OpenSRP server at the facility level. This dynamic list defines which trade items, down to the lot level are available at each facility. These trade items will determine which items display in the stock management landing view.
- lots - Lots are optional for the entire OpenSRP implementation and can be set in a global configuration variable. If a lot is not defined, we will not include displaying lot information in the Android client. If lots are defined, they are required at all facilities. Lots will be defined in OpenLMIS and pushed to OpenSRP server. If lots are enabled, this impacts what is displayed in the stock management landing view as well as what information is collected in the stock event transactions and physical inventory.
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:
- Stock Control > OPV: The text "OPV" will be populated based on the trade item name that's imported by OpenLMIS
- OPV Stock: This will be populated based on the trade item name
- 13 vials: The number of vials will be populated based on the metadata from the trade item information imported by OpenLMIS, including the unit of measure
- (New) Number of Doses: We will add an item approximating the number of doses available based on the metadata that's imported from OpenLMIS
- (New) Lot and Expiration Date: Display the lot and expiration date information if activated
- Note: stock numbers are in vials: This item in the bottom will be populated based on the unit of measure for the trade item.
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:
- OPV Stock Received: The blue header text "OPV" will be dynamically populated based on the name of the trade item
- Date OPV stock received: The text "OPV stock" will be removed and it will just say "Date received". No functionality will change on this widget
- Reason: This is populated from a list of valid stock card line item reasons from OpenSRP server (originally from OpenLMIS).
- Received from: This radio button will change to two fields:
- Location: A location hierarchy widget will be available based on the OpenSRP locations. Note that this assumes there is a one-to-one match between locations in OpenSRP and OpenLMIS.
- Other: This is a field that allows them to type in text if not from a location that's in the hierarchy.
- Vials OPV received: The text "Vials" will be populated based on the unit of measure imported from OpenLMIS and the text "OPV" will be replaced with the name of the orderable imported from OpenLMIS
- (new) VVM: A radio button will be displayed with the VVM stage numbers (1-2)
- Note: We may have a problem here if another location tracks lots and the lot isn't available already on this device.
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:
- OPV Stock Issued: The blue header text "OPV" will be dynamically populated based on the name of the trade item
- Date OPV stock issued: The text "OPV stock" will be removed and it will just say "Date received". No functionality will change on this widget.
- Reason: This is populated from a list of valid stock card line item reasons from OpenSRP server (originally from OpenLMIS).
- Issued to: This radio button will change to two fields:
- Location: A location hierarchy widget will be available based on the OpenSRP locations. Note that this assumes there is a one-to-one match between locations in OpenSRP and OpenLMIS.
- Other: This is a field that allows them to type in text if not from a location that's in the hierarchy.
- Vials OPV issued: The text "Vials" will be populated based on the unit of measure imported from OpenLMIS and the text "OPV" will be replaced with the name of the trade item imported from OpenLMIS
- (new) VVM: A radio button will be displayed with the VVM stage numbers (1-2)
- Wasted Vials: The text "Vials" will be populated based on the unit of measure imported from OpenLMIS
- (new) Wasted Reason: If the "Wasted Vials" field is populated, a new "Wasted Reason" field will display with a radio button that's populated by the OpenLMIS program specific adjustment metadata. If the users are able to enter a free text reason, this radio button will include an "other" option that will toggle the next field
- Note: The suggested number of vials will be based on the number of children immunized today by commodity type. It's possible that this calculation will be inaccurate if there are multiple lots for a particular commodity type that were used for a particular day. Maybe we can perform a smarter calculation here based on the total stock on hand for this trade item and lot compared to the number of children immunized today minus any other trade item debits that also happened today to this same location.
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:
- OPV Stock Loss/Adjustment: The blue header text "OPV" will be dynamically populated based on the name of the trade item
- Date OPV stock loss/adjustment: The text "OPV stock" will be removed and it will just say "Date received". No functionality will change on this widget.
- Reason for OPV adjustment: The text "OPV" will be dynamically populated based on the name of the orderable. Additional items will be added to the radio button
- Vials OPV adjustment: The text "Vials" will be populated based on the unit of measure imported from OpenLMIS and the text "OPV" will be replaced with the name of the trade item imported from OpenLMIS
- Business Logic Change: If Wastage, Expiration or VVM/CCE failure are selected, only negative integers will be able to be saved.
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:
- Stock Control > OPV:
- The text "OPV" will be dynamically populated based on the name of the trade item
- Units will be displayed in parenthesis based on the metadata populated from OpenLMIS
- OPV Planning: The text "OPV" will be dynamically populated based on the name of the trade item
- 3 month OPV stock levels:
- The text "OPV" will be dynamically populated based on the name of the trade item.
- The business logic for this graph will have to change: The y-axis will only display whole numbers, not decimals
- 3 month OPV stock used:
- The text "OPV" will be dynamically populated based on the name of the trade item.
- Units will be displayed instead of the text "vials" in the table based on the metadata populated from OpenLMIS
- Current OPV stock:
- The text "OPV" will be dynamically populated based on the name of the trade item
- Units will be displayed instead of the text "vials" in the table based on the metadata populated from OpenLMIS
- Number of active children: no changes to this section
- Due OPV next month Mar 2018:
- The text "OPV" will be dynamically populated based on the name of the commodity type
- Units will be displayed instead of the text "vials" in the table based on the metadata populated from OpenLMIS
- The business logic will have to change based on the number of doses available by commodity type that is populated by OpenLMIS
- For example:
- If we are viewing rota 1, the calculation is 1 dose per child, but if it's a different type of Rota, it may be a 2 vial dose.
- For example:
- Average OPV waste rate: The text "OPV" will be dynamically populated based on the name of the trade item
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:
- Section: Orderables - This section displays a tabular view of all orderables that are in available to this facility. Each orderable signifies a single row.
- (The UI for this section has not yet been defined)
- Column: Orderable name
- Column: Orderable unit
- Column: Stock on Hand - This shows the current stock on hand for the orderable
- Column: Physical Count - This field allows the user to capture the number counted
- Column: Calculated difference: - This is a calculated field that calculates the physical count minus the stock on hand values and displays in whole units
- Column: VVM - If a VVM is available for this product, the user must select the VVM of the orderable (number 1 - 4)
- Business logic:
- Each orderable represents in a row in the table
- Orderable name and unit are auto populated by the OpenLMIS metadata
- All orderables are displayed on this screen
- VVM is only displayed if the orderable has a VVM. In which case, VVM is a required field.
Form Save Android Client Business Logic
- Once the form is saved each orderable is adjusted to the physical count quantity and values are updated across the entire stock management module
- The user is redirected to the Stock Control Landing View
Discussion:
- Do we need to include open vials in this stock take?
- Do we need to account for different VVM?
- How do we define the order of the orderables that are displayed on this screen?
- What is the server side business logic?
- Future Idea: Facilities may request that we order the orderables specifically tailored to their environment so it's easier to take stock.
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:
- Stock control landing view:
- List of stock cards
- Orderable item metadata (name, unit of measure, dose)
- Assumption: The order of the JSON will be the order in which the item is displayed on this view
- Stock card views:
- Each orderable item has its own metadata that populates the view (name, unit of measure, dose)
- Each orderable item has specific business logic when performing calculations on the wastage view
- Each orderable item has specific business logic in the Stock Card - Stock Planning view
- Each orderable item has an associated program adjustment reason
- Location Hierarchy:
- The OpenLMIS location hierarchy is used to define stock issues and receipts. This widget will need to be populated from OpenSRP server
- Stock issue and receipt from Community Health Workers (suballocation):
- Stock issues to community health workers need to be dynamically populated based on the names of the users registered in the team for that facility or zone.
- Orderable metadata
- Name is required
- Unit of measure is required
- Number of doses is required
- VVM is required
- Program metadata
- Program name is required
- Adjustment reasons are required
- Program specific orderables are required - so we can link the adjustment reasons to the program for a specific orderable
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:
- Orderables
- productCode
- name
- dispensingUnit
- netContent - Number of doses available
- CommodityType - Allows for grouping of orderables (See discussion point below in Orderable Feature-2)
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_Type | Orderable_productCode | |
---|---|---|
OPV | OPV20 | |
OPV | OPV50 | |
OPV | oralSyringe5ml |
INSTEAD OF SAYING OPENSRP_STOCK_TYPE WOULD IT MAKE MORE SENSE TO SAY HEALTH EVENT OR SOMETHING LIKE THAT?
\Discussion:
- Do we need to have a concept of a grouped consumption package for orderables? For example, the OPV consumption package includes 1 unit of productCode OPV20 and 1 unit of oralSyringe5ml. (Assumption: Yes) . I DON'T KNOW IF WE HAVE TO WORRY ABOUT THIS USE CASE FOR IMMUNIZATION.
- Is CommodityType a better grouping mechanism here?
- We don't need all orderables that are in OpenLMIS, only a subset. What is the best mechanism to filter this subset of orderables? Should we filter this by program, or by the map? CAN ORDERABLES BE IN MULTIPLE PROGRAMS IN OPENLMIS OR IS IT A 1-1 RELATIONSHIP? IF WE CAN CREATE PROGRAMS WITH ARBITRARY ORDERABLES THEN IT WOULD BE IDEAL POTENTIALLY USE THE PROGRAM AS THE FILTER. THAT WAY WE CAN MANAGE THIS ON THE OPENLIMS SIDE. I SEE THE MAPPING AS A POTENTIAL CONSTANT WE WOULD WANT TO STORE IN OPENLMIS. IE) AN ORDERABLE TO PROGRAMMATIC MAPPING. WE SHOULD PROBABLY CALL IT THAT VS. OPENSRP
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:
- program_name
- program_code
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.
- Name
- reasonType
- reasoncategory
- isFreeTextAllowed
OpenLMIS: the global initiative for powerful LMIS software