After further circulating the "product model" with representatives of GS1, USAID, BI&A LRM (Intellicog - Logical Reference Model) it has become clear that a few changes to the OpenLMIS "product model" would help put the community and the code-base a step further in learning from best practices.
- Removal of the word "Product" as each stakeholder in the supply chain has their own view of what a "product" is. Therefore:
- OrderableProduct changes to Orderable (likewise class ProgramProduct changes to ProgramOrderable)
- ProductCategory changes to OrderableDisplayCategory
- GlobalProduct changes to CommodityType
- . Instead a TradeItem will have an attribute that lists all of the CommodityTypes it is (1 per classification system). This identifier will serve as a cross-reference to CommodityType if that classification system is in use in the OpenLMIS implementation.
- CommodityType and TradeItem now have an Orderable, rather than as a sub-class to Orderable. This change better reflects the nature of a TradeItem not being a sub-class of an Orderable, rather it shows that a TradeItem may be the source or backing of an Orderable.
- CommodityTypes will become heirarchical as they are a representation of a GS1 classification system. A CommodityType knows its parent using Adjacency List (like supervisory nodes), and a parent may have multiple children. This allows for heirarchy and branching that classification systems typically exhibit and follows GS1 best practice in allowing an implementation to mix and match existing classification systems in practice.
- The resource /orderableProducts (now /orderables) will only return Orderables. To further get the TradeItem or CommodityType that created the Orderable, the client will use the identifiers collection in the response of the Orderable to see if an identifier for a TradeItem or CommodityType is present.
- Orderable's are no longer able to determine if any other Orderable may fulfill for it - atleast not alone. Instead:
- A TradeItem knows if it may fulfill for a CommodityType if:
- the TradeItem is classified by the CommodityType or one of the CommodityType's children
- AND the CommodityType has an Orderable which has an equivalent Dispensible as the Orderable which the TradeItem has.
- A TradeItem may be fulfillable by another TradeItem - e.g. if an EDI TradeItem Align message were received. This is diagramed by the method TradeItem.mayFulfillFor(TradeItem), however the classes necessary for this are not yet diagrammed
Changes in orange:
TradeItem fulfills for TradeItem (EDI TradeItem Align)
, however this should mostly follow EDI Item Data Notification - which for OpenLMIS would start as a direct substitution model.
TradeItem fulfill for CommodityType
Given a classification system such as UNSPSC for Mefloquine (used to prevent/treat Malaria):
Drugs and Pharmaceutical Products (51100000) → Antiprotozoals (51101900) → Mefloquine (51101902)
In OpenLMIS, this hierarchy would represent each level in the above as a CommodityType. There are of course a number of manufacturers/brands of Mefloquine that would be represented as TradeItems. e.g. Altimef and Confal (source). To create a fulfilable relationship between Altimef and Confal with we need the following:
- Altimef and Confal need to list that in UNSPSC, they are classified by Mefloquine.
- Altimef and Confal need to create one or more Orderable's that setup things like the OpenLMIS product code, the Dispensible, number of dispensing units are in the pack, etc. In the future, many of these attributes could be pulled directly from TradeItem information through a GDSN using their respective GTINs.
- . The information needed for an Orderable aren't present in UNSPSC and so we'd have to setup the Product Code, Dispensible, etc. For the fulfill for to work, we'll need to set up Dispensables that Altimef and Confal.
Therefore these links rely heavily on the information that may be found in TradeItems and classification systems. Where we need to go further, so that we may list Mefloquine on our order form, we must create Orderable's for . If Altimef comes in individual pills of 100mg, and Confal comes in strips of 2 pills of 25mg then we will need to create Orderables in OpenLMIS for Mefloquine that will match with those Dispensibles from Altimef and Confal.