Domain Modeling - First Pass
Notes from a brief whiteboard design session on domain modeling, starting with Orders. The 2.0 ERD was taken as inspiration. This is meant to capture basic ideas and relationships - we expect attribute lists to be fleshed out, names normalized, etc. Business requirement input is also needed.
Fulfillment
Orders
requisitionCode | Code back to originating Requisition (Optional) |
createdDate | When order was created |
createdBy |
|
program |
|
requestingFacility | Facility requesting the order |
receivingFacility | Facility to receive the Shipment. Could be requestingFacility or one that holds it on behalf |
supplyingFacility | Facility fulfilling the order. Handles local fill or ERP |
orderCode | Order number - user defined and configurable |
status | ORDERED, IN_TRANSIT, PICKING, PICKED, SHIPPED, etc. |
id |
|
quotedCost |
|
Likely need more audit columns, e.g. addl time stamps, assignments, etc. Approvals? Notes?
Order Line Item
orderId | Foreign key to Order |
Id |
|
product | Foreign key to Product*. Or <Requestable>? |
orderedQuantity |
|
fulfillmentStatus | Has this been fulfilled by a shipment? Needed if orders are broken up into several Shipments |
*Current OpenLMIS: Requisition specifies exact Product, including pack size, etc. Do we refactor this to request doses or impact, e.g. "Give me 1,000 pills of aspirin" vs. "10 bottles of 100 count aspirin"? Esp. when considering vaccines and doses. This is a required ToDo. Also consider quotedCost here.
If Rationing is done at the order level, need additional column for rationedQuantity.
Picklist
Must support substitutions and quantity adjustments
Picklist Line Item
Id |
|
Lot |
|
QuantityToPick |
|
product |
|
pickListId |
|
Shipment
id |
|
orderId | If originated from an Order |
originFacility | Facility sending shipment |
destinationFacility | Deliver to address |
program |
|
shipmentCode |
|
status |
|
Need various date and audit fields. Tracking id.
Shipment Line Item
Id |
|
shipmentId |
|
lot |
|
product |
|
quantity |
|
status |
|
Likely have a ReceivedQuantity column - a specialized ReceivedLineItem object required only if detailed accounting of receipt is required.
Requisitions
Requisition
id | |
facility | |
program | |
processingPeriod | |
status | |
supervisoryNode | Not sure why this here; drop it? |
emergency | boolean. Specifies whether this is an emergency requisition. Perhaps emergency requisitions should simply be thought of as (ad-hoc) Orders? |
allocatedBudget | |
fullSupplySubmittedCost | |
nonFullSupplySubmittedCost | |
clientSubmittedTime | For mobile client, subject to revision |
clientSubmittedNotes | For mobile client, subject to revision |
(Standard audit info columns) | |
patientQuantification | Foreign key related to requisitions, but should go wherever the report/program data goes |
requisitionSignatures | Foreign key; used by the mobile client and subject to revision |
requisitionStatusChanges | Foreign key; used by the mobile client and subject to revision |
TODO: Determine whether current approval-model is sufficient. Perhaps we need something more sophisticated?
TODO: Consider pulling out authorization into its own domain object to be informed by desired REST endpoint for requisition authorization (e.g. in the REST API, a requisition might have a link with rel=requisition/approve to some URI, and we might want a Requisition Approval to back this, rather than just capturing this in requisition.status, requisition.lineItems.quantityApproved, and requisition.statusChanges)
Requisition_line_item
id | |
requisition | |
product | code, or fk to product table |
productDisplayOrder | sort order of the products (within each category) |
productCategory | |
productCategoryDisplayOrder | sort order of the product categories |
quantityRequested | |
quantityApproved | |
skip | Is this really needed? If the uses checks "skip" in the UI, can we just decline to add a cooresponding row? |
packsToShip | (may not be at top level) |
reason | reason for requested quantity |
remarks | Used as part of approval process (should rename to approvalRemarks) |
(part of reporting, but not necessarily in top-level requisition domain) | |
quantityRecieved | |
beginingBalance | |
quantityRecieved | |
quantityDispensed | Used for reporting: tells you what was dispensed over the last period |
stockInHand | |
calculatedOrderQuantity | calculated by the system |
totalLossesAndAdjustments | |
newPatientCount | |
stockoutDays | Used for reporting |
normalizedConsumption | |
previousNormalizedConsumption | |
periodNormalizedConsumption | |
AMC | |
price | |
expirationDate | |
previousStockInHand | |
(copied reference data) | if underlying data is mutable, take snapshot of values of these fields in this table |
dispensingUnit | |
maxMonthsOfStock | |
maxStockQuantity | |
dosesPerDispensingUnit | |
dosesPerMonth | |
packSize | |
roundToZero | |
packRoundingThreshold | |
fullSupply | |
reportingDays |
Requisition Strategy
RequisitionAdviceStrategy(Facility, Program, ProcessingPeriod, RequisitionTemplate) → Requisition
- For v1, we can implement a simple strategy that gets products, product categories (and similar) w/o determining amounts, and implement additional logic for calculating amounts in a later version of the reference strategy
Reference Data
Will want to take some fields in these tables and put it into extensions, either through a JSON extradata field or attribute type and attribute tables, or something similar.
Program
id | |
code | |
name | |
description | |
active | |
processes | NEW, workflows in a particular program, ex: vaccine program might use requisition process at higher level, but allocation process at lower level |
createdby | |
createddate | |
modifiedby | |
modifieddate | |
implementations should handle these via attributes or json extradata field | |
enableivdform | |
isequipmentconfigured |
Program Process
push? | column to determine if requisition, allocation, etc. is turned on |
program_requisition_config table
budgetingapplies | |
usepriceschedule | |
sendfeed | |
hideskippedproducts | |
shownonfullsupplytab | |
enableskipperiod |
Program Product
Program Product ISA
Program Product Price
Facility
id | |
code | |
name | |
description | |
geographiczoneid | |
typeid | |
catchmentpopulation | possibly might want to move this out to an extension |
operatedbyid | |
active | |
golivedate | |
godowndate | |
comment | |
enabled | |
location | has location related attributes (mainphone, fax, address, lat, long, altitude, etc.) |
createdby | |
createddate | |
modifiedby | |
modifieddate | |
implementations should handle these via attributes or json extradata field | |
gln | |
coldstoragegrosscapacity | |
coldstoragenetcapacity | |
online | |
satellite | |
pricescheduleid | |
haselectricity | |
haselectronicdar | |
suppliesothers | |
sdp | |
haselectronicscc | this one should probably move into inventory management context |
facility ftp details |
facility_demographic_estimates; demography as another domain?
facility_mappings; support mapping to DHIS2 facility code somehow (ELMIS)
mos_adjustment_facilities, order_quantity_adjustment_products; ???
Facility Type
id | |
code | |
name | |
description | |
displayorder | |
active | |
createddate | |
createdby | |
modifiedby | |
modifieddate | |
implementations should handle these via attributes or json extradata field | |
nominalmaxmonth | |
nominaleop |
Note: consider an alternate model of facility capabilities, instead or in addition to facility type
Facility Operator
id | |
code | |
name | |
description | |
displayorder | |
createddate | |
createdby | |
modifiedby | |
modifieddate |
Program Supported
id | |
facility | |
program | |
startdate | |
active | |
standard audit fields |
Processing Schedule
id | |
code | |
name | |
description | |
standard audit fields |
Processing Period
id | |
processingSchedule | |
name | |
description | |
startdate | |
enddate | |
numberofmonths | is this needed? |
standard audit fields |
TODO: Get rid of period short name and include as a field in Processing Period?
Is this a sub-resource of Processing Schedule?
Hierarchy and Supervision
Supervisory Node
TODO: consider along with other things that deal with hierarchy and supervision
Requisition Groups and Members
Supply Lines
Geographic Zones and Levels
User
id | |
username | |
password | |
firstname | |
lastname | |
restrictlogin | does this duplicate active? |
primarynotificationmethod | consider pulling all notification into its own domain |
officephone | consider pulling all notification into its own domain |
cellphone | consider pulling all notification into its own domain |
consider pulling all notification into its own domain | |
supervisorid | |
facilityid | |
verified | |
active | |
preferences | user-specific preference settings |
roleAssignments | consider pulling some of this functionality out into a supervisions domain |
implementations should handle these via attributes or json extradata field | |
employeeid | |
jobtitle | |
ismobileuser |
user_password_reset_tokens
Role
Right
"Product" (Requestable)
Dosage Unit
Product Form
Product Category
Product (Commodity)
Kit
Generic Product/Branded Product
Product "Type" (for impact)
Program Product
Program Product ISA
Program Product Price
Facility (Type) Approved Program Product
Inventory Management
Not all of these may be domain models
Stock Card
Stock Card Entry
Stock Movement
Stock Movement Line Item
Lot (and Lot on Hand?)
Stock Event
Stock Event Type
Stock Adjustment Reason
Shipping/Receiving
Its own context or under Fulfillment context? Currently mentioned under fulfillment
Program Data
Open Questions
Can we merge fulfillment_role_assignments into role_assignments?
OpenLMIS: the global initiative for powerful LMIS software