OpenSRP-OpenLMIS Proof of Concept Software Requirement Specification

This page documents the software requirements and outlines the integration for the OpenSRP-OpenLMIS proof of concept that will be demonstrated to GAVI the week of 26th March 2018.

High Level Workflows

This section was copied from the previous page for reference. This section defines the minimum functional workflows for the proof of concept demo. Stretch activities are clearly marked with (Stretch)

  1. (Current Functionality) OpenSRP Android Client Demo prep to show current functionality
    • The OpenSRP user will login to the stock management module to see the current number of vials available for the antigen
    • The OpenSRP user click the card for the antigen and touch the Issued button to record an adjustment in the stock of that antigen
  2. (New) OpenSRP Android Client Requesting Stock
    • The OpenSRP user is already at the Stock Management Module screen
    • The user will touch a button to request stock based on Ideal Stock Amounts
      • A message will appear verifying that the user is requesting stock "Please confirm that you would like to request stock based on your Ideal Stock Amounts"
    • The device syncs with OpenSRP Server
    • NiFi queries the OpenSRP Server endpoint every 'n' seconds and identifies that a new stock request has been received
      • How do we tell what's "new"? Are new stock requests any with a created data newer than the last created date we saw on the endpoint?
    • NiFi performs internal business logic to map the stock request to the facility, user and ideal stock amount (ISA)
    • NiFi pushes an order to the OpenLMIS Orders API endpoint in the Fulfillment Microservice. An Order number is returned to NiFi.
      • Not sure NiFi can receive an order number, what is it supposed to do with it?
    • OpenLMIS user logs in to verify the order was created
  3. (Current Functionality) OpenLMIS Demo to convert Order to Shipment
    • OpenLMIS user walks through the order fulfillment process
    • A shipment is created
  4. (New) OpenSRP Android Client Receiving Shipment
    • NiFi queries the OpenLMIS Shipments API in the Fulfillment Service to see if a new shipment has been generated
      • (Note: Should this be the API endpoint, or should we query the Proof of Delivery Endpoint?)
      • How do we tell what's "new"?
    • When a new Shipment is identified, NiFi queries the Shipment/{id} API endpoint in the Fulfillment service to get the shipment details
    • NiFi performs business logic on the Shipment details to convert it to the appropriate JSON format required by OpenSRP
      • Does this logic require any data not received from the shipment/{id} endpoint?
    • NiFi posts the JSON to the OpenSRP Server
    • OpenSRP Server receives the shipment information
    • On a regular schedule, OpenSRP Android Client Syncs with the OpenSRP Server
      • A new shipment is received
      • A notification is generated in the Stock Management Module's Shipment section (new section)
    • OpenSRP user touches the shipments section in the stock management module and they are redirected to a page showing that a shipment is available
    • OpenSRP user touches the shipment and they view details of the shipment
    • User can accept shipment
    • (Stretch) User can adjust the amounts of each orderable and touch save
      • On Save action, the antigen amounts update on the tablet
    • OpenSRP Android client will sync with OpenSRP server
    • (Stretch) NiFi Queries OpenSRP Server on a regular schedule for Proof of Delivery
      • What is the proof of delivery?
    • (Stretch) NiFi performs the appropriate business logic to accept the proof of delivery and creates the appropriate JSON to post to OpenLMIS
    • (Stretch) NiFi posts the Proof of Delivery to the OpenLMIS Proof of Delivery API endpoint in the Fulfillment Service.

Software Development Required

This section defines the software development required to deliver the two core features that are outlined in the above workflow.

Core Feature 1: OpenSRP Client Request Stock

This feature requires development in the Android Client, OpenSRP Server and NiFi.

OpenSRP Android Client

The Android Client will need to be enhanced with a push button that requests stock in the Stock Management module. This button will store the datetime, user and facility information for the stock request and it will sync with the OpenSRP server.

1.1 Data Model Enhancement:

  • We will need to create a data element in the Android client that collects an "Order" request. Orders are events, and representing them similarly to the event model is appropriate.
    • Entity Name: Order
    • Sample Fields:
      • "_id": "",
      • "_rev": "",
      • "type": "Event",
      • "dateCreated": "2018-02-07T14:27:54.156Z",
      • "dateEdited": "2018-02-07T14:31:23.339+02:00",
      • "serverVersion": 1518006659097,
      • "locationId": "",
      • "eventDate": "2018-02-07T00:00:00.000Z",
      • "eventType": "Stock Order",
      • "formSubmissionId": "",
      • "providerId": ""
      • Payload { We will need to create a payload placeholder here for future Order payloads.}

1.2 UI Enhancement: (See Separate Section)

1.3 Sync Enhancement:

  • Each Order will need to be added to the sync routine. (SEE Server Side API Endpoints)
  • Business Logic:
    • When the "Order Stock" button is pushed, a sync routine should be kicked off for the stock management workflow

OpenSRP Server

OpenSRP Server will need to store the Order data in the server, update the REST API and expose one new API endpoint to track these orders.

1.4 Data Model Enhancement:

  • We will need to add a Order object within the Stock Domain Object. This domain object will track the orders that are generated by the Android Client.

1.5 REST API Enhancement:

  • (NOTE: This is not final and will need to be reviewed by the developer team)
  • We will need to add an "Order" endpoint to the REST API that allows users to GET and POST Orders
  • This endpoint will be available at the following endpoint /rest/stockresource/order/
    • Is a /rest/ prefix a thing? 
    • Methods:
      • /add - maybe POST / The add method will have to be enhanced
        • Does this add an order?
      • /sync - The sync method will have to be enhanced to get order events
        • What does this endpoint do?
      • /getOrders - maybe GET /{id} This is a new GET method that will get orders by facility. This will be the primary endpoint that NiFi queries to get order updates. Filter parameters will need to include asOfDateTime (ServerVersion) so we can minimize the number of results returned.
        • What's the DB column holding the time we want to filter on? Suggest query param key as "min-{the column name}"

1.6 Sync Enhancement:

  • The Sync service will need to be modified to include these orders and appropriately place the order content.

NiFi

NiFi will be responsible for querying the /getOrders API endpoint and kicking off the orders in OpenLMIS. The getOrders API will be queried on a regular schedule for new orders. When a new order is received, a NiFi Flow is run that ultimately creates an order in the /api/Orders endpoint in OpenLMIS. The structure of orders in OpenLMIS are defined by the project and we will need to hard code these for the demo.

Once an order is created, the order number will be stored in NiFi for future use.

NiFi can not store any permanent data

NiFi will need to create a number of maps:

  • OpenSRP Facility ID: OpenLMIS Facility ID - This map is used to translate the location from the OpenSRP server into the appropriate location in OpenLMIS. This map will be hardcoded for the demo.
  • Order Template: The OpenLMIS order for the chosen facility and program will be created in an Order Template file. This file will include the ideal stock amounts for the demo.

Business Logic:

  • When OpenSRP sees that a facility has requested an Order in from the getOrders API, it will:
    • Map the OpenSRP Facility ID to the OpenLMIS facility ID
    • Query NiFi for the order template for the OpenLMIS facility ID
      • There's no way to query NiFi, we can store a JSON mapping in NiFi and convert from OSRP to OLMIS facility ID (alright, I guess that's a kind of "query" :)
    • Complete the appropriate fields in the Order Template, (Order Date, Source, etc)
    • Save a log of the order
      • What's this log for, how accesible does it need to be?
    • Post the Order to the OpenLMIS /api/Orders/ endpoint
    • Store the Order number in a log
      • What's this log for, how accesible does it need to be?
  • Authentication will be stored in Nifi with a demo credentials

Core Feature 2: OpenSRP Android Client Receiving Shipment

The second core feature focuses on receiving a Shipment from OpenLMIS, sending it to the Android Client, notifying the user and allowing them to receive the stock in their inventory.

OpenSRP Android Client

The Android client will need to be enhanced to include a data model and user interface that presents a list of "Shipments". The shipments will require a data model enhancement in the client to be able to sync them from the server. Once a shipment is "Accepted" it generates "Received" events in the Android client for all of the antigens that are mapped in the shipment payload.

2.1 Data Model Enhancement:

  • We will need to create a data element in the Android client that stores a "Shipment". A "Shipment" is a bulk list of stock that is received from an outside source. The "Shipment" lists stock for multiple stock items. The user will be able to "Approve" a "Shipment" and apply the stock items that are in the "Shipment" to their stock. Shipments are events, and representing them similarly to the event model is appropriate.
    • Entity Name: Shipment
    • Sample Fields:
      • "_id": "",
      • "_rev": "",
      • "type": "Event",
      • "dateCreated": "2018-02-07T14:27:54.156Z",
      • "dateEdited": "2018-02-07T14:31:23.339+02:00",
      • "serverVersion": 1518006659097,
      • "locationId": "",
      • "eventDate": "2018-02-07T00:00:00.000Z",
      • "eventType": "Stock Order",
      • "formSubmissionId": "",
      • "providerId": ""
      • "accepted": This is a boolean that states when the shipment was accepted
      • "acceptedDateTime": This is the dateTime that the shipment was accepted by the end user
      • Payload { This is the JSON representation of the shipmentt. Each item in the shipment must map to the stock items.}

2.2 UI Enhancement: (See Separate Section)

2.3 Sync Enhancement:

  • Shipments will have to be synced from the OpenSRP server down to the client device. We do not anticipate the need to sync shipments from the Android client to the OpenSRP server for this demo. However, it will be a requirement in the future.

OpenSRP Server

The OpenSRP server will need to be enhanced to include the idea of "Shipments". Once the Shipment gets sent to the Android client, it becomes a "Receipt" at the lowest level of the supply chain, a facility who will consume the stock item.

2.4 Data Model Enhancement:

  • We will need to add a Shipment object within the Stock Domain Object. This domain object will track the shipments that are generated by OpenLMIS, pushed from Nifi and sent to the OpenSRP server.

2.5 REST API Enhancement:

  • (NOTE: This is not final and will need to be reviewed by the developer team)
  • We will need to add a "Shipment" endpoint to the REST API that allows users to GET and POST Shipments
  • This endpoint will be available at the following endpoint /rest/stockresource/shipment/
    • Methods:
      • /add - The add method will have to be enhanced to include the ability to add a Shipment from NiFi.
      • /sync - The sync method will have to be enhanced to get shipment events and sync them down to the Android client
      • /getShipments - This is a new GET method that will allow Android client get shipments by location. This will be the primary endpoint that the Android client queries to get shipment updates. Filter parameters will need to include ServerVersion so we can ensure the sync is applied appropriately.

2.6 Sync Enhancement:

  • The Sync service will need to be modified to include these shipments and appropriately place the shipment content on the Android client.

NiFi

NiFi is responsible for querying the OpenLMIS Shipments API to identify if there are any shipments that are on the way. When a shipment is received, NiFi, queries further for the shipment content, performs the correct business logic and posts a shipment to the OpenSRP Server /rest/stockresource/shipment/add endpoint.

  • Content of the shipments will be standardized for the demo from OpenLMIS (Need help from VR on this)

Business Logic:

  • NiFi will need to keep a map of OpenSRP facility ID vs OpenLMIS Location ID
  • NiFi will need to do quality control to ensure shipments only include products that are already hard coded in OpenSRP
  • NiFi will convert from orderables to Antigen Types and units across the systems. Only the antigen name (i.e. OPV) will be sent to OpenSRP for this
  • NiFi will need to develop a standardized JSON payload that can be easily parsed by the client.

Android Client UI Enhancements

This section includes a unified view of the UI enhancements that are required to deliver both features. We will need to create the following:

  1. A new "Orders" view that has two actions:
    1. View Orders
    2. New Order
  2. Orders view
    1. Allows a user to view orders, shipments that are available and completed orders
  3. Shipment Receipt View
    1. Allows a user to receive a shipment and apply it to their stock on hand

Screens


New Order Button

  • Business Logic
    • When the button is pushed, a confirmation dialog will pop-up with the text "Please confirm you wish to order stock"
      • UI Fields "Confirm" and "Cancel"
      • Business Logic:
        • When "Confirm" is touched, the order stock request is submitted
        • When "Cancel" is touched, the user returns to the screen

Orders(s) View

This view shows a list of all orders, shipments and completed that have been sent from this facility. The user can only touch items in the shipments dropdown that haven't yet been accepted.

Shipment Receipt View

This view allows users to take action on the shipment and apply it to their stock on hand.

  • A "Receive" view that displays the stock items to be received
    • This view includes the detail by antigen type (OPV, PENTA, etc).
    • Fields:
      • Stock Item - This shows the name of the stock Item (OPV)
      • Ordered - This shows the quantity received (Integer)
      • Shipped - This shows the number of vials ordered (Integer)
      • Doses - This shows the calculated number of doses in the shipped Quantity
    • (STRECH GOAL)
      • A stretch goal for this screen would be to allow users to adjust the amount received. The form would be populated by the amount in the server, but the user could increase or decrease each stock item with actual values.
    • Actions and Business Logic:
      • Receive - When the user touches "Receive" the following business logic is performed
        • The Receipt is updated with "received" and "receivedDateTime" information
        • Each item in the receipt creates a stock item event in the android client
          • The date of the event will be automatically populated to the current Date and Time
          • Each stock item event will be from "Other" with the name of the sending facility saved
          • The amount received will be added to the current stock on hand
          • The order will no longer display in the shipment section of the "View Orders" screen
        • The user will be redirected to the stock card control screen where they will see the new values.
      • Cancel - When the user touches "Cancel" they are returned to the previous screen


OpenLMIS: the global initiative for powerful LMIS software