Cannot stop drugs because of minor time difference between client and server
Description
Attachments
Gliffy Diagrams
Activity

swathi varkala July 24, 2018 at 11:22 AM
: Tested by users. this looks ok. issue reproducible on demo and working fine on qa.

Angshuman Sarkar July 19, 2018 at 1:34 PMEdited
Fixed temporarily by sending dateActivated for stopped drug to NULL. This would need further investigation and refactoring to put a proper fix. Created a TECH-DEBT card [BAH-590 [TECH DEBT] Discontinuation of Drug|https://bahmni.atlassian.net/browse/BAH-590] for release 0.93

Darius Jazayeri May 30, 2018 at 9:16 PM
Tech Analysis
Here is a deep-dive analysis of the code. (I didn't actually test this against the running app, this is what I infer from using the JSON post from Maharjun's recent comment)
We post a drug order that looks like this:
FYI from the OpenMRS perspective we are doing this wrong. If we're sending a new "discontinuation order" this should only include action=discontinue, one date, and a link to the order to be discontinued. (We should not be including all the details of the previous order to be discontinued as if they're part of the new discontinuation order.)
Our submission is eventually inspected by BahmniEncounterTransactionServiceImpl.handleDrugOrders. Since there's >=1 order whose scheduledDate is in the past (this is actually the scheduledDate of the order we are stopping, not really today's action), it does cloneForPastDrugOrders and saves this in a past encounter transaction. (I think this section of code is not ideal, because it means that if you're stopping one drug order and starting another one they both will get saved in a "past encounter transaction". But that is not new for this issue.)
Because it's a past encounter transaction, this goes via BahmniEncounterTransaction#updateForRetrospectiveEntry and
BahmniEncounterTransaction#updateDrugOrderDates which sets dateActivated to encounterDate if it was null. (I think this is why sending a null dateActivated works.)
This eventually hits org.openmrs.module.emrapi.encounter.EmrOrderServiceImpl_1_12#save(List<DrugOrder> drugOrders, Encounter encounter). This groups things in OrderGroups (irrelevant for this example) and delegates to the OpenMRS Java API's EncounterService.saveEncounter
EncounterService.saveEncounter eventually delegates to openmrs-core's OrderService.saveOrder and https://github.com/openmrs/openmrs-core/blob/2.1.3/api/src/main/java/org/openmrs/api/impl/OrderServiceImpl.java#L128
Since action=discontinue, most of what we submit is ignored, and we end up in discontinueExistingOrdersIfNecessary: https://github.com/openmrs/openmrs-core/blob/2.1.3/api/src/main/java/org/openmrs/api/impl/OrderServiceImpl.java#L338
This calls stopOrder(previousOrder, aMomentBefore(order.getDateActivated()), ...) on the previous order https://github.com/openmrs/openmrs-core/blob/2.1.3/api/src/main/java/org/openmrs/api/impl/OrderServiceImpl.java#L726 which sets dateStopped on the previous order.
Then our new discontinuation order is saved (this is the continuation of OrderService.saveOrder).
Conclusion
The code is quite complex, and I agree with Angshuman that it's a bad idea to edit this based on trial and error of calling the REST API. If you ensure we have good enough test coverage of all scenarios I could possibly live with this change, but that seems tough given the remaining time.
In particular I think that the proposed change will do the wrong thing if you try to stop two drug orders that have different start dates, because BahmniEncounterTransaction#cloneForPastDrugOrders sets the encounterDatetime to the oldest scheduledDate.
I think the correct thing to do would be to clean up our front-end code so that we're only submitting the minimal set of data that's supposed to be used to discontinue an order (on stopping an order) and clean up our back-end code so that we're sending a valid and appropriate data model to openmrs-core. (E.g. stopping a drug order should be done by creating a discontinuation order in the current encounter transaction, regardless of the fact that the original order was started before.) But this is also unrealistic to do and merge in one day.

Maharjun M May 30, 2018 at 5:24 PMEdited
We found where this error is being thrown but unable to find where the dateActivated is being set.
Error is thrown from this file(openmrs-api-2.1.1.jar/org/openmrs/validator/ValidateUtil.java (at line no:- 45)) which is invoking from another file(openmrs-api-2.1.1.jar/org/openmrs/validator/OrderValidator.java (at line no:- 129))

Maharjun M May 30, 2018 at 5:11 PM
We saved the drug order info from DB in the following CSV file
Details
Assignee
Angshuman SarkarAngshuman SarkarReporter
Charles JohnCharles JohnUAT Assignee
Arjun KhandelwalArjun KhandelwalComponents
Sprint
NoneFix versions
Priority
Major
Details
Details
Assignee

Reporter

UAT Assignee

Multiple clients (JSS/LBP) reported this issue when trying to stop a drug. Please see the attachment for the error thrown.
The corresponding error log is as below:
This error happens intermittently. Also, see this https://talk.openmrs.org/t/issues-stopping-tb-drug-orders-with-the-current-date-as-the-stop-date/12048