Order Entry Module Design
We did not release this module. Ultimately, we introduced a new Order Entry API in OpenMRS Platform 1.10.0, and there is no module to add this support in earlier OpenMRS platform versions.
Background
A new 'Order Entry' module will be authored to provide a new API and features necessary to manage patient specific orders, the module is intended to be a cleaner version of the existing order entry API with several additions and subtractions. For more background information, please visit api support for order entry page. This module will use the "org.openmrs" namespace, rather than the conventional "org.openmrs.module" namespace in order to more easily support the goal of eventually incorporating this module into core. By keeping it as a module initially, this allows implementations running older versions of OpenMRS (1.7, 1.8, 1.9, etc) to take advantage of, and test out, this work, without requiring them to upgrade. It also will allow the module to evolve at a different pace than the core code.
The module will use existing orders tables, installing the module will essentially lead to modification of the related tables,
Can we have the OrderService in core marked as deprecated prior to releasing 1.9?
Module id: orderentry
Module name: Order Entry
Package namespace: org.openmrs.orderentry
Module design
We are getting rid of the OrderType class including the associated database table, the broader categorization of will by the concept class of each order's backing concept. A more granular break down of these can be done through attribute types. (Though this is not supported in older versions)
Order
( * = required)
class Order extends BaseOpenmrsData{
public enum OrderAction {
DISCONTINUE, ORDER
}
*Integer orderId
*Patient patient
*Concept concept
*String orderNumber
String previousOrderNumber
*OrderAction orderAction
*Date startDate
Date autoExpireDate
*Encounter encounter
String instructions
*User orderer
Boolean discontinued
User discontinuedBy
Date discontinuedDate
String discontinuedReason
}
DrugOrder
class DrugOrder extends Order{
Drug drug
Concept concept;//should be drug.concept if drug is not null
Double dose
String doseUnits
Boolean isStructuredDosing
Double strength
String strengthUnits
Integer quantity
String quantityUnits
String frequency
String brandName
String dosageForm
String route
Boolean asNeeded - Indicated PRN
String asNeededCondition
String additionalInstructions
Integer duration
String durationUnits
Integer numRefills
}
TestOrder
class TestOrder extends Order{
Concept specimenSource
Concept laterality
String clinicalHistory
}
Orderable
Marker interface for things that a User can order
public interface Orderable {
String getUniqueIdentifier(); //The unique identifier for this Orderable.
Concept getConcept(); //The concept of the order that will ultimately be created from this Orderable.
String getName(); //display name of this orderable, typically should be inherited from the concept. Intended for use in the UI.
String getDescription(); //display descripion of this orderable, typically should be inherited from the concept. Intended for use in the UI.
}
BaseOrderable
Base implementation of the Orderable interface, should define the properties and provide the default implementation of the inherited methods
Is Drug.concept nullable?
abstract class BaseOrderable{
Concept concept; //will this be required?
String name; //We really need this if drug.concept is nullable and fetch it from the drug?
String description; //same here
}
SimpleOrderable
Acts a wrapper for a concept or Drug(if drug.concept is nullable) with concept class as 'Drug' or 'Test' or 'Misc Order' or a Drug with no
class GenericOrderable extends BaseOrderable{
//constructor that takes in a concept
public SimpleOrderable(Concept concept) {
..............
}
//constructor that takes in a drug if drug.concept is nullable
public SimpleOrderable(Drug drug) {
..............
}
//return something unique with type included i.e Concept Vs Drug(if drug.concept is nullable)
@Override
public String getUniqueIdentifier() {
...........
}
}
OrderEntryService
interface OrderService extends OpenmrsService{
saveOrder(Order);//Should not let you change an Order. can only do an sql insert from here.
voidOrder(Order, String voidReason);
unvoidOrder(Order order);
purgeOrder(Order);
//Creates a new order with a new order number that is a "discontinue" order. previous_order_number on this
//should point to old Order, also finds old Order and marks it as discontinued with the given parameters
discontinueOrder(Order order, Concept discontinueReason, Date discontinueDate);
discontinueOrder(Order order, String discontinueReason, Date discontinueDate);
createOrdersAndEncounter(Patient p, Collection<Order> orders);// activates the orders given, do we need this?
getOrder(Integer orderId);
getOrderByUuid(String uuid);
String getNewOrderNumber();
getOrderByOrderNumber(String orderNumber);
Class<T extends Order> getOrder(Integer orderId, Class<T> orderClassType);
getOrders(Class<T extends Order> orderClassType, List<Patient> patients, List<Concept> concepts, OrderAction action, List<User> orderers, List<Encounter> encounters, List<ConceptClass> conceptClasses);
getOrdersByOrderer(User user);
getOrdersByPatient(Patient patient);
getDrugOrdersByPatient(Patient patient, OrderAction orderAction);
getDrugOrdersByPatient(Patient patient, OrderAction orderAction, boolean includeVoided);
getDrugOrdersByPatient(Patient patient);
getOrdersByEncounter(Encounter encounter);
List<Order> getOrderHistoryByConcept(Patient patient, Concept concept);
getOrderables(String query);
getOrderables(String uniqueIdentifier);
}
OrderValidator
class OrderValidator implements Validator{
public void validate(Object obj, Errors errors) {
//Enforce all required fields
//TODO: What are the extra validation rules?
}
}
DrugOrderValidator
class DrugOrderValidator extends OrderValidator{
public void validate(Object obj, Errors errors) {
super.validate(obj, errors);
//drug and concept cannot both be null, drug.concept should match concept if not null
//Check that the class of the concept is Drug
//TODO: Add other validation rules specific to drug orders
}
}
TestOrderValidator
class TestOrderValidator extends OrderValidator{
public void validate(Object obj, Errors errors) {
super.validate(obj, errors);
//Check that the class of the concept is Test
//TODO: Add other validation rules specific to test orders
}
}