/** * The contents of this file are subject to the OpenMRS Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.api.impl; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.Concept; import org.openmrs.DrugOrder; import org.openmrs.Encounter; import org.openmrs.EncounterType; import org.openmrs.Location; import org.openmrs.Order; import org.openmrs.OrderType; import org.openmrs.Patient; import org.openmrs.User; import org.openmrs.aop.RequiredDataAdvice; import org.openmrs.api.APIException; import org.openmrs.api.OrderService; import org.openmrs.api.context.Context; import org.openmrs.api.db.OrderDAO; import org.openmrs.api.handler.SaveHandler; import org.openmrs.order.DrugOrderSupport; import org.openmrs.order.OrderUtil; import org.openmrs.order.RegimenSuggestion; import org.openmrs.validator.ValidateUtil; import org.springframework.util.StringUtils; /** * Default implementation of the Order-related services class. This method should not be invoked by * itself. Spring injection is used to inject this implementation into the ServiceContext. Which * implementation is injected is determined by the spring application context file: * /metadata/api/spring/applicationContext.xml * * @see org.openmrs.api.OrderService */ public class OrderServiceImpl extends BaseOpenmrsService implements OrderService { protected final Log log = LogFactory.getLog(getClass()); protected OrderDAO dao; public OrderServiceImpl() { } /** * @see org.openmrs.api.OrderService#setOrderDAO(org.openmrs.api.db.OrderDAO) */ public void setOrderDAO(OrderDAO dao) { this.dao = dao; } /** * @see org.openmrs.api.OrderService#saveOrder(org.openmrs.Order) */ public Order saveOrder(Order order) throws APIException { ValidateUtil.validate(order); return dao.saveOrder(order); } /** * @see org.openmrs.api.OrderService#createOrder(org.openmrs.Order) * @deprecated */ @Deprecated public void createOrder(Order order) throws APIException { Context.getOrderService().saveOrder(order); } /** * @see org.openmrs.api.OrderService#updateOrder(org.openmrs.Order) * @deprecated */ @Deprecated public void updateOrder(Order order) throws APIException { Context.getOrderService().saveOrder(order); } /** * @see org.openmrs.api.OrderService#deleteOrder(org.openmrs.Order) * @deprecated */ @Deprecated public void deleteOrder(Order order) throws APIException { Context.getOrderService().purgeOrder(order); } /** * @see org.openmrs.api.OrderService#purgeOrder(org.openmrs.Order) */ public void purgeOrder(Order order) throws APIException { purgeOrder(order, false); } /** * @see org.openmrs.api.OrderService#purgeOrder(Order) */ public void purgeOrder(Order order, boolean cascade) throws APIException { if (cascade) { // TODO delete other order stuff before deleting this order // (like DrugOrder?) throw new APIException("Cascade purging of Orders is not written yet"); } dao.deleteOrder(order); } /** * @see org.openmrs.api.OrderService#voidOrder(org.openmrs.Order, java.lang.String) */ public Order voidOrder(Order order, String voidReason) throws APIException { // fail early if this order is already voided if (order.getVoided()) return order; if (!StringUtils.hasLength(voidReason)) throw new IllegalArgumentException("voidReason cannot be empty or null"); order.setVoided(Boolean.TRUE); order.setVoidReason(voidReason); order.setVoidedBy(Context.getAuthenticatedUser()); order.setDateVoided(new Date()); return saveOrder(order); } /** * @see org.openmrs.api.OrderService#unvoidOrder(org.openmrs.Order) */ public Order unvoidOrder(Order order) throws APIException { order.setVoided(false); return saveOrder(order); } /** * @see org.openmrs.api.OrderService#discontinueOrder(org.openmrs.Order, org.openmrs.Concept, * java.util.Date) */ public Order discontinueOrder(Order order, Concept discontinueReason, Date discontinueDate) throws APIException { order.setDiscontinued(Boolean.TRUE); order.setDiscontinuedReason(discontinueReason); order.setDiscontinuedDate(discontinueDate); order.setDiscontinuedBy(Context.getAuthenticatedUser()); return saveOrder(order); } /** * @see org.openmrs.api.OrderService#undiscontinueOrder(org.openmrs.Order) */ public Order undiscontinueOrder(Order order) throws APIException { order.setDiscontinued(Boolean.FALSE); order.setDiscontinuedBy(null); order.setDiscontinuedDate(null); order.setDiscontinuedReason(null); return saveOrder(order); } /** * @see org.openmrs.api.OrderService#saveOrderType(org.openmrs.OrderType) */ public OrderType saveOrderType(OrderType orderType) throws APIException { return dao.saveOrderType(orderType); } /** * @see org.openmrs.api.OrderService#createOrderType(org.openmrs.OrderType) * @deprecated */ @Deprecated public void createOrderType(OrderType orderType) throws APIException { Context.getOrderService().saveOrderType(orderType); } /** * @see org.openmrs.api.OrderService#updateOrderType(org.openmrs.OrderType) * @deprecated */ @Deprecated public void updateOrderType(OrderType orderType) throws APIException { Context.getOrderService().saveOrderType(orderType); } /** * @see org.openmrs.api.OrderService#deleteOrderType(org.openmrs.OrderType) * @deprecated */ @Deprecated public void deleteOrderType(OrderType orderType) throws APIException { Context.getOrderService().purgeOrderType(orderType); } /** * @see org.openmrs.api.OrderService#retireOrderType(OrderType, String) */ public OrderType retireOrderType(OrderType orderType, String reason) throws APIException { orderType.setRetired(true); orderType.setRetireReason(reason); return saveOrderType(orderType); } /** * @see org.openmrs.api.OrderService#unretireOrderType(org.openmrs.OrderType) */ public OrderType unretireOrderType(OrderType orderType) throws APIException { orderType.setRetired(false); return saveOrderType(orderType); } /** * @see org.openmrs.api.OrderService#purgeOrderType(org.openmrs.OrderType) */ public void purgeOrderType(OrderType orderType) throws APIException { dao.deleteOrderType(orderType); } /** * TODO: Refactor, generalize, or remove this method * * @see org.openmrs.api.OrderService#createOrdersAndEncounter(org.openmrs.Patient, * java.util.Collection) */ public void createOrdersAndEncounter(Patient p, Collection<Order> orders) throws APIException { // Get unknown user (or the authenticated user) User unknownUser = Context.getUserService().getUserByUsername("Unknown"); // TODO: fix this hack if (unknownUser == null) { unknownUser = Context.getAuthenticatedUser(); } // Get unknown location Location unknownLocation = Context.getLocationService().getDefaultLocation(); if (unknownUser == null || unknownLocation == null) { throw new APIException("Couldn't find a Location and a User named 'Unknown'."); } EncounterType encounterType = Context.getEncounterService().getEncounterType("Regimen Change"); if (encounterType == null) { throw new APIException("Couldn't find an encounter type 'Regimen Change'"); } Encounter e = new Encounter(); e.setPatient(p); e.setProvider(unknownUser.getPerson()); e.setLocation(unknownLocation); e.setEncounterDatetime(new Date()); // TODO: Remove hardcoded encounter type e.setEncounterType(encounterType); RequiredDataAdvice.recursivelyHandle(SaveHandler.class, e, null); for (Order order : orders) { e.addOrder(order); order.setEncounter(e); } Context.getEncounterService().saveEncounter(e); } /** * @see org.openmrs.api.OrderService#getOrder(java.lang.Integer) */ public Order getOrder(Integer orderId) throws APIException { return getOrder(orderId, Order.class); } /** * @see org.openmrs.api.OrderService#getDrugOrder(java.lang.Integer) * @deprecated */ @Deprecated public DrugOrder getDrugOrder(Integer drugOrderId) throws APIException { return getOrder(drugOrderId, DrugOrder.class); } /** * @see org.openmrs.api.OrderService#getOrder(java.lang.Integer, java.lang.Class) */ public <o extends Order> o getOrder(Integer orderId, Class<o> orderClassType) throws APIException { return dao.getOrder(orderId, orderClassType); } /** * @deprecated This is a dumb method */ @Deprecated public List<Order> getOrders() throws APIException { return getOrders(Order.class, null, null, null, null, null, null); } /** * @deprecated This is a dumb method */ @Deprecated public List<DrugOrder> getDrugOrders() throws APIException { return getOrders(DrugOrder.class, null, null, null, null, null, null); } /** * @see org.openmrs.api.OrderService#getOrders(java.lang.Class, java.util.List, java.util.List, * org.openmrs.api.OrderService.ORDER_STATUS, java.util.List, java.util.List, * java.util.List) */ public <Ord extends Order> List<Ord> getOrders(Class<Ord> orderClassType, List<Patient> patients, List<Concept> concepts, ORDER_STATUS status, List<User> orderers, List<Encounter> encounters, List<OrderType> orderTypes) { if (orderClassType == null) throw new APIException( "orderClassType cannot be null. An order type of Order.class or DrugOrder.class is required"); if (patients == null) patients = new Vector<Patient>(); if (concepts == null) concepts = new Vector<Concept>(); if (status == null) status = ORDER_STATUS.CURRENT; if (orderers == null) orderers = new Vector<User>(); if (encounters == null) encounters = new Vector<Encounter>(); if (orderTypes == null) orderTypes = new Vector<OrderType>(); return dao.getOrders(orderClassType, patients, concepts, status, orderers, encounters, orderTypes); } /** * @see org.openmrs.api.OrderService#getOrdersByUser(org.openmrs.User) */ public List<Order> getOrdersByUser(User user) throws APIException { if (user == null) throw new APIException("Unable to get orders if I am not given a user"); List<User> users = new Vector<User>(); users.add(user); return getOrders(Order.class, null, null, ORDER_STATUS.NOTVOIDED, users, null, null); } /** * @see org.openmrs.api.OrderService#getOrdersByPatient(org.openmrs.Patient) */ public List<Order> getOrdersByPatient(Patient patient) throws APIException { if (patient == null) throw new APIException("Unable to get orders if I am not given a patient"); List<Patient> patients = new Vector<Patient>(); patients.add(patient); return getOrders(Order.class, patients, null, ORDER_STATUS.NOTVOIDED, null, null, null); } /** * @see org.openmrs.api.OrderService#getDrugOrdersByPatient(org.openmrs.Patient, int) * @deprecated */ @Deprecated public List<DrugOrder> getDrugOrdersByPatient(Patient patient, int whatToShow) { return getDrugOrdersByPatient(patient, whatToShow, false); } /** * @see org.openmrs.api.OrderService#getDrugOrdersByPatient(org.openmrs.Patient, int, boolean) * @deprecated */ @Deprecated public List<DrugOrder> getDrugOrdersByPatient(Patient patient, int whatToShow, boolean includeVoided) { return getDrugOrdersByPatient(patient, convertToOrderStatus(whatToShow), includeVoided); } /** * @see org.openmrs.api.OrderService#getDrugOrdersByPatient(org.openmrs.Patient, * org.openmrs.api.OrderService.ORDER_STATUS, boolean) */ @SuppressWarnings("unchecked") public List<DrugOrder> getDrugOrdersByPatient(Patient patient, ORDER_STATUS orderStatus, boolean includeVoided) { if (patient == null) throw new APIException("Unable to get drug orders if not given a patient"); List<Patient> patients = new Vector<Patient>(); patients.add(patient); List<DrugOrder> drugOrders = getOrders(DrugOrder.class, patients, null, ORDER_STATUS.ANY, null, null, null); // loop over the drug orders and add them if they are within the current desired order if (drugOrders != null) { if (orderStatus == ORDER_STATUS.ANY) return drugOrders; else { // the user wants to limit the type of drug order to get, so loop over // them all and do the logic on each List<DrugOrder> ret = new ArrayList<DrugOrder>(); for (DrugOrder drugOrder : drugOrders) { if (orderStatus == ORDER_STATUS.CURRENT && drugOrder.isCurrent()) ret.add(drugOrder); else if (orderStatus == ORDER_STATUS.NOTVOIDED && !drugOrder.getVoided()) ret.add(drugOrder); else if (orderStatus == ORDER_STATUS.COMPLETE && drugOrder.isDiscontinuedRightNow()) ret.add(drugOrder); } return ret; } } // default return if no drug orders were found in the database return Collections.EMPTY_LIST; } /** * @see org.openmrs.api.OrderService#getDrugOrdersByPatient(org.openmrs.Patient, * org.openmrs.api.OrderService.ORDER_STATUS) */ public List<DrugOrder> getDrugOrdersByPatient(Patient patient, ORDER_STATUS orderStatus) { return getDrugOrdersByPatient(patient, orderStatus, false); } /** * @see org.openmrs.api.OrderService#getOrderTypes() * @deprecated */ @Deprecated public List<OrderType> getOrderTypes() throws APIException { return getAllOrderTypes(true); } /** * @see org.openmrs.api.OrderService#getAllOrderTypes() */ public List<OrderType> getAllOrderTypes() throws APIException { return getAllOrderTypes(true); } /** * @see org.openmrs.api.OrderService#getAllOrderTypes(boolean) */ public List<OrderType> getAllOrderTypes(boolean includeRetired) throws APIException { return dao.getAllOrderTypes(includeRetired); } /** * @see org.openmrs.api.OrderService#getOrderType(java.lang.Integer) */ public OrderType getOrderType(Integer orderTypeId) throws APIException { return dao.getOrderType(orderTypeId); } /** * @see org.openmrs.api.OrderService#getDrugOrdersByPatient(org.openmrs.Patient) */ public List<DrugOrder> getDrugOrdersByPatient(Patient patient) throws APIException { List<Patient> patients = new Vector<Patient>(); patients.add(patient); return getOrders(DrugOrder.class, patients, null, ORDER_STATUS.NOTVOIDED, null, null, null); } /** * @see org.openmrs.api.OrderService#getStandardRegimens() */ public List<RegimenSuggestion> getStandardRegimens() { DrugOrderSupport dos = null; List<RegimenSuggestion> standardRegimens = null; try { dos = DrugOrderSupport.getInstance(); } catch (Exception e) { log.error("Error getting instance of DrugOrderSupport object", e); } if (dos != null) { standardRegimens = dos.getStandardRegimens(); } else { log.error("DrugOrderSupport object is null after new instance"); } return standardRegimens; } /** * @see org.openmrs.api.OrderService#getDrugSetsByConcepts(java.util.List, java.util.List) * @deprecated use {@link OrderUtil#getDrugSetsByConcepts(List, List)} */ @Deprecated public Map<Concept, List<DrugOrder>> getDrugSetsByConcepts(List<DrugOrder> drugOrders, List<Concept> drugSets) throws APIException { return OrderUtil.getDrugSetsByConcepts(drugOrders, drugSets); } /** * @see org.openmrs.api.OrderService#getDrugSetsByDrugSetIdList(java.util.List, * java.lang.String, java.lang.String) * @deprecated use {@link OrderUtil#getDrugSetsByDrugSetIdList(List, String, String)} */ @Deprecated public Map<String, List<DrugOrder>> getDrugSetsByDrugSetIdList(List<DrugOrder> orderList, String drugSetIdList, String delimiter) { return OrderUtil.getDrugSetsByDrugSetIdList(orderList, drugSetIdList, delimiter); } /** * @see org.openmrs.api.OrderService#getDrugSetHeadersByDrugSetIdList(java.lang.String) * @deprecated use {@link OrderUtil#getDrugSetHeadersByDrugSetIdList(String)} */ @Deprecated public Map<String, String> getDrugSetHeadersByDrugSetIdList(String drugSetIds) { return OrderUtil.getDrugSetHeadersByDrugSetIdList(drugSetIds); } /** * @see org.openmrs.api.OrderService#discontinueDrugSet(org.openmrs.Patient, java.lang.String, * org.openmrs.Concept, java.util.Date) * @deprecated use {@link OrderUtil#discontinueDrugSet(Patient, String, Concept, Date)} */ @Deprecated public void discontinueDrugSet(Patient patient, String drugSetId, Concept discontinueReason, Date discontinueDate) { OrderUtil.discontinueDrugSet(patient, drugSetId, discontinueReason, discontinueDate); } /** * @see org.openmrs.api.OrderService#voidDrugSet(Patient, String, String, int) * @deprecated use * {@link OrderUtil#voidDrugSet(Patient, String, String, org.openmrs.api.OrderService.ORDER_STATUS)} */ @Deprecated public void voidDrugSet(Patient patient, String drugSetId, String voidReason, int whatToVoid) { OrderUtil.voidDrugSet(patient, drugSetId, voidReason, convertToOrderStatus(whatToVoid)); } /** * @see org.openmrs.api.OrderService#discontinueAllOrders(org.openmrs.Patient, * org.openmrs.Concept, java.util.Date) * @deprecated use {@link OrderUtil#discontinueAllOrders(Patient, Concept, Date)} */ @Deprecated public void discontinueAllOrders(Patient patient, Concept discontinueReason, Date discontinueDate) { OrderUtil.discontinueAllOrders(patient, discontinueReason, discontinueDate); } /** * Convenience method to convert between the old integer Order status and the new enumeration * ORDER_STATUS. This method can be removed when all deprecated methods using the Integer order * status are removed * * @param oldOrderStatus * @return */ @SuppressWarnings("deprecation") private ORDER_STATUS convertToOrderStatus(Integer oldOrderStatus) { switch (oldOrderStatus) { case SHOW_CURRENT: return ORDER_STATUS.CURRENT; case SHOW_ALL: return ORDER_STATUS.ANY; case SHOW_COMPLETE: return ORDER_STATUS.COMPLETE; //case SHOW_NOTVOIDED: // fall through to default default: return ORDER_STATUS.NOTVOIDED; } } /** * @see org.openmrs.api.OrderService#getOrderByUuid(java.lang.String) */ public Order getOrderByUuid(String uuid) throws APIException { return dao.getOrderByUuid(uuid); } /** * @see org.openmrs.api.OrderService#getOrderTypeByUuid(java.lang.String) */ public OrderType getOrderTypeByUuid(String uuid) throws APIException { return dao.getOrderTypeByUuid(uuid); } /** * @see org.openmrs.api.OrderService#getOrdersByEncounter(org.openmrs.Encounter) */ public List<Order> getOrdersByEncounter(Encounter encounter) { List<Encounter> encounters = new Vector<Encounter>(); encounters.add(encounter); return getOrders(Order.class, null, null, null, null, encounters, null); } }