Versioning in FacilityTypeApprovedProducts - approach

Hello everyone,

as a part of the updating products epic, I’m currently looking into the approach to version (or not) the FacilityTypeApprovedProducts. There are two main questions that need to be answered:

  • Should FTAPs be versioned themselves?
  • Should FTAPs reference specific versions of orderable?

Before diving into those questions, a quick recap on the FTAPs:

Facility Type Approved Products allow you to segment orderables by facility type. Although a program supports a specific list of orderables, different facilities may not have the capacity to support providing the orderables. This is why you would want to segment orderables by facility type. Each facility that performs duties related to the requisition process must be set up with their Facility Type Approved Products.

How does that look in practice? FTAPs are taken into consideration in two of our services: requisition and stock management.

Requisitions rely on the two things in FTAPs: first of all - their presence. A newly initiated requisition will only be populated with the products that are supported for the given program and at the associated facility type. In other words, an FTAP entry must exist in the database for the combination of an orderable-facility type-program in order for that product to appear in requisitions. If there’s no such entry, the product won’t appear in the requisitions. If the FTAP entry was there at some point but was removed later on, all the past requisitions will properly display and link to that product, but no new requisitions will have that product included anymore. The second thing that requisitions need from FTAPs is the max periods of stock property that OpenLMIS allows to set for each orderable-facility type-program combo separately. This property helps calculate the reorder quantities for the product in requisitions.

Things get a little more blurry with the Stock management service. FTAPs help determine which products we can manage at any given facility. If there’s an FTAP entry for the given orderable-facility type-program combo, we will be able to manage the given product at the facility - include it in the physical inventory, receive from another facility, issue to other facilities and view its stock on hand. If the entry is removed, we lose access to the related stock card - we can no longer receive or issue that product, or even view its historical transactions. The Stock Management service only relies on the presence of the FTAP entry. Whether the current behavior is expected is unclear to me at the moment. It seems weird that we even lose read-only access to the stock card - on the other hand, if we wanted to ensure the access to the historical transactions, we would need to somehow mark that this product is no longer managed for this facility.

Now, how does this impact our questions? Should we version FTAPs? In my opinion - no. With FTAPs we are mainly interested in “here and now”. If an entry for FTAP exists, we include it in new requisitions or allow stock transactions. This fact of “presence” of the FTAP entry is directly captured in created requisitions and stock cards. If the requisition contains a given product it means that an FTAP entry existed. Same with stock cards - if it exists, it means that the FTAP for the product existed at some point. The only property we are interested in capturing is the max periods of stock value in requisitions and we would like to keep it as it was at the time of requisition initiate. It seems though that introducing versioning just for this single property doesn’t make much sense. Especially, that if we resigned from snapshotting it in requisition, we would need to make an additional call for each product to retrieve its value in requisitions.

How about having FTAPs reference a specific version of the orderable? In other words, if I update my orderable (e.g. by changing its price, or pack size) do I automatically want to cancel the existing support for this product in requisitions and stock management? Based on the observations of product updates in Malawi, that doesn’t seem to be the case. All product updates are separate from their support at the facilities and programs. Based on the first question, it also doesn’t look like we need to keep track of which orderable versions were supported by FTAP. Clients of the FTAP endpoint are not interested in this - they only need to know whether the product is supported right now.

Summarizing all of the above, the path forward that I see is:

  • Do not introduce versioning of FTAPs
  • Drop the reference to orderable by its version and restore the relation that we originally had - by orderable id

If you have made it through that post - congrats! Now let me know what are your thoughts :slight_smile: This is a complex topic, so any feedback is welcome before we go into the action with the implementation work.

Best regards,
Sebastian

Hey @Sebastian_Brudzinski,

Thanks for this write-up; it’s quite thorough.

I now can’t remember why we decided to version FTAPs, so I will not respond to that in this post, but I agree that the FTAP should not need to reference an orderable by its version. The reason why it does that in this case is because of how our database schema is set up. FTAPs have a foreign key to the orderable, so when we made a new composite primary key of orderables, including the version id, the foreign key also had to reference the version. If we do drop the reference to orderable by its version, we’ll need to do that by removing the foreign key altogether. I’ll leave it up to you to determine the effects, if any, that will do to the system.

Shalom,
Chongsun

Thanks @Sebastian_Brudzinski,

On your second question, what I recall is that we did not want to hold a versioned reference to the Orderable. Agreed there.

On your first question I think you make a good point, though I would be wary in two areas:

  • The other fields of an FTAP, min periods of stock and emergency order point, aren’t currently snapshotted in the Requisition. In versions prior to v3 these used to show up on the printed form of the Requisition and in certain reports. I’m not sure if these are left over fields that implementations no longer have use for, or if our current v3 implementations simply haven’t chosen to use them yet.
  • I’m concerned that having two approaches, snapshotting and versioned reference data, would add extra confusion to developers attempting to on-board. Additionally one of the reason’s we moved away from snapshotting is that we were missing fields in the snapshot’s we took in Requisition’s and this had the potential to introduce breaking Orderable updates.

Overall I agree that it’s easier to rely on the already snapshotted maxperiodsofstock field, however I’d be concerned we’re leaving a trap for future developers and adding to the patterns in the source without making it clear which we prefer. Is there a middle ground? Could we version the FTAP and record it in the Requisition, but keep relying on the snapshotted maxperiodsofstock? If that’s reasonable we could atleast provide a path for which direction we’re moving in terms of snapshotting vs. versioning.

Best,
Josh

Thanks for the replies!

One thing that I forgot to explicitly mention, is that the current workflow to remove support for any given product at the facility type is to remove the corresponding FTAP entry. With FTAP versioning that will no longer be possible. The simple solution is to additionally introduce the “active” flag to FTAPs, modify our endpoints appropriately to take it into consideration, and modify the workflow to update the flag to inactive, rather than deleting the FTAP, to remove the support.

The only other bigger concern with the complete versioning of FTAP is the potential performance drop caused by the additional call to fetch FTAPs at each stage of the requisition workflow. We could probably think of some ways to mitigate it, like returning an orderable with the FTAP resource, but that’s yet another thing we would need to invest some time into.

To be honest, I’ve got mixed feelings about the proposed middle ground. I don’t see, how it would make it clear for a new developer to determine which approach we prefer. They might still tend to think it’s snapshotting, because that’s what we would be ultimately using.

My slight preference would be to either go with full versioning support, and accept this will consume more resources to figure out the above problems, or just stay with snapshotting, at least for 3.7, but I’m keeping an open mind on this.

Best regards,
Sebastian

Then I’d agree lets skip the middle ground and try to get full versioning support, it’ll be more consistent.