Skip to content

Commit 879f079

Browse files
authored
HTML-878: Order Tag should support placing orders for the same drug at an earlier date if the expiry date doesn't overlap (#330)
1 parent 2f98750 commit 879f079

2 files changed

Lines changed: 80 additions & 4 deletions

File tree

api-tests/src/test/java/org/openmrs/module/htmlformentry/element/OrderSubmissionElementTest.java

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,70 @@ public void shouldFailValidationIfOverlappingOrders() {
135135
FormResultsTester results = formSessionTester.submitForm();
136136
results.assertErrorMessage("htmlformentry.orders.overlappingScheduleWithActiveOrder");
137137
}
138-
139-
@Test
138+
139+
@Test
140+
public void shouldAllowEarlierOrderIfNonOverlappingByCalculatedExpiryDate() {
141+
FormTester formTester = FormTester.buildForm("orderTestForm.xml");
142+
143+
// Enter an encounter with an order for drug 2
144+
{
145+
FormSessionTester formSessionTester = formTester.openNewForm(6);
146+
formSessionTester.setEncounterFields("2020-03-30", "2", "502");
147+
OrderFieldTester triomuneField = OrderFieldTester.forDrug(2, formSessionTester);
148+
triomuneField.orderAction("NEW").careSetting("2").urgency(Order.Urgency.ROUTINE.name());
149+
triomuneField.freeTextDosing("Triomune instructions");
150+
FormResultsTester results = formSessionTester.submitForm();
151+
results.assertNoErrors().assertEncounterCreated().assertOrderCreatedCount(1).assertNonVoidedOrderCount(1);
152+
DrugOrder o1 = results.assertDrugOrder(Order.Action.NEW, 2);
153+
TestUtil.assertDate(o1.getDateActivated(), "yyyy-MM-dd HH:mm:ss", "2020-03-30 00:00:00");
154+
assertThat(o1.getDateStopped(), nullValue());
155+
}
156+
157+
// Now, enter an encounter month earlier, but with a duration of only 20 days
158+
FormSessionTester formSessionTester = formTester.openNewForm(6);
159+
formSessionTester.setEncounterFields("2020-02-28", "2", "502");
160+
OrderFieldTester triomuneField = OrderFieldTester.forDrug(2, formSessionTester);
161+
triomuneField.orderAction("NEW").careSetting("2").urgency(Order.Urgency.ROUTINE.name());
162+
triomuneField.freeTextDosing("Triomune instructions");
163+
triomuneField.duration("20");
164+
triomuneField.durationUnits("28"); // duration concept for days
165+
FormResultsTester results = formSessionTester.submitForm();
166+
results.assertNoErrors().assertEncounterCreated().assertOrderCreatedCount(1).assertNonVoidedOrderCount(1);
167+
}
168+
169+
@Test
170+
public void shouldNotAllowEarlierOrderIfOverlappingByCalculatedExpiryDate() {
171+
FormTester formTester = FormTester.buildForm("orderTestForm.xml");
172+
173+
// Enter an encounter with an order for drug 2
174+
{
175+
FormSessionTester formSessionTester = formTester.openNewForm(6);
176+
formSessionTester.setEncounterFields("2020-03-30", "2", "502");
177+
OrderFieldTester triomuneField = OrderFieldTester.forDrug(2, formSessionTester);
178+
triomuneField.orderAction("NEW").careSetting("2").urgency(Order.Urgency.ROUTINE.name());
179+
triomuneField.freeTextDosing("Triomune instructions");
180+
FormResultsTester results = formSessionTester.submitForm();
181+
results.assertNoErrors().assertEncounterCreated().assertOrderCreatedCount(1).assertNonVoidedOrderCount(1);
182+
DrugOrder o1 = results.assertDrugOrder(Order.Action.NEW, 2);
183+
TestUtil.assertDate(o1.getDateActivated(), "yyyy-MM-dd HH:mm:ss", "2020-03-30 00:00:00");
184+
assertThat(o1.getDateStopped(), nullValue());
185+
}
186+
187+
// Now, enter an encounter month earlier, with a duration of 40 days
188+
FormSessionTester formSessionTester = formTester.openNewForm(6);
189+
formSessionTester.setEncounterFields("2020-02-28", "2", "502");
190+
OrderFieldTester triomuneField = OrderFieldTester.forDrug(2, formSessionTester);
191+
triomuneField.orderAction("NEW").careSetting("2").urgency(Order.Urgency.ROUTINE.name());
192+
triomuneField.freeTextDosing("Triomune instructions");
193+
triomuneField.duration("40");
194+
triomuneField.durationUnits("28"); // duration concept for days
195+
FormResultsTester results = formSessionTester.submitForm();
196+
results.assertErrorMessage("htmlformentry.orders.overlappingScheduleWithActiveOrder");
197+
}
198+
199+
200+
201+
@Test
140202
public void shouldFailValidationIfMultipleOrdersPlacedForSameOrderable() {
141203
FormTester formTester = FormTester.buildForm("orderTestForm.xml");
142204

api/src/main/java/org/openmrs/module/htmlformentry/element/OrderSubmissionElement.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.openmrs.Concept;
99
import org.openmrs.Drug;
1010
import org.openmrs.DrugOrder;
11+
import org.openmrs.Duration;
1112
import org.openmrs.Encounter;
1213
import org.openmrs.FreeTextDosingInstructions;
1314
import org.openmrs.Order;
@@ -35,6 +36,8 @@
3536
import java.util.Map;
3637
import java.util.Set;
3738

39+
import static org.apache.commons.lang3.time.DateUtils.addSeconds;
40+
3841
/**
3942
* Holds the widgets used to represent orders for a configured set of orderables (concepts, drugs),
4043
* and serves as both the HtmlGeneratorElement and the FormSubmissionControllerAction for the
@@ -352,7 +355,7 @@ public boolean overlapsWithExistingDrugOrder(FormEntryContext ctx, List<Order> e
352355
return false;
353356
}
354357

355-
private boolean checkScheduleOverlap(FormEntryContext ctx, Order newOrder, Order existingOrder) {
358+
private boolean checkScheduleOverlap(FormEntryContext ctx, DrugOrder newOrder, Order existingOrder) {
356359
Date newStart = newOrder.getEffectiveStartDate();
357360
Date newStop = newOrder.getEffectiveStopDate();
358361
Date existingStart = existingOrder.getEffectiveStartDate();
@@ -361,7 +364,18 @@ private boolean checkScheduleOverlap(FormEntryContext ctx, Order newOrder, Order
361364
if (newStart == null) {
362365
newStart = ctx.getBestApproximationOfEncounterDate();
363366
}
364-
367+
368+
// attempt to estimate the stop date based on the auto-expire date
369+
if (newStop == null) {
370+
if (newOrder.getDuration() != null && newOrder.getDurationUnits() != null) {
371+
String durationCode = Duration.getCode(newOrder.getDurationUnits());
372+
if (durationCode != null) {
373+
Duration duration = new Duration(newOrder.getDuration(), durationCode);
374+
newStop = addSeconds(duration.addToDate(newStart, newOrder.getFrequency()),-1);
375+
}
376+
}
377+
}
378+
365379
// If both orders start on the same date, then they overlap
366380
if (OpenmrsUtil.compareWithNullAsLatest(newStart, existingStart) == 0) {
367381
return true;

0 commit comments

Comments
 (0)