Other Ideas for Connecting Stock & Requisition Services
Other Options & Ideas
The list of ideas and options below was created before the specific proposal above was selected and refined.
Idea 1: Create one common Reason list that both services share
We would merge the lists of adjustment reasons that both services use to create one common list. OpenLMIS 3.1 would ship with one common list that both services use. The Requisition form would use that list of reasons in its modal. The Stock service would use that list of reasons in its stock events.
Benefits: Get rid of redundancy in the status quo. We could actually get rid of one of the two APIs for reasons. Currently we have a duplicative set of APIs for this, one in RefData and one in Stock service. Implementors could still customize their adjustment reasons on a per-program basis, but if any program is using the Requisition service and the Stock service, it would have the same list of reasons in both places. Having a common data model makes a lot of things easier: reporting this data from the two different services together in one report/analysis; migrating or auto-populating any of this data from one service to the other (many ideas for this below); and moving us towards data governance rather than further fracturing this with different data models in different places.
Level of Effort/Feasibility: Low effort, compared to the other options. This option may be a dependency we would need to do to achieve some of the ideas below.
Idea 2: Requisition Form pushes stock data into Stock service
When a facility submits their Requisition form, the adjustments and the stock-on-hand balance they enter would be pushed into the Stock service. It would become stock event(s) that capture the adjustments. They would be associated with the date at the end of the period, because we don't know the exact date each adjustment happened. The stock-on-hand balance information from the Requisition form could be mapped to a physical inventory event, recording that a count was conducted on the closing day of the period.
Benefits: Reduce data entry burden. Automatically begin capturing a history of stock events from the R&R reporting process.
Level of Effort/Feasibility: Medium. Would require a common list of reasons (idea 1) or a mapping between the different lists of reasons (something like idea 10).
Technical Note: If the Stock service is enabled, then you can toggle this data push feature on. This could be a "toggle" setting on each Requisition Template (per program).
Question: Do we consider the Requisition form lower-quality or lower-fidelity data? If so, is there any problem in populating that lower-quality or lower-fidelity data into the stock service? Or perhaps it is not a problem—perhaps having some data is better than having no data, and this is just part of the process of a country moving to higher-fidelity data and a more professional supply chain over time?
Idea 3: Requisition Form prompts users to open Stock UI to record adjustments
When a facility is filling out their Requisition form, the UI could prompt them to jump over to the Stock service to record adjustments there. Then what they record there could be pulled back into the Requisition form (with a copy of the data stored in both services), or the Requisition form could simply store a "pointer" to the adjustments recorded in the stock service.
Benefits: Reduce data entry burden.
Level of Effort/Feasibility: Medium. Need to account for the asynchronous technical issue noted below.
Technical Note: This feature would be a toggle setting on the Requisition Template (per program), if the Stock service is enabled. This feature would also require handling the issues around asynchronous data entry or offline sync, because the adjustments stored in the stock service might continue to change over time as the Requisition moves through initiation/submission/authorization/etc. The requisition form would probably contain one Total Adjustment value (e.g. +26 units), that is a snapshot in time of what was in stock when the user went through this workflow. The pointer would point to IDs of stock adjustment events that total up to +26. But if stock events change later over time, it would not change what was submitted on the Requisition.
Idea 4: Stock UI pulls Adjustments from Requisition form
When a user is in the Stock UI making adjustments, the Stock UI would pull any adjustments that were recorded on the Requisition form and display them as "draft" or "suggested" adjustments in the Stock UI. The user would have to edit and clean up the adjustments in order to be able to save them in the Stock service. The user would enter exact dates for the adjustments and enter Lots data. Or the user could remove these draft "suggestions" and just manually enter new stock adjustments.
Benefits: Slightly reduced data entry burden compared to Status Quo. However, this is not as much help as Idea 2 or Idea 3, because they still need to touch the data in two places.
Level of Effort/Feasibility: Medium. Feasible even if we don't have the same list of reasons in both services.
Technical Note: This approach handles the low-fidelity versus high-fidelity issue by giving the user a UI and a process to improve their low-fidelity data and clean it up to be high-fidelity. For example, they would specify Lots and provide exact Dates for each adjustment. And if the adjustment reasons do not match, they would have to assign an adjustment reason from the stock service list of reasons. Doing this clean-up puts some burden on the user (see Benefits above).
Idea 5: One-time Data Migration from Requisition forms to Stock events
This migration would be a scripted, automated process. An implementor or technical administrator could push a button or run a script to migrate historical Adjustment forms into Stock events. This would create Stock adjustments and stock-on-hand inventory events using the data entered in historical Requisition forms.
Level of Effort/Feasibility: Medium-Difficult. Depends on whether it is a shell script or has a UI that helps you handle and resolve errors or issues. Depends on whether it can truly be a one-time script or needs to handle repeated migrations.
Technical Note: This also has limitations/challenges around when you would run this migration if it is truly a one-time migration. Maybe it would need to be re-run or happen multiple times during a period of transition from one mode of operation to another. Maybe you would need to run it by program, by facility, or by a limited set of products.
Idea 6: View Requisition Adjustments and SOH inside Stock UI
When a user is inside the Stock UI, it could provide a view-only look at the adjustments and the stock-on-hand numbers that were submitted on Requisition forms. This data would not actually become stock events in the system—instead we would just show the Requisition adjustments side-by-side on the same screen, or inside the same table, as the Stock adjustment events. Hopefully the user would see that they correspond often. The view-only data from the Requisition Forms would clearly be identified with a visual indicator that it comes from Requisitions, not the Stock service. The user may want an option to show/hide that part of the screen.
Benefits: Even if the data comes from two different places, or has two different data models, at least the user has an option to see it together in one place.
Level of Effort/Feasibility: Low effort
Ideas 2-6 all deal with how the stock-related data in Requisition forms could flow to the Stock service.
Next, the ideas below address the reverse direction.
Idea 7: Stock data auto-populates the Requisition form
When a user is filling out their monthly/periodic Requisition form, if they have the Stock service enabled for that program, then the Requisition form can be auto-populated with data from the Stock service. Many fields on the Requisition Form can be populated by querying the Stock APIs: Beginning Balance, Received Quantity, Consumed Quantity, Adjustments, and Stock-on-Hand. All of those fields can pull data from the Stock APIs by querying for balances as of a certain date and querying for adjustments and stock card line items during a range of dates (using dates from the start and end of the Requisition reporting period).
Benefits: Significant reduction in duplicative data entry. For users of Stock Management, it makes the requisition burden much lower.
Level of Effort/Feasibility: Low effort. APIs already exist.
Technical Note: This would be pretty simple to implement. It would just be configured by a toggle on each Requisition Template. The logic could all go inside the Requisition service (Java code), and basically at the moment of initiation of a requisition, it would look to see if Stock Cards exist for this facility, and if so it would use any available information in the stock service to pre-populate the Requisition form. If the data does not exist, then it fails gracefully and it's up to the end user to fill out the entire Requisition form.
Idea 10: Fancy Mapping Between Reasons
Idea 10 is a fancy alternative to Idea 1. Instead of Idea 1, which would harmonize data, we could instead accept the brutal reality that the adjustment reasons and stock-on-hand numbers are fundamentally and forever different between the Requisition and Stock services. To address that, a fancy solution is to create a configurable mapping between the two sets of reasons. The mapping would say "Requisition adjustment reason X maps to Stock adjustment reason Y".
Benefits: The mapping could be used in a variety of ways. First, it could control the automatic push or pull of stock data between either service. For example, the Requisition adjustments could be automatically mapped to Stock adjustments that use a totally different vocabulary. Second, it could be used for reporting in order to align data so you could have one report or one analysis that would take in data from both services that uses different lists of reasons but visualizes the data together.
Level of Effort/Feasibility: Very difficult and costly to build this. The level of complexity and on-going maintenance burden are likely not justified.
OpenLMIS: the global initiative for powerful LMIS software