Skip to content

Commit c3e9f39

Browse files
TRUNK-5964: Hard-coded uuids for drug order type and test order type. (#4585)
1 parent 7c63401 commit c3e9f39

File tree

5 files changed

+168
-8
lines changed

5 files changed

+168
-8
lines changed

api/src/main/java/org/openmrs/api/OrderService.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,35 @@ public Order discontinueOrder(Order orderToDiscontinue, String reasonNonCoded, D
724724
*/
725725
@Authorized(PrivilegeConstants.GET_ORDER_TYPES)
726726
public OrderType getOrderTypeByConcept(Concept concept);
727-
727+
728+
/**
729+
* Get order types by java class name
730+
*
731+
* @param javaClassName the class name used to get the order types
732+
* @param includeRetired boolean flag for include retired or not
733+
* @since 3.0.0
734+
* @return return the order types associated with given class name
735+
* <strong>Should</strong> find order types with the specified class name
736+
* <strong>Should</strong> get include retired order types if includeRetired is set to true
737+
*/
738+
@Authorized(PrivilegeConstants.GET_ORDER_TYPES)
739+
public List<OrderType> getOrderTypesByClassName(String javaClassName, boolean includeRetired) throws APIException;
740+
741+
/**
742+
* Get order types by java class name
743+
*
744+
* @param javaClassName the class name used to get the order types
745+
* @param includeSubclasses boolean flag for include subclasses or not
746+
* @param includeRetired boolean flag for include retired or not
747+
* @since 3.0.0
748+
* @return return the order types associated with given class name
749+
* <strong>Should</strong> find order types with the specified class name
750+
* <strong>Should</strong> get include order types subclasses if includeSubclasses is set to true
751+
* <strong>Should</strong> get include retired order types if includeRetired is set to true
752+
*/
753+
@Authorized(PrivilegeConstants.GET_ORDER_TYPES)
754+
public List<OrderType> getOrderTypesByClassName(String javaClassName, boolean includeSubclasses, boolean includeRetired) throws APIException;
755+
728756
/**
729757
* Gets the possible drug routes, i.e the set members for the concept that matches the uuid
730758
* specified as the value for the global property

api/src/main/java/org/openmrs/api/db/OrderDAO.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,11 @@ public List<OrderFrequency> getOrderFrequencies(String searchPhrase, Locale loca
202202
* @see org.openmrs.api.OrderService#getOrderTypeByConceptClass(org.openmrs.ConceptClass)
203203
*/
204204
public OrderType getOrderTypeByConceptClass(ConceptClass conceptClass);
205+
206+
/**
207+
* @see org.openmrs.api.OrderService#getOrderTypesByClassName(String, boolean)
208+
*/
209+
public List<OrderType> getOrderTypesByClassName(String javaClassName, boolean includeRetired) throws DAOException;
205210

206211
/**
207212
* @see org.openmrs.api.OrderService#saveOrderType(org.openmrs.OrderType)

api/src/main/java/org/openmrs/api/db/hibernate/HibernateOrderDAO.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,31 @@ public OrderType getOrderTypeByConceptClass(ConceptClass conceptClass) {
778778
"from OrderType where :conceptClass in elements(conceptClasses)").setParameter("conceptClass", conceptClass)
779779
.uniqueResult();
780780
}
781+
782+
/**
783+
* @see org.openmrs.api.OrderService#getOrderTypesByClassName(String, boolean)
784+
*/
785+
@Override
786+
public List<OrderType> getOrderTypesByClassName(String javaClassName, boolean includeRetired) throws DAOException {
787+
if (StringUtils.isBlank(javaClassName)) {
788+
throw new APIException("javaClassName cannot be null");
789+
}
790+
791+
Session session = sessionFactory.getCurrentSession();
792+
CriteriaBuilder cb = session.getCriteriaBuilder();
793+
CriteriaQuery<OrderType> cq = cb.createQuery(OrderType.class);
794+
Root<OrderType> root = cq.from(OrderType.class);
795+
796+
List<Predicate> predicates = new ArrayList<>();
797+
if (!includeRetired) {
798+
predicates.add(cb.isFalse(root.get("retired")));
799+
}
800+
predicates.add(cb.equal(root.get("javaClassName"), javaClassName));
801+
802+
cq.where(predicates.toArray(new Predicate[]{}));
803+
804+
return session.createQuery(cq).getResultList();
805+
}
781806

782807
/**
783808
* @see org.openmrs.api.OrderService#saveOrderType(org.openmrs.OrderType)

api/src/main/java/org/openmrs/api/impl/OrderServiceImpl.java

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -270,13 +270,13 @@ private void ensureOrderTypeIsSet(Order order, OrderContext orderContext) {
270270
orderType = getOrderTypeByConcept(order.getConcept());
271271
}
272272
if (orderType == null && order instanceof DrugOrder) {
273-
orderType = Context.getOrderService().getOrderTypeByUuid(OrderType.DRUG_ORDER_TYPE_UUID);
273+
orderType = getDefaultOrderType(DrugOrder.class, OrderType.DRUG_ORDER_TYPE_UUID);
274274
}
275275
if (orderType == null && order instanceof TestOrder) {
276-
orderType = Context.getOrderService().getOrderTypeByUuid(OrderType.TEST_ORDER_TYPE_UUID);
276+
orderType = getDefaultOrderType(TestOrder.class, OrderType.TEST_ORDER_TYPE_UUID);
277277
}
278278
if (orderType == null && order instanceof ReferralOrder) {
279-
orderType = Context.getOrderService().getOrderTypeByUuid(OrderType.REFERRAL_ORDER_TYPE_UUID);
279+
orderType = getDefaultOrderType(ReferralOrder.class, OrderType.REFERRAL_ORDER_TYPE_UUID);
280280
}
281281
if (orderType == null) {
282282
throw new OrderEntryException("Order.type.cannot.determine");
@@ -312,10 +312,21 @@ private void failOnOrderTypeMismatch(Order order) {
312312

313313
private boolean areDrugOrdersOfSameOrderableAndOverlappingSchedule(Order firstOrder, Order secondOrder) {
314314
return firstOrder.hasSameOrderableAs(secondOrder)
315-
&& !OpenmrsUtil.nullSafeEquals(firstOrder.getPreviousOrder(), secondOrder)
316-
&& OrderUtil.checkScheduleOverlap(firstOrder, secondOrder)
317-
&& firstOrder.getOrderType().equals(
318-
Context.getOrderService().getOrderTypeByUuid(OrderType.DRUG_ORDER_TYPE_UUID));
315+
&& !OpenmrsUtil.nullSafeEquals(firstOrder.getPreviousOrder(), secondOrder)
316+
&& OrderUtil.checkScheduleOverlap(firstOrder, secondOrder)
317+
&& firstOrder.getOrderType().equals(getDefaultOrderType(DrugOrder.class, OrderType.DRUG_ORDER_TYPE_UUID));
318+
}
319+
320+
private OrderType getDefaultOrderType(Class<? extends Order> orderSubclass, String fallbackUuid) {
321+
OrderType type = getOrderTypeByUuid(fallbackUuid);
322+
323+
if (type == null) {
324+
List<OrderType> types = getOrderTypesByClassName(orderSubclass.getName(), true, false);
325+
if (types.size() == 1) {
326+
type = types.get(0);
327+
}
328+
}
329+
return type;
319330
}
320331

321332
private boolean isDrugOrder(Order order) {
@@ -1061,6 +1072,47 @@ public OrderType getOrderTypeByConceptClass(ConceptClass conceptClass) {
10611072
public OrderType getOrderTypeByConcept(Concept concept) {
10621073
return Context.getOrderService().getOrderTypeByConceptClass(concept.getConceptClass());
10631074
}
1075+
1076+
/**
1077+
* @see org.openmrs.api.OrderService#getOrderTypesByClassName(String, boolean)
1078+
*/
1079+
@Override
1080+
@Transactional(readOnly = true)
1081+
public List<OrderType> getOrderTypesByClassName(String javaClassName, boolean includeRetired) throws APIException {
1082+
return dao.getOrderTypesByClassName(javaClassName, includeRetired);
1083+
}
1084+
1085+
/**
1086+
* @see org.openmrs.api.OrderService#getOrderTypesByClassName(String, boolean, boolean)
1087+
*/
1088+
@Override
1089+
@Transactional(readOnly = true)
1090+
public List<OrderType> getOrderTypesByClassName(String javaClassName, boolean includeSubclasses, boolean includeRetired) throws APIException {
1091+
if (!StringUtils.hasText(javaClassName)) {
1092+
throw new APIException("javaClassName cannot be null");
1093+
}
1094+
1095+
if (!includeSubclasses) {
1096+
return getOrderTypesByClassName(javaClassName, includeRetired);
1097+
}
1098+
1099+
Class<?> superClass;
1100+
try {
1101+
superClass = Context.loadClass(javaClassName);
1102+
} catch (ClassNotFoundException e) {
1103+
throw new APIException("Invalid javaClassName: " + javaClassName, e);
1104+
}
1105+
1106+
return getOrderTypes(includeRetired).stream()
1107+
.filter(ot -> {
1108+
try {
1109+
Class<?> c = Context.loadClass(ot.getJavaClassName());
1110+
return superClass.isAssignableFrom(c);
1111+
} catch (Exception ignore) {
1112+
return false;
1113+
}
1114+
}).toList();
1115+
}
10641116

10651117
/**
10661118
* @see org.openmrs.api.OrderService#getDrugRoutes()

api/src/test/java/org/openmrs/api/OrderServiceTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2762,6 +2762,53 @@ public void getOrderTypeByConcept_shouldGetOrderTypeMappedToTheGivenConcept() {
27622762
assertEquals(2, orderType.getOrderTypeId().intValue());
27632763
}
27642764

2765+
/**
2766+
* @see org.openmrs.api.OrderService#getOrderTypesByClassName(String, boolean)
2767+
*/
2768+
@Test
2769+
public void getOrderTypesByClassName_shouldReturnOrderTypesForTheGivenJavaClassName() {
2770+
List<OrderType> drugOrderTypes = orderService.getOrderTypesByClassName(DrugOrder.class.getName(), false);
2771+
2772+
assertNotNull(drugOrderTypes);
2773+
assertEquals(1, drugOrderTypes.size());
2774+
assertEquals("Drug order", drugOrderTypes.get(0).getName());
2775+
2776+
List<OrderType> testOrderTypes = orderService.getOrderTypesByClassName(TestOrder.class.getName(), false);
2777+
2778+
assertNotNull(testOrderTypes);
2779+
assertEquals(2, testOrderTypes.size());
2780+
assertEquals("Test order", testOrderTypes.get(0).getName());
2781+
}
2782+
2783+
/**
2784+
* @see org.openmrs.api.OrderService#getOrderTypesByClassName(String, boolean, boolean)
2785+
*/
2786+
@Test
2787+
public void getOrderTypesByClassName_shouldReturnOrderTypesForTestOrderAndItsSubclasses() {
2788+
// create and save a new OrderType for MyTestOrder
2789+
OrderType myTestOrderType = new OrderType();
2790+
myTestOrderType.setName("My Test Order");
2791+
myTestOrderType.setJavaClassName(MyTestOrder.class.getName());
2792+
Context.getOrderService().saveOrderType(myTestOrderType);
2793+
2794+
List<OrderType> polymorphicTestOrderTypes = orderService.getOrderTypesByClassName(TestOrder.class.getName(), true, false);
2795+
2796+
assertNotNull(polymorphicTestOrderTypes);
2797+
2798+
// should include the original TestOrder types + the new subclass
2799+
assertEquals(3, polymorphicTestOrderTypes.size());
2800+
assertTrue(polymorphicTestOrderTypes.stream()
2801+
.anyMatch(ot -> MyTestOrder.class.getName().equals(ot.getJavaClassName())));
2802+
}
2803+
2804+
/**
2805+
* @see org.openmrs.api.OrderService#getOrderTypesByClassName(String, boolean)
2806+
*/
2807+
@Test
2808+
public void getOrderTypesByClassName_shouldThrowAPIExceptionForNullJavaClassName() {
2809+
assertThrows(APIException.class, () -> orderService.getOrderTypesByClassName(null, false));
2810+
}
2811+
27652812
/**
27662813
* @see OrderService#saveOrder(org.openmrs.Order, OrderContext)
27672814
*/
@@ -4421,4 +4468,7 @@ private Date aMomentBefore(Date date) {
44214468
private Date truncateToSeconds(Date date) {
44224469
return DateUtils.truncate(date, Calendar.SECOND);
44234470
}
4471+
4472+
// Test-only subclass
4473+
public static class MyTestOrder extends TestOrder { }
44244474
}

0 commit comments

Comments
 (0)