• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmrs / openmrs-core / 21752204880

05 Feb 2026 06:57PM UTC coverage: 63.778%. Remained the same
21752204880

push

github

ibacher
Fix some serious errors in the ThreadSafeCircularFifoQueue (#5746)

6 of 6 new or added lines in 1 file covered. (100.0%)

31 existing lines in 6 files now uncovered.

21872 of 34294 relevant lines covered (63.78%)

0.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.89
/api/src/main/java/org/openmrs/api/impl/OrderServiceImpl.java
1
/**
2
 * This Source Code Form is subject to the terms of the Mozilla Public License,
3
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4
 * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
5
 * the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
6
 *
7
 * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
8
 * graphic logo is a trademark of OpenMRS Inc.
9
 */
10
package org.openmrs.api.impl;
11

12
import org.apache.commons.lang3.time.DateUtils;
13
import org.hibernate.proxy.HibernateProxy;
14
import org.openmrs.CareSetting;
15
import org.openmrs.Concept;
16
import org.openmrs.ConceptClass;
17
import org.openmrs.Encounter;
18
import org.openmrs.DrugOrder;
19
import org.openmrs.Order;
20
import org.openmrs.OrderAttribute;
21
import org.openmrs.OrderAttributeType;
22
import org.openmrs.OrderFrequency;
23
import org.openmrs.OrderGroup;
24
import org.openmrs.OrderType;
25
import org.openmrs.GlobalProperty;
26
import org.openmrs.Patient;
27
import org.openmrs.Provider;
28
import org.openmrs.ReferralOrder;
29
import org.openmrs.Order.FulfillerStatus;
30
import org.openmrs.OrderGroupAttribute;
31
import org.openmrs.OrderGroupAttributeType;
32
import org.openmrs.TestOrder;
33
import org.openmrs.api.APIException;
34
import org.openmrs.api.AmbiguousOrderException;
35
import org.openmrs.api.CannotDeleteObjectInUseException;
36
import org.openmrs.api.CannotStopDiscontinuationOrderException;
37
import org.openmrs.api.CannotStopInactiveOrderException;
38
import org.openmrs.api.CannotUnvoidOrderException;
39
import org.openmrs.api.CannotUpdateObjectInUseException;
40
import org.openmrs.api.EditedOrderDoesNotMatchPreviousException;
41
import org.openmrs.api.GlobalPropertyListener;
42
import org.openmrs.api.MissingRequiredPropertyException;
43
import org.openmrs.api.OrderContext;
44
import org.openmrs.api.OrderEntryException;
45
import org.openmrs.api.OrderNumberGenerator;
46
import org.openmrs.api.OrderService;
47
import org.openmrs.api.UnchangeableObjectException;
48
import org.openmrs.api.context.Context;
49
import org.openmrs.api.db.OrderDAO;
50
import org.openmrs.customdatatype.CustomDatatypeUtil;
51
import org.openmrs.order.OrderUtil;
52
import org.openmrs.parameter.OrderSearchCriteria;
53
import org.openmrs.util.OpenmrsConstants;
54
import org.openmrs.util.OpenmrsUtil;
55
import org.slf4j.Logger;
56
import org.slf4j.LoggerFactory;
57
import org.springframework.transaction.annotation.Propagation;
58
import org.springframework.transaction.annotation.Transactional;
59
import org.springframework.util.StringUtils;
60

61
import java.lang.reflect.Field;
62
import java.util.ArrayList;
63
import java.util.Arrays;
64
import java.util.Calendar;
65
import java.util.Collections;
66
import java.util.Date;
67
import java.util.List;
68
import java.util.Locale;
69
import java.util.Set;
70

71
import static org.openmrs.Order.Action.DISCONTINUE;
72
import static org.openmrs.Order.Action.REVISE;
73

74
/**
75
 * Default implementation of the Order-related services class. This method should not be invoked by
76
 * itself. Spring injection is used to inject this implementation into the ServiceContext. Which
77
 * implementation is injected is determined by the spring application context file:
78
 * /metadata/api/spring/applicationContext.xml
79
 * 
80
 * @see org.openmrs.api.OrderService
81
 */
82
@Transactional
83
public class OrderServiceImpl extends BaseOpenmrsService implements OrderService, OrderNumberGenerator, GlobalPropertyListener {
84
        
85
        private static final Logger log = LoggerFactory.getLogger(OrderServiceImpl.class);
1✔
86
        
87
        private static final String ORDER_NUMBER_PREFIX = "ORD-";
88
        
89
        protected OrderDAO dao;
90
        
91
        private static OrderNumberGenerator orderNumberGenerator = null;
1✔
92

93
        public OrderServiceImpl() {
1✔
94
        }
1✔
95
        
96
        /**
97
         * @see org.openmrs.api.OrderService#setOrderDAO(org.openmrs.api.db.OrderDAO)
98
         */
99
        @Override
100
        public void setOrderDAO(OrderDAO dao) {
101
                this.dao = dao;
1✔
102
        }
1✔
103
        
104
        /**
105
         * @see org.openmrs.api.OrderService#saveOrder(org.openmrs.Order, org.openmrs.api.OrderContext)
106
         */
107
        @Override
108
        public synchronized Order saveOrder(Order order, OrderContext orderContext) throws APIException {
109
                return saveOrder(order, orderContext, false);
1✔
110
        }
111
        
112
        /**
113
         * @see org.openmrs.api.OrderService#saveOrderGroup(org.openmrs.OrderGroup)
114
         */
115
        @Override
116
        public OrderGroup saveOrderGroup(OrderGroup orderGroup) throws APIException {
117
                if (orderGroup.getId() == null) {
1✔
118
                        // an OrderGroup requires an encounter, which has a patient, so it
119
                        // is odd that OrderGroup has a patient field. There is no obvious
120
                        // reason why they should ever be different.
121
                        orderGroup.setPatient(orderGroup.getEncounter().getPatient());
1✔
122
                        CustomDatatypeUtil.saveAttributesIfNecessary(orderGroup);
1✔
123
                        dao.saveOrderGroup(orderGroup);
1✔
124
                }
125
                List<Order> orders = orderGroup.getOrders();
1✔
126
                for (Order order : orders) {
1✔
127
                        if (order.getId() == null) {
1✔
128
                                order.setEncounter(orderGroup.getEncounter());
1✔
129
                                Context.getOrderService().saveOrder(order, null);
1✔
130
                        }
131
                }
1✔
132
                Set<OrderGroup> nestedGroups = orderGroup.getNestedOrderGroups();
1✔
133
                if (nestedGroups != null) {
1✔
134
                        for (OrderGroup nestedGroup : nestedGroups) {
1✔
UNCOV
135
                                Context.getOrderService().saveOrderGroup(nestedGroup);
×
136
                        }
×
137
                }
138
                return orderGroup;
1✔
139
        }
140
        
141
        /**
142
         * @see org.openmrs.api.OrderService#saveOrder(org.openmrs.Order, org.openmrs.api.OrderContext)
143
         */
144
        @Override
145
        public synchronized Order saveRetrospectiveOrder(Order order, OrderContext orderContext) {
146
                return saveOrder(order, orderContext, true);
1✔
147
        }
148

149
        private Order saveOrder(Order order, OrderContext orderContext, boolean isRetrospective) {
150

151
                failOnExistingOrder(order);
1✔
152
                ensureDateActivatedIsSet(order);
1✔
153
                ensureConceptIsSet(order);
1✔
154
                ensureDrugOrderAutoExpirationDateIsSet(order);
1✔
155
                ensureOrderTypeIsSet(order,orderContext);
1✔
156
                ensureCareSettingIsSet(order,orderContext);
1✔
157
                failOnOrderTypeMismatch(order);
1✔
158
                
159
                // If isRetrospective is false, but the dateActivated is prior to the current date, set isRetrospective to true
160
                if (!isRetrospective) {
1✔
161
                        Date dateActivated = order.getDateActivated();
1✔
162
                        Date currentDate = new Date();
1✔
163
                        isRetrospective = !dateActivated.after(currentDate) && !DateUtils.isSameDay(dateActivated, currentDate);
1✔
164
                }
165
                
166
                Order previousOrder = order.getPreviousOrder();
1✔
167
                if (REVISE == order.getAction()) {
1✔
168
                        if (previousOrder == null) {
1✔
169
                                throw new MissingRequiredPropertyException("Order.previous.required", (Object[]) null);
1✔
170
                        }
171
                        stopOrder(previousOrder, aMomentBefore(order.getDateActivated()), isRetrospective);
1✔
172
                } else if (DISCONTINUE == order.getAction()) {
1✔
173
                        discontinueExistingOrdersIfNecessary(order, isRetrospective);
1✔
174
                }
175
                
176
                if (previousOrder != null) {
1✔
177
                        //concept should be the same as on previous order, same applies to drug for drug orders
178
                        if (!order.hasSameOrderableAs(previousOrder)) {
1✔
179
                                throw new EditedOrderDoesNotMatchPreviousException("Order.orderable.doesnot.match");
1✔
180
                        } else if (!order.getOrderType().equals(previousOrder.getOrderType())) {
1✔
181
                                throw new EditedOrderDoesNotMatchPreviousException("Order.type.doesnot.match");
1✔
182
                        } else if (!order.getCareSetting().equals(previousOrder.getCareSetting())) {
1✔
183
                                throw new EditedOrderDoesNotMatchPreviousException("Order.care.setting.doesnot.match");
1✔
184
                        } else if (!getActualType(order).equals(getActualType(previousOrder))) {
1✔
185
                                throw new EditedOrderDoesNotMatchPreviousException("Order.class.doesnot.match");
1✔
186
                        }
187
                }
188
                
189
                if (DISCONTINUE != order.getAction()) {
1✔
190
                        Date asOfDate = new Date();
1✔
191
                        if (isRetrospective) {
1✔
192
                                asOfDate = order.getDateActivated();
1✔
193
                        }
194
                        List<Order> activeOrders = getActiveOrders(order.getPatient(), null, order.getCareSetting(), asOfDate);
1✔
195
                        List<String> parallelOrders = Collections.emptyList();
1✔
196
                        if (orderContext != null && orderContext.getAttribute(PARALLEL_ORDERS) != null) {
1✔
197
                                parallelOrders = Arrays.asList((String[]) orderContext.getAttribute(PARALLEL_ORDERS));
1✔
198
                        }
199
                        for (Order activeOrder : activeOrders) {
1✔
200
                                //Reject if there is an active drug order for the same orderable with overlapping schedule
201
                                if (!parallelOrders.contains(activeOrder.getUuid())
1✔
202
                                        && areDrugOrdersOfSameOrderableAndOverlappingSchedule(order, activeOrder)) {
1✔
203
                                        throw new AmbiguousOrderException("Order.cannot.have.more.than.one");
1✔
204
                                }
205
                        }
1✔
206
                }
207
                return saveOrderInternal(order, orderContext);
1✔
208
        }
209

210
        private void failOnExistingOrder(Order order) {
211
                if (order.getOrderId() != null) {
1✔
212
                        throw new UnchangeableObjectException("Order.cannot.edit.existing");
1✔
213
                }
214
        }
1✔
215

216
        private void ensureDateActivatedIsSet(Order order) {
217
                if (order.getDateActivated() == null) {
1✔
218
                        order.setDateActivated(new Date());
1✔
219
                }
220
        }
1✔
221

222
        private void ensureConceptIsSet(Order order) {
223
                Concept concept = order.getConcept();
1✔
224
                if (concept == null && isDrugOrder(order)) {
1✔
UNCOV
225
                        DrugOrder drugOrder = (DrugOrder) order;
×
226
                        if (drugOrder.getDrug() != null) {
×
227
                                concept = drugOrder.getDrug().getConcept();
×
228
                                drugOrder.setConcept(concept);
×
229
                        }
230
                }
231
                if (concept == null) {
1✔
UNCOV
232
                        throw new MissingRequiredPropertyException("Order.concept.required");
×
233
                }
234
        }
1✔
235

236
        private void ensureDrugOrderAutoExpirationDateIsSet(Order order) {
237
                if (isDrugOrder(order)) {
1✔
238
                        ((DrugOrder) order).setAutoExpireDateBasedOnDuration();
1✔
239
                }
240
        }
1✔
241

242
        private void ensureOrderTypeIsSet(Order order, OrderContext orderContext) {
243
                if (order.getOrderType() != null) {
1✔
244
                        return;
1✔
245
                }
246
                OrderType orderType = null;
1✔
247
                if (orderContext != null) {
1✔
248
                        orderType = orderContext.getOrderType();
1✔
249
                }
250
                if (orderType == null) {
1✔
251
                        orderType = getOrderTypeByConcept(order.getConcept());
1✔
252
                }
253
                if (orderType == null && order instanceof DrugOrder) {
1✔
254
                        orderType = Context.getOrderService().getOrderTypeByUuid(OrderType.DRUG_ORDER_TYPE_UUID);
1✔
255
                }
256
                if (orderType == null && order instanceof TestOrder) {
1✔
257
                        orderType = Context.getOrderService().getOrderTypeByUuid(OrderType.TEST_ORDER_TYPE_UUID);
1✔
258
                }
259
                if (orderType == null && order instanceof ReferralOrder) {
1✔
UNCOV
260
                        orderType = Context.getOrderService().getOrderTypeByUuid(OrderType.REFERRAL_ORDER_TYPE_UUID);
×
261
                }
262
                if (orderType == null) {
1✔
263
                        throw new OrderEntryException("Order.type.cannot.determine");
1✔
264
                }
265
                Order previousOrder = order.getPreviousOrder();
1✔
266
                if (previousOrder != null && !orderType.equals(previousOrder.getOrderType())) {
1✔
UNCOV
267
                        throw new OrderEntryException("Order.type.does.not.match");
×
268
                }
269
                order.setOrderType(orderType);
1✔
270
        }
1✔
271

272
        private void ensureCareSettingIsSet(Order order, OrderContext orderContext) {
273
                if (order.getCareSetting() != null) {
1✔
274
                        return;
1✔
275
                }
276
                CareSetting careSetting = null;
1✔
277
                if (orderContext != null) {
1✔
278
                        careSetting = orderContext.getCareSetting();
1✔
279
                }
280
                Order previousOrder = order.getPreviousOrder();
1✔
281
                if (careSetting == null || (previousOrder != null && !careSetting.equals(previousOrder.getCareSetting()))) {
1✔
UNCOV
282
                        throw new OrderEntryException("Order.care.cannot.determine");
×
283
                }
284
                order.setCareSetting(careSetting);
1✔
285
        }
1✔
286

287
        private void failOnOrderTypeMismatch(Order order) {
288
                if (!order.getOrderType().getJavaClass().isAssignableFrom(order.getClass())) {
1✔
UNCOV
289
                        throw new OrderEntryException("Order.type.class.does.not.match", new Object[] {
×
290
                                        order.getOrderType().getJavaClass(), order.getClass().getName() });
×
291
                }
292
        }
1✔
293

294
        private boolean areDrugOrdersOfSameOrderableAndOverlappingSchedule(Order firstOrder, Order secondOrder) {
295
                return firstOrder.hasSameOrderableAs(secondOrder)
1✔
296
                        && !OpenmrsUtil.nullSafeEquals(firstOrder.getPreviousOrder(), secondOrder)
1✔
297
                        && OrderUtil.checkScheduleOverlap(firstOrder, secondOrder)
1✔
298
                        && firstOrder.getOrderType().equals(
1✔
299
                            Context.getOrderService().getOrderTypeByUuid(OrderType.DRUG_ORDER_TYPE_UUID));
1✔
300
        }
301

302
        private boolean isDrugOrder(Order order) {
303
                return DrugOrder.class.isAssignableFrom(getActualType(order));
1✔
304
        }
305

306
        
307
        /**
308
         * To support MySQL datetime values (which are only precise to the second) we subtract one
309
         * second. Eventually we may move this method and enhance it to subtract the smallest moment the
310
         * underlying database will represent.
311
         * 
312
         * @param date
313
         * @return one moment before date
314
         */
315
        private Date aMomentBefore(Date date) {
316
                return DateUtils.addSeconds(date, -1);
1✔
317
        }
318
        
319
        private Order saveOrderInternal(Order order, OrderContext orderContext) {
320
                if (order.getOrderId() == null) {
1✔
321
                        setProperty(order, "orderNumber", getOrderNumberGenerator().getNewOrderNumber(orderContext));
1✔
322
                        
323
                        //DC orders should auto expire upon creating them
324
                        if (DISCONTINUE == order.getAction()) {
1✔
325
                                order.setAutoExpireDate(order.getDateActivated());
1✔
326
                        } else if (order.getAutoExpireDate() != null) {
1✔
327
                                Calendar cal = Calendar.getInstance();
1✔
328
                                cal.setTime(order.getAutoExpireDate());
1✔
329
                                int hours = cal.get(Calendar.HOUR_OF_DAY);
1✔
330
                                int minutes = cal.get(Calendar.MINUTE);
1✔
331
                                int seconds = cal.get(Calendar.SECOND);
1✔
332
                                cal.get(Calendar.MILLISECOND);
1✔
333
                                //roll autoExpireDate to end of day (23:59:59) if no time portion is specified
334
                                if (hours == 0 && minutes == 0 && seconds == 0) {
1✔
335
                                        cal.set(Calendar.HOUR_OF_DAY, 23);
1✔
336
                                        cal.set(Calendar.MINUTE, 59);
1✔
337
                                        cal.set(Calendar.SECOND, 59);
1✔
338
                                        // the OpenMRS database is only precise to the second
339
                                        cal.set(Calendar.MILLISECOND, 0);
1✔
340
                                        order.setAutoExpireDate(cal.getTime());
1✔
341
                                }
342
                        }
343
                }
344
                
345
                return dao.saveOrder(order);
1✔
346
        }
347
        
348
        private void setProperty(Order order, String propertyName, Object value) {
349
                Boolean isAccessible = null;
1✔
350
                Field field = null;
1✔
351
                try {
352
                        field = Order.class.getDeclaredField(propertyName);
1✔
353
                        field.setAccessible(true);
1✔
354
                        field.set(order, value);
1✔
355
                }
UNCOV
356
                catch (Exception e) {
×
357
                        throw new APIException("Order.failed.set.property", new Object[] { propertyName, order }, e);
×
358
                }
359
                finally {
360
                        if (field != null && isAccessible != null) {
1✔
UNCOV
361
                                field.setAccessible(isAccessible);
×
362
                        }
363
                }
364
        }
1✔
365
        
366
        /**
367
         * Gets the configured order number generator, if none is specified, it defaults to an instance
368
         * if this class
369
         * 
370
         * @return
371
         */
372
        private OrderNumberGenerator getOrderNumberGenerator() {
373
                if (orderNumberGenerator == null) {
1✔
374
                        String generatorBeanId = Context.getAdministrationService().getGlobalProperty(
1✔
375
                            OpenmrsConstants.GP_ORDER_NUMBER_GENERATOR_BEAN_ID);
376
                        if (StringUtils.hasText(generatorBeanId)) {
1✔
377
                                orderNumberGenerator = Context.getRegisteredComponent(generatorBeanId, OrderNumberGenerator.class);
1✔
378
                                log.info("Successfully set the configured order number generator");
1✔
379
                        } else {
380
                                orderNumberGenerator = this;
1✔
381
                                log.info("Setting default order number generator");
1✔
382
                        }
383
                }
384
                
385
                return orderNumberGenerator;
1✔
386
        }
387
        
388
        /**
389
         * If this is a discontinue order, ensure that the previous order is discontinued. If a
390
         * previousOrder is present, then ensure this is discontinued. If no previousOrder is present,
391
         * then try to find a previousOrder and discontinue it. If cannot find a previousOrder, throw
392
         * exception
393
         * 
394
         * @param order
395
         * @param isRetrospective
396
         */
397
        //Ignore and return if this is not an order to discontinue
398
        private void discontinueExistingOrdersIfNecessary(Order order, Boolean isRetrospective) {
399
                if (DISCONTINUE != order.getAction()) {
1✔
UNCOV
400
                        return;
×
401
                }
402
                
403
                //Mark previousOrder as discontinued if it is not already
404
                Order previousOrder = order.getPreviousOrder();
1✔
405
                if (previousOrder != null) {
1✔
406
                        stopOrder(previousOrder, aMomentBefore(order.getDateActivated()), isRetrospective);
1✔
407
                        return;
1✔
408
                }
409
                
410
                //Mark first order found corresponding to this DC order as discontinued.
411
                Date asOfDate = null;
1✔
412
                if (isRetrospective) {
1✔
413
                        asOfDate = order.getDateActivated();
1✔
414
                }
415
                List<? extends Order> orders = getActiveOrders(order.getPatient(), order.getOrderType(), order.getCareSetting(),
1✔
416
                    asOfDate);
417
                boolean isDrugOrderAndHasADrug = isDrugOrder(order)
1✔
418
                        && (((DrugOrder) order).getDrug() != null || ((DrugOrder) order).isNonCodedDrug());
1✔
419
                Order orderToBeDiscontinued = null;
1✔
420
                for (Order activeOrder : orders) {
1✔
421
                        if (!getActualType(order).equals(getActualType(activeOrder))) {
1✔
UNCOV
422
                                continue;
×
423
                        }
424
                        //For drug orders, the drug must match if the order has a drug
425
                        if (isDrugOrderAndHasADrug) {
1✔
426
                                Order existing = order.hasSameOrderableAs(activeOrder) ? activeOrder : null;
1✔
427
                                if (existing != null) {
1✔
428
                                        if (orderToBeDiscontinued == null) {
1✔
429
                                                orderToBeDiscontinued = existing;
1✔
430
                                        } else {
431
                                                throw new AmbiguousOrderException("Order.discontinuing.ambiguous.orders");
1✔
432
                                        }
433
                                }
434
                        } else if (activeOrder.getConcept().equals(order.getConcept())) {
1✔
435
                                if (orderToBeDiscontinued == null) {
1✔
436
                                        orderToBeDiscontinued = activeOrder;
1✔
437
                                } else {
438
                                        throw new AmbiguousOrderException("Order.discontinuing.ambiguous.orders");
1✔
439
                                }
440
                        }
441
                }
1✔
442
                if (orderToBeDiscontinued != null) {
1✔
443
                        order.setPreviousOrder(orderToBeDiscontinued);
1✔
444
                        stopOrder(orderToBeDiscontinued, aMomentBefore(order.getDateActivated()), isRetrospective);
1✔
445
                }
446
        }
1✔
447
        
448
        /**
449
         * Returns the class object of the specified persistent object returning the actual persistent
450
         * class in case it is a hibernate proxy
451
         *
452
         * @param persistentObject
453
         * @return the Class object
454
         */
455
        private Class<?> getActualType(Object persistentObject) {
456
                Class<?> type = persistentObject.getClass();
1✔
457
                if (persistentObject instanceof HibernateProxy) {
1✔
UNCOV
458
                        type = ((HibernateProxy) persistentObject).getHibernateLazyInitializer().getPersistentClass();
×
459
                }
460
                return type;
1✔
461
        }
462
        
463
        /**
464
         * @see org.openmrs.api.OrderService#purgeOrder(org.openmrs.Order)
465
         */
466
        @Override
467
        public void purgeOrder(Order order) throws APIException {
468
                purgeOrder(order, false);
1✔
469
        }
1✔
470
        
471
        /**
472
         * @see org.openmrs.api.OrderService#purgeOrder(Order)
473
         */
474
        @Override
475
        public void purgeOrder(Order order, boolean cascade) throws APIException {
476
                if (cascade) {
1✔
477
                        dao.deleteObsThatReference(order);
1✔
478
                }
479
                
480
                dao.deleteOrder(order);
1✔
481
        }
1✔
482
        
483
        /**
484
         * @see org.openmrs.api.OrderService#voidOrder(org.openmrs.Order, java.lang.String)
485
         */
486
        @Override
487
        public Order voidOrder(Order order, String voidReason) throws APIException {
488
                if (!StringUtils.hasLength(voidReason)) {
1✔
UNCOV
489
                        throw new IllegalArgumentException("voidReason cannot be empty or null");
×
490
                }
491
                
492
                Order previousOrder = order.getPreviousOrder();
1✔
493
                if (previousOrder != null && isDiscontinueOrReviseOrder(order)) {
1✔
494
                        setProperty(previousOrder, "dateStopped", null);
1✔
495
                }
496
                
497
                return saveOrderInternal(order, null);
1✔
498
        }
499
        
500
        /**
501
         * @see org.openmrs.api.OrderService#unvoidOrder(org.openmrs.Order)
502
         */
503
        @Override
504
        public Order unvoidOrder(Order order) throws APIException {
505
                Order previousOrder = order.getPreviousOrder();
1✔
506
                if (previousOrder != null && isDiscontinueOrReviseOrder(order)) {
1✔
507
                        if (!previousOrder.isActive()) {
1✔
508
                                final String action = DISCONTINUE == order.getAction() ? "discontinuation" : "revision";
1✔
509
                                throw new CannotUnvoidOrderException(action);
1✔
510
                        }
511
                        stopOrder(previousOrder, aMomentBefore(order.getDateActivated()), false);
1✔
512
                }
513
                
514
                return saveOrderInternal(order, null);
1✔
515
        }
516
        
517
        @Override
518
        public Order updateOrderFulfillerStatus(Order order, Order.FulfillerStatus orderFulfillerStatus, String fullFillerComment) {
519
                return updateOrderFulfillerStatus(order, orderFulfillerStatus, fullFillerComment, null);
1✔
520
        }
521

522
        @Override
523
        public Order updateOrderFulfillerStatus(Order order, FulfillerStatus orderFulfillerStatus, String fullFillerComment,
524
                                                                                        String accessionNumber) {
525

526
                if (orderFulfillerStatus != null) {
1✔
527
                        order.setFulfillerStatus(orderFulfillerStatus);
1✔
528
                }
529

530
                if (fullFillerComment != null) {
1✔
531
                        order.setFulfillerComment(fullFillerComment);
1✔
532
                }
533
        
534
                if (accessionNumber != null) {
1✔
535
                        order.setAccessionNumber(accessionNumber);
1✔
536
                }
537
                
538
                return saveOrderInternal(order, null);
1✔
539
        }
540
        
541
        /**
542
         * @see org.openmrs.api.OrderService#getOrder(java.lang.Integer)
543
         */
544
        @Override
545
        @Transactional(readOnly = true)
546
        public Order getOrder(Integer orderId) throws APIException {
547
                return dao.getOrder(orderId);
1✔
548
        }
549
        
550
        /**
551
         * @see OrderService#getOrders(org.openmrs.Patient, org.openmrs.CareSetting,
552
         *      org.openmrs.OrderType, boolean)
553
         */
554
        @Override
555
        public List<Order> getOrders(Patient patient, CareSetting careSetting, OrderType orderType, boolean includeVoided) {
556
                if (patient == null) {
1✔
557
                        throw new IllegalArgumentException("Patient is required");
1✔
558
                }
559
                if (careSetting == null) {
1✔
560
                        throw new IllegalArgumentException("CareSetting is required");
1✔
561
                }
562
                List<OrderType> orderTypes = null;
1✔
563
                if (orderType != null) {
1✔
564
                        orderTypes = new ArrayList<>();
1✔
565
                        orderTypes.add(orderType);
1✔
566
                        orderTypes.addAll(getSubtypes(orderType, true));
1✔
567
                }
568
                return dao.getOrders(patient, careSetting, orderTypes, includeVoided, false);
1✔
569
        }
570
        
571
        /**
572
         * @see OrderService#getAllOrdersByPatient(org.openmrs.Patient)
573
         */
574
        @Override
575
        public List<Order> getAllOrdersByPatient(Patient patient) {
576
                if (patient == null) {
1✔
577
                        throw new IllegalArgumentException("Patient is required");
1✔
578
                }
579
                return dao.getOrders(patient, null, null, true, true);
1✔
580
        }
581
        
582
        @Override
583
        public List<Order> getOrders(OrderSearchCriteria orderSearchCriteria) {
584
                return dao.getOrders(orderSearchCriteria);
1✔
585
        }
586
        
587
        /**
588
         * @see org.openmrs.api.OrderService#getOrderByUuid(java.lang.String)
589
         */
590
        @Override
591
        @Transactional(readOnly = true)
592
        public Order getOrderByUuid(String uuid) throws APIException {
593
                return dao.getOrderByUuid(uuid);
1✔
594
        }
595
        
596
        /**
597
         * @see org.openmrs.api.OrderService#getDiscontinuationOrder(Order)
598
         */
599
        @Transactional(readOnly = true)
600
        @Override
601
        public Order getDiscontinuationOrder(Order order) throws APIException {
602
                return dao.getDiscontinuationOrder(order);
1✔
603
        }
604
        
605
        /**
606
         * @see org.openmrs.api.OrderService#getRevisionOrder(Order)
607
         */
608
        @Override
609
        public Order getRevisionOrder(Order order) throws APIException {
610
                return dao.getRevisionOrder(order);
1✔
611
        }
612
        
613
        /**
614
         * @see org.openmrs.api.OrderNumberGenerator#getNewOrderNumber(org.openmrs.api.OrderContext)
615
         * @param orderContext
616
         */
617
        @Override
618
        public String getNewOrderNumber(OrderContext orderContext) throws APIException {
619
                return ORDER_NUMBER_PREFIX + Context.getOrderService().getNextOrderNumberSeedSequenceValue();
1✔
620
        }
621
        
622
        /**
623
         * @see org.openmrs.api.OrderService#getOrderByOrderNumber(java.lang.String)
624
         */
625
        @Override
626
        @Transactional(readOnly = true)
627
        public Order getOrderByOrderNumber(String orderNumber) {
628
                return dao.getOrderByOrderNumber(orderNumber);
1✔
629
        }
630
        
631
        /**
632
         * @see org.openmrs.api.OrderService#getOrderHistoryByConcept(org.openmrs.Patient,
633
         *      org.openmrs.Concept)
634
         */
635
        @Override
636
        @Transactional(readOnly = true)
637
        public List<Order> getOrderHistoryByConcept(Patient patient, Concept concept) {
638
                if (patient == null || concept == null) {
1✔
639
                        throw new IllegalArgumentException("patient and concept are required");
1✔
640
                }
641
                List<Concept> concepts = new ArrayList<>();
1✔
642
                concepts.add(concept);
1✔
643
                
644
                List<Patient> patients = new ArrayList<>();
1✔
645
                patients.add(patient);
1✔
646
                
647
                return dao.getOrders(null, patients, concepts, new ArrayList<>(), new ArrayList<>());
1✔
648
        }
649
        
650
        /**
651
         * @see org.openmrs.api.OrderService#getNextOrderNumberSeedSequenceValue()
652
         */
653
        @Override
654
        @Transactional(propagation = Propagation.REQUIRES_NEW)
655
        public synchronized Long getNextOrderNumberSeedSequenceValue() {
656
                return dao.getNextOrderNumberSeedSequenceValue();
1✔
657
        }
658
        
659
        /**
660
         * @see org.openmrs.api.OrderService#getOrderHistoryByOrderNumber(java.lang.String)
661
         */
662
        @Override
663
        @Transactional(readOnly = true)
664
        public List<Order> getOrderHistoryByOrderNumber(String orderNumber) {
665
                List<Order> orders = new ArrayList<>();
1✔
666
                Order order = dao.getOrderByOrderNumber(orderNumber);
1✔
667
                while (order != null) {
1✔
668
                        orders.add(order);
1✔
669
                        order = order.getPreviousOrder();
1✔
670
                }
671
                return orders;
1✔
672
        }
673
        
674
        /**
675
         * @see org.openmrs.api.OrderService#getActiveOrders(org.openmrs.Patient, org.openmrs.OrderType,
676
         *      org.openmrs.CareSetting, java.util.Date)
677
         */
678
        @Override
679
        @Transactional(readOnly = true)
680
        public List<Order> getActiveOrders(Patient patient, OrderType orderType, CareSetting careSetting, Date asOfDate) {
681
                if (patient == null) {
1✔
682
                        throw new IllegalArgumentException("Patient is required when fetching active orders");
1✔
683
                }
684
                if (asOfDate == null) {
1✔
685
                        asOfDate = new Date();
1✔
686
                }
687
                List<OrderType> orderTypes = null;
1✔
688
                if (orderType != null) {
1✔
689
                        orderTypes = new ArrayList<>();
1✔
690
                        orderTypes.add(orderType);
1✔
691
                        orderTypes.addAll(getSubtypes(orderType, true));
1✔
692
                }
693
                return dao.getActiveOrders(patient, orderTypes, careSetting, asOfDate);
1✔
694
        }
695
        
696
        /**
697
         * @see org.openmrs.api.OrderService#getCareSetting(Integer)
698
         */
699
        @Override
700
        public CareSetting getCareSetting(Integer careSettingId) {
701
                return dao.getCareSetting(careSettingId);
1✔
702
        }
703
        
704
        /**
705
         * @see org.openmrs.api.OrderService#getCareSettingByUuid(String)
706
         */
707
        @Override
708
        public CareSetting getCareSettingByUuid(String uuid) {
709
                return dao.getCareSettingByUuid(uuid);
1✔
710
        }
711
        
712
        /**
713
         * @see org.openmrs.api.OrderService#getCareSettingByName(String)
714
         */
715
        @Override
716
        public CareSetting getCareSettingByName(String name) {
717
                return dao.getCareSettingByName(name);
1✔
718
        }
719
        
720
        /**
721
         * @see org.openmrs.api.OrderService#getCareSettings(boolean)
722
         */
723
        @Override
724
        public List<CareSetting> getCareSettings(boolean includeRetired) {
725
                return dao.getCareSettings(includeRetired);
1✔
726
        }
727
        
728
        /**
729
         * @see OrderService#getOrderTypeByName(String)
730
         */
731
        @Override
732
        public OrderType getOrderTypeByName(String orderTypeName) {
733
                return dao.getOrderTypeByName(orderTypeName);
1✔
734
        }
735
        
736
        /**
737
         * @see OrderService#getOrderFrequency(Integer)
738
         */
739
        @Override
740
        public OrderFrequency getOrderFrequency(Integer orderFrequencyId) {
741
                return dao.getOrderFrequency(orderFrequencyId);
1✔
742
        }
743
        
744
        /**
745
         * @see OrderService#getOrderFrequencyByUuid(String)
746
         */
747
        @Override
748
        public OrderFrequency getOrderFrequencyByUuid(String uuid) {
749
                return dao.getOrderFrequencyByUuid(uuid);
1✔
750
        }
751
        
752
        /**
753
         * @see OrderService#getOrderFrequencies(boolean)
754
         */
755
        @Override
756
        public List<OrderFrequency> getOrderFrequencies(boolean includeRetired) {
757
                return dao.getOrderFrequencies(includeRetired);
1✔
758
        }
759
        
760
        /**
761
         * @see OrderService#getOrderFrequencies(String, java.util.Locale, boolean, boolean)
762
         */
763
        @Override
764
        public List<OrderFrequency> getOrderFrequencies(String searchPhrase, Locale locale, boolean exactLocale,
765
                                                        boolean includeRetired) {
766
                if (searchPhrase == null) {
1✔
767
                        throw new IllegalArgumentException("searchPhrase is required");
1✔
768
                }
769
                return dao.getOrderFrequencies(searchPhrase, locale, exactLocale, includeRetired);
1✔
770
        }
771
        
772
        /**
773
         * @see org.openmrs.api.OrderService#discontinueOrder(org.openmrs.Order, org.openmrs.Concept,
774
         *      java.util.Date, org.openmrs.Provider, org.openmrs.Encounter)
775
         */
776
        @Override
777
        public Order discontinueOrder(Order orderToDiscontinue, Concept reasonCoded, Date discontinueDate, Provider orderer,
778
                                      Encounter encounter) {
779
                if (discontinueDate == null) {
1✔
780
                        discontinueDate = aMomentBefore(new Date());
1✔
781
                }
782
                stopOrder(orderToDiscontinue, discontinueDate, false);
1✔
783
                Order newOrder = orderToDiscontinue.cloneForDiscontinuing();
1✔
784
                newOrder.setOrderReason(reasonCoded);
1✔
785
                newOrder.setOrderer(orderer);
1✔
786
                newOrder.setEncounter(encounter);
1✔
787
                newOrder.setDateActivated(discontinueDate);
1✔
788
                return saveOrderInternal(newOrder, null);
1✔
789
        }
790
        
791
        /**
792
         * @see org.openmrs.api.OrderService#discontinueOrder(org.openmrs.Order, String, java.util.Date,
793
         *      org.openmrs.Provider, org.openmrs.Encounter)
794
         */
795
        @Override
796
        public Order discontinueOrder(Order orderToDiscontinue, String reasonNonCoded, Date discontinueDate, Provider orderer,
797
                                      Encounter encounter) {
798
                if (discontinueDate == null) {
1✔
799
                        discontinueDate = aMomentBefore(new Date());
1✔
800
                }
801
                stopOrder(orderToDiscontinue, discontinueDate, false);
1✔
802
                Order newOrder = orderToDiscontinue.cloneForDiscontinuing();
1✔
803
                newOrder.setOrderReasonNonCoded(reasonNonCoded);
1✔
804
                newOrder.setOrderer(orderer);
1✔
805
                newOrder.setEncounter(encounter);
1✔
806
                newOrder.setDateActivated(discontinueDate);
1✔
807
                return saveOrderInternal(newOrder, null);
1✔
808
        }
809
        
810
        private boolean isDiscontinueOrReviseOrder(Order order) {
811
                return DISCONTINUE == order.getAction() || REVISE == order.getAction();
1✔
812
        }
813
        
814
        /**
815
         * Make necessary checks, set necessary fields for discontinuing <code>orderToDiscontinue</code>
816
         * and save.
817
         *
818
         * @param orderToStop
819
         * @param discontinueDate
820
         */
821
        private void stopOrder(Order orderToStop, Date discontinueDate, boolean isRetrospective) {
822
                if (discontinueDate == null) {
1✔
UNCOV
823
                        discontinueDate = new Date();
×
824
                }
825
                if (discontinueDate.after(new Date())) {
1✔
826
                        throw new IllegalArgumentException("Discontinue date cannot be in the future");
1✔
827
                }
828
                if (DISCONTINUE == orderToStop.getAction()) {
1✔
829
                        throw new CannotStopDiscontinuationOrderException();
1✔
830
                }
831
                
832
                if (isRetrospective && orderToStop.getDateStopped() != null) {
1✔
833
                        throw new CannotStopInactiveOrderException();
1✔
834
                }
835
                if (!isRetrospective && !orderToStop.isActive()) {
1✔
836
                        throw new CannotStopInactiveOrderException();
1✔
837
                } else if (isRetrospective && !orderToStop.isActive(discontinueDate)) {
1✔
UNCOV
838
                        throw new CannotStopInactiveOrderException();
×
839
                }
840
                
841
                setProperty(orderToStop, "dateStopped", discontinueDate);
1✔
842
                saveOrderInternal(orderToStop, null);
1✔
843
        }
1✔
844
        
845
        /**
846
         * @see org.openmrs.api.OrderService#saveOrderFrequency(org.openmrs.OrderFrequency)
847
         */
848
        @Override
849
        public OrderFrequency saveOrderFrequency(OrderFrequency orderFrequency) throws APIException {
850
                return dao.saveOrderFrequency(orderFrequency);
1✔
851
        }
852
        
853
        /**
854
         * @see org.openmrs.api.OrderService#retireOrderFrequency(org.openmrs.OrderFrequency,
855
         *      java.lang.String)
856
         */
857
        @Override
858
        public OrderFrequency retireOrderFrequency(OrderFrequency orderFrequency, String reason) {
859
                return dao.saveOrderFrequency(orderFrequency);
1✔
860
        }
861
        
862
        /**
863
         * @see org.openmrs.api.OrderService#unretireOrderFrequency(org.openmrs.OrderFrequency)
864
         */
865
        @Override
866
        public OrderFrequency unretireOrderFrequency(OrderFrequency orderFrequency) {
867
                return Context.getOrderService().saveOrderFrequency(orderFrequency);
1✔
868
        }
869
        
870
        /**
871
         * @see org.openmrs.api.OrderService#purgeOrderFrequency(org.openmrs.OrderFrequency)
872
         */
873
        @Override
874
        public void purgeOrderFrequency(OrderFrequency orderFrequency) {
875
                
876
                if (dao.isOrderFrequencyInUse(orderFrequency)) {
1✔
877
                        throw new CannotDeleteObjectInUseException("Order.frequency.cannot.delete", (Object[]) null);
1✔
878
                }
879
                
880
                dao.purgeOrderFrequency(orderFrequency);
1✔
881
        }
1✔
882
        
883
        /**
884
         * @see org.openmrs.api.OrderService#getOrderFrequencyByConcept(org.openmrs.Concept)
885
         */
886
        @Override
887
        @Transactional(readOnly = true)
888
        public OrderFrequency getOrderFrequencyByConcept(Concept concept) {
889
                return dao.getOrderFrequencyByConcept(concept);
1✔
890
        }
891
        
892
        /**
893
         * @see GlobalPropertyListener#supportsPropertyName(String)
894
         */
895
        @Override
896
        public boolean supportsPropertyName(String propertyName) {
897
                return OpenmrsConstants.GP_ORDER_NUMBER_GENERATOR_BEAN_ID.equals(propertyName);
1✔
898
        }
899
        
900
        /**
901
         * @see GlobalPropertyListener#globalPropertyChanged(org.openmrs.GlobalProperty)
902
         */
903
        @Override
904
        public void globalPropertyChanged(GlobalProperty newValue) {
905
                setOrderNumberGenerator(null);
1✔
906
        }
1✔
907
        
908
        /**
909
         * @see GlobalPropertyListener#globalPropertyDeleted(String)
910
         */
911
        @Override
912
        public void globalPropertyDeleted(String propertyName) {
UNCOV
913
                setOrderNumberGenerator(null);
×
914
        }
×
915
        
916
        /**
917
         * Helper method to deter instance methods from setting static fields
918
         */
919
        private static void setOrderNumberGenerator(OrderNumberGenerator orderNumberGenerator) {
920
                OrderServiceImpl.orderNumberGenerator = orderNumberGenerator;
1✔
921
        }
1✔
922
        
923
        /**
924
         * @see org.openmrs.api.OrderService#getOrderType(Integer)
925
         */
926
        
927
        @Override
928
        @Transactional(readOnly = true)
929
        public OrderType getOrderType(Integer orderTypeId) {
930
                return dao.getOrderType(orderTypeId);
1✔
931
        }
932
        
933
        /**
934
         * @see org.openmrs.api.OrderService#getOrderTypeByUuid(String)
935
         */
936
        @Override
937
        @Transactional(readOnly = true)
938
        public OrderType getOrderTypeByUuid(String uuid) {
939
                return dao.getOrderTypeByUuid(uuid);
1✔
940
        }
941
        
942
        /**
943
         * @see org.openmrs.api.OrderService#getOrderTypes(boolean)
944
         */
945
        @Override
946
        @Transactional(readOnly = true)
947
        public List<OrderType> getOrderTypes(boolean includeRetired) {
948
                return dao.getOrderTypes(includeRetired);
1✔
949
        }
950
        
951
        /**
952
         * @see org.openmrs.api.OrderService#saveOrderType(org.openmrs.OrderType)
953
         */
954
        @Override
955
        public OrderType saveOrderType(OrderType orderType) {
956
                return dao.saveOrderType(orderType);
1✔
957
        }
958
        
959
        /**
960
         * @see org.openmrs.api.OrderService#purgeOrderType(org.openmrs.OrderType)
961
         */
962
        @Override
963
        public void purgeOrderType(OrderType orderType) {
964
                if (dao.isOrderTypeInUse(orderType)) {
1✔
965
                        throw new CannotDeleteObjectInUseException("Order.type.cannot.delete", (Object[]) null);
1✔
966
                }
967
                dao.purgeOrderType(orderType);
1✔
968
        }
1✔
969
        
970
        /**
971
         * @see org.openmrs.api.OrderService#retireOrderType(org.openmrs.OrderType, String)
972
         */
973
        @Override
974
        public OrderType retireOrderType(OrderType orderType, String reason) {
975
                return saveOrderType(orderType);
1✔
976
        }
977
        
978
        /**
979
         * @see org.openmrs.api.OrderService#unretireOrderType(org.openmrs.OrderType)
980
         */
981
        @Override
982
        public OrderType unretireOrderType(OrderType orderType) {
983
                return saveOrderType(orderType);
1✔
984
        }
985
        
986
        /**
987
         * @see org.openmrs.api.OrderService#getSubtypes(org.openmrs.OrderType, boolean)
988
         */
989
        @Override
990
        @Transactional(readOnly = true)
991
        public List<OrderType> getSubtypes(OrderType orderType, boolean includeRetired) {
992
                List<OrderType> allSubtypes = new ArrayList<>();
1✔
993
                List<OrderType> immediateAncestors = dao.getOrderSubtypes(orderType, includeRetired);
1✔
994
                while (!immediateAncestors.isEmpty()) {
1✔
995
                        List<OrderType> ancestorsAtNextLevel = new ArrayList<>();
1✔
996
                        for (OrderType type : immediateAncestors) {
1✔
997
                                allSubtypes.add(type);
1✔
998
                                ancestorsAtNextLevel.addAll(dao.getOrderSubtypes(type, includeRetired));
1✔
999
                        }
1✔
1000
                        immediateAncestors = ancestorsAtNextLevel;
1✔
1001
                }
1✔
1002
                return allSubtypes;
1✔
1003
        }
1004
        
1005
        /**
1006
         * @see org.openmrs.api.OrderService#getOrderTypeByConceptClass(org.openmrs.ConceptClass)
1007
         */
1008
        @Override
1009
        @Transactional(readOnly = true)
1010
        public OrderType getOrderTypeByConceptClass(ConceptClass conceptClass) {
1011
                return dao.getOrderTypeByConceptClass(conceptClass);
1✔
1012
        }
1013
        
1014
        /**
1015
         * @see org.openmrs.api.OrderService#getOrderTypeByConcept(org.openmrs.Concept)
1016
         */
1017
        @Override
1018
        @Transactional(readOnly = true)
1019
        public OrderType getOrderTypeByConcept(Concept concept) {
1020
                return Context.getOrderService().getOrderTypeByConceptClass(concept.getConceptClass());
1✔
1021
        }
1022
        
1023
        /**
1024
         * @see org.openmrs.api.OrderService#getDrugRoutes()
1025
         */
1026
        @Override
1027
        @Transactional(readOnly = true)
1028
        public List<Concept> getDrugRoutes() {
1029
                return getSetMembersOfConceptSetFromGP(OpenmrsConstants.GP_DRUG_ROUTES_CONCEPT_UUID);
1✔
1030
        }
1031
        
1032
        @Override
1033
        @Transactional(readOnly = true)
1034
        public List<Concept> getDrugDosingUnits() {
1035
                return getSetMembersOfConceptSetFromGP(OpenmrsConstants.GP_DRUG_DOSING_UNITS_CONCEPT_UUID);
1✔
1036
        }
1037
        
1038
        @Override
1039
        @Transactional(readOnly = true)
1040
        public List<Concept> getDrugDispensingUnits() {
1041
                List<Concept> dispensingUnits = new ArrayList<>(
1✔
1042
                                getSetMembersOfConceptSetFromGP(OpenmrsConstants.GP_DRUG_DISPENSING_UNITS_CONCEPT_UUID));
1✔
1043
                for (Concept concept : getDrugDosingUnits()) {
1✔
1044
                        if (!dispensingUnits.contains(concept)) {
1✔
1045
                                dispensingUnits.add(concept);
1✔
1046
                        }
1047
                }
1✔
1048
                return dispensingUnits;
1✔
1049
        }
1050
        
1051
        @Override
1052
        @Transactional(readOnly = true)
1053
        public List<Concept> getDurationUnits() {
1054
                return getSetMembersOfConceptSetFromGP(OpenmrsConstants.GP_DURATION_UNITS_CONCEPT_UUID);
1✔
1055
        }
1056
        
1057
        /**
1058
         * @see org.openmrs.api.OrderService#getTestSpecimenSources()
1059
         */
1060
        @Override
1061
        public List<Concept> getTestSpecimenSources() {
1062
                return getSetMembersOfConceptSetFromGP(OpenmrsConstants.GP_TEST_SPECIMEN_SOURCES_CONCEPT_UUID);
1✔
1063
        }
1064
        
1065
        @Override
1066
        public Concept getNonCodedDrugConcept() {
1067
                String conceptUuid = Context.getAdministrationService().getGlobalProperty(OpenmrsConstants.GP_DRUG_ORDER_DRUG_OTHER);
1✔
1068
                if (StringUtils.hasText(conceptUuid)) {
1✔
1069
                        return Context.getConceptService().getConceptByUuid(conceptUuid);
1✔
1070
                }
1071
                return null;
1✔
1072
        }
1073
        
1074
        @Override
1075
        @Transactional(readOnly = true)
1076
        public OrderGroup getOrderGroupByUuid(String uuid) throws APIException {
1077
                return dao.getOrderGroupByUuid(uuid);
1✔
1078
        }
1079
        
1080
        @Override
1081
        @Transactional(readOnly = true)
1082
        public OrderGroup getOrderGroup(Integer orderGroupId) throws APIException {
1083
                return dao.getOrderGroupById(orderGroupId);
1✔
1084
        }
1085
        
1086
        private List<Concept> getSetMembersOfConceptSetFromGP(String globalProperty) {
1087
                String conceptUuid = Context.getAdministrationService().getGlobalProperty(globalProperty);
1✔
1088
                Concept concept = Context.getConceptService().getConceptByUuid(conceptUuid);
1✔
1089
                if (concept != null && concept.getSet()) {
1✔
1090
                        return concept.getSetMembers();
1✔
1091
                }
1092
                return Collections.emptyList();
1✔
1093
        }
1094
        @Override
1095
        public List<OrderGroup> getOrderGroupsByPatient(Patient patient) throws APIException {
1096
                return dao.getOrderGroupsByPatient(patient);
1✔
1097
        }
1098

1099
        @Override
1100
        public List<OrderGroup> getOrderGroupsByEncounter(Encounter encounter) throws APIException {
1101
                return dao.getOrderGroupsByEncounter(encounter);
1✔
1102
        }
1103
        
1104
        /**
1105
         * @see org.openmrs.api.OrderService#getOrderGroupAttributeTypes()
1106
         */
1107
        @Override
1108
        @Transactional(readOnly = true)
1109
        public List<OrderGroupAttributeType> getAllOrderGroupAttributeTypes() throws APIException {
1110
                return dao.getAllOrderGroupAttributeTypes();
1✔
1111
        }
1112
        
1113
        /**
1114
         * @see org.openmrs.api.OrderService#getOrderGroupAttributeTypeById()
1115
         */
1116
        @Override
1117
        @Transactional(readOnly = true)
1118
        public OrderGroupAttributeType getOrderGroupAttributeType(Integer id) throws APIException {
1119
                return dao.getOrderGroupAttributeType(id);
1✔
1120
        }
1121
        
1122
        /**
1123
         * @see org.openmrs.api.OrderService#getOrderGroupAttributeTypeByUuid()
1124
         */
1125
        @Override
1126
        @Transactional(readOnly = true)
1127
        public OrderGroupAttributeType getOrderGroupAttributeTypeByUuid(String uuid)throws APIException {
1128
                return dao.getOrderGroupAttributeTypeByUuid(uuid);
1✔
1129
        }
1130
        
1131
        /**
1132
         * @see org.openmrs.api.OrderService#saveOrderGroupAttributeType()
1133
         */
1134
        @Override
1135
        public OrderGroupAttributeType saveOrderGroupAttributeType(OrderGroupAttributeType orderGroupAttributeType) throws APIException{
1136
                return dao.saveOrderGroupAttributeType(orderGroupAttributeType);
1✔
1137
        }
1138

1139
        /**
1140
         * @see org.openmrs.api.OrderService#retireOrderGroupAttributeType()
1141
         */
1142
        @Override
1143
        public OrderGroupAttributeType retireOrderGroupAttributeType(OrderGroupAttributeType orderGroupAttributeType, String reason)throws APIException {
1144
                return Context.getOrderService().saveOrderGroupAttributeType(orderGroupAttributeType);
1✔
1145
        }
1146

1147
        /**
1148
         * @see org.openmrs.api.OrderService#unretireOrderGroupAttributeType()
1149
         */
1150
        @Override
1151
        public OrderGroupAttributeType unretireOrderGroupAttributeType(OrderGroupAttributeType orderGroupAttributeType)throws APIException {
1152
                return Context.getOrderService().saveOrderGroupAttributeType(orderGroupAttributeType);
1✔
1153
        }
1154

1155
        /**
1156
         * @see org.openmrs.api.OrderService#purgeOrderGroupAttributeType()
1157
         */
1158
        @Override
1159
        public void purgeOrderGroupAttributeType(OrderGroupAttributeType orderGroupAttributeType) throws APIException{
1160
                dao.deleteOrderGroupAttributeType(orderGroupAttributeType);
1✔
1161
        }
1✔
1162

1163
        /**
1164
         * @see org.openmrs.api.OrderService#getOrderGroupAttributeTypeByName()
1165
         */
1166
        @Override
1167
        @Transactional(readOnly = true)
1168
        public OrderGroupAttributeType getOrderGroupAttributeTypeByName(String orderGroupAttributeTypeName)throws APIException {
1169
                return dao.getOrderGroupAttributeTypeByName(orderGroupAttributeTypeName);
1✔
1170
        }
1171

1172
        /**
1173
         * @see org.openmrs.api.OrderService#getOrderGroupAttributeByUuid()
1174
         */
1175
        @Override
1176
        @Transactional(readOnly = true)
1177
        public OrderGroupAttribute getOrderGroupAttributeByUuid(String uuid)throws APIException {
1178
                return dao.getOrderGroupAttributeByUuid(uuid);
1✔
1179
        }
1180

1181
        /**
1182
         * @see org.openmrs.api.OrderService#getAllOrderAttributeTypes()
1183
         */
1184
        @Override
1185
        @Transactional(readOnly = true)
1186
        public List<OrderAttributeType> getAllOrderAttributeTypes() throws APIException {
1187
                return dao.getAllOrderAttributeTypes();
1✔
1188
        }
1189

1190
        /**
1191
         * @see org.openmrs.api.OrderService#getOrderAttributeTypeById(Integer)
1192
         */
1193
        @Override
1194
        @Transactional(readOnly = true)
1195
        public OrderAttributeType getOrderAttributeTypeById(Integer id) throws APIException {
1196
                return dao.getOrderAttributeTypeById(id);
1✔
1197
        }
1198

1199
        /**
1200
         * @see org.openmrs.api.OrderService#getOrderAttributeTypeByUuid(String)
1201
         */
1202
        @Override
1203
        @Transactional(readOnly = true)
1204
        public OrderAttributeType getOrderAttributeTypeByUuid(String uuid)throws APIException {
1205
                return dao.getOrderAttributeTypeByUuid(uuid);
1✔
1206
        }
1207

1208
        /**
1209
         * @see org.openmrs.api.OrderService#saveOrderAttributeType(OrderAttributeType)
1210
         */
1211
        @Override
1212
        public OrderAttributeType saveOrderAttributeType(OrderAttributeType orderAttributeType) throws APIException{
1213
                return dao.saveOrderAttributeType(orderAttributeType);
1✔
1214
        }
1215

1216
        /**
1217
         * @see org.openmrs.api.OrderService#retireOrderAttributeType(OrderAttributeType)
1218
         */
1219
        @Override
1220
        public OrderAttributeType retireOrderAttributeType(OrderAttributeType orderAttributeType, String reason)throws APIException {
1221
                return Context.getOrderService().saveOrderAttributeType(orderAttributeType);
1✔
1222
        }
1223

1224
        /**
1225
         * @see org.openmrs.api.OrderService#unretireOrderAttributeType(OrderAttributeType)
1226
         */
1227
        @Override
1228
        public OrderAttributeType unretireOrderAttributeType(OrderAttributeType orderAttributeType)throws APIException {
1229
                return Context.getOrderService().saveOrderAttributeType(orderAttributeType);
1✔
1230
        }
1231

1232
        /**
1233
         * @see org.openmrs.api.OrderService#purgeOrderAttributeType(OrderAttributeType)
1234
         */
1235
        @Override
1236
        public void purgeOrderAttributeType(OrderAttributeType orderAttributeType) throws APIException{
1237
                dao.deleteOrderAttributeType(orderAttributeType);
1✔
1238
        }
1✔
1239

1240
        /**
1241
         * @see org.openmrs.api.OrderService#getOrderAttributeTypeByName(String)
1242
         */
1243
        @Override
1244
        @Transactional(readOnly = true)
1245
        public OrderAttributeType getOrderAttributeTypeByName(String orderAttributeTypeName)throws APIException {
UNCOV
1246
                return dao.getOrderAttributeTypeByName(orderAttributeTypeName);
×
1247
        }
1248

1249
        /**
1250
         * @see org.openmrs.api.OrderService#getOrderAttributeByUuid(String)
1251
         */
1252
        @Override
1253
        @Transactional(readOnly = true)
1254
        public OrderAttribute getOrderAttributeByUuid(String uuid)throws APIException {
1255
                return dao.getOrderAttributeByUuid(uuid);
1✔
1256
        }
1257
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc