Have you implemented OpenMRS? Please participate in the Implementation Site Survey. If you already have, thank you!
Child pages
  • 2011 Initial attempt at API Support for Order Entry
Skip to end of metadata
Go to start of metadata

Background


Order entry is an important part of an electronic medical record system.  To date, OpenMRS has provided minimal support for orders within the database, since our initial focus was on around data (observation) gathering and reporting.  As OpenMRS implementations have grown, more and more have found the need for support of orders within the system.  Our goal is to create enterprise-quality support for order-entry within OpenMRS.  We begin with the underlying API (programmers interface).


Scope


Our goal is to provide an order entry service capable of supporting outpatient orders, focusing initially on medication orders but allowing for other types of orders (tests, referrals, etc.).  While starting with outpatient orders, we want a design that will be able to gracefully grow into support for inpatient orders as well as supporting concurrent inpatient and outpatient orders.


We are taking a pragmatic approach, realizing that our design will not cover every possible attribute or need, but will cover at least 80% of the use cases & needs within resource-constrained environments.


Definitions


  • activation – an order is "activated" at the point that it can be carried out (filled) – i.e., in a paper-based system, an "activated" order is one that has been written in ink and signed.  In many cases, signing & activation occur within in a single step, where, for example, signing an order also makes it immediately available to be carried out.  In other cases, signing & activation may occur in discrete steps.  For example: in some clinical workflows (especially inpatient settings) certain orders (like admitting, discharge, & transfer orders) may be created & signed prior to being activated.  When verbal orders are created, they may be activated before being signed by the ordering provider.  "Activated" and "active" have different meanings, see the note below on "Activated vs. Active".
  • order number – this is an identifier generated for a given order and shared by all revisions (if any) of that order.  The order number is passed to ancillary systems in order for results & events related to the order to be connected to the original order.
  • order filter – filters determine which properties (fields) available within a given context.  Similar to order validators, filters can be chained together to apply specific business rules based on the current context (user, setting, patient, item being ordered, etc.).  For example, if refills are not allowed for opiates then an order filter could remove "refills" from the list of available properties when an opiate is being ordered.
  • order group – orders may be placed within groups to assist with subsequent management or reporting of the orders (e.g., a drug regimen of three drugs may be placed within an order group).
  • order set – an order set represents a pre-defined list of orders to be used in certain situations (e.g., pre-defined drug regimens, a set of common orders for treating viral gastroenteritis, etc.)
  • order template – an order template is a document (e.g., XML) describing a single order, which may include choices and/or defaults for the various components of the order – i.e., a pre-defined order.  templates allow providers generate structured orders without having to manually complete every component of the order.
  • order type – there are pre-defined types of orders (e.g., medications, tests, referrals, activities, diet, etc.)
  • order validator – used to check the validity of an order given the current ordering context (setting, user, item being ordered, etc.); multiple order validators may be chained together so that each validator can focus on a specific business rule.
  • order version – to keep track of different revisions of the same order
  • orderable concepts – only certain concepts are valid for defining an order (e.g., while you might want to order a "CD4 COUNT", you should not be able to order an "HIV POSITIVE" or a "YES").
  • orders – our "order" is modeled much like the HL7 order event.  Each order represents a clinical provider's intent for something to happen for/to a patient, including drug prescriptions, tests, referrals, etc.
  • signing – signing of an order represents either documentation of an existing signature or – more commonly – the electronic signature provided by a user
  • urgency – specifies when the order should first occur (e.g., stat/immediately, routine, on a specific date, etc.)


"Active" Orders


There can be many interpretations of "active" orders (e.g., which medications have been ordered, which medications are being filled, which medications are being taken) and these are not always identical lists.  There can also be differences based on context – e.g., inpatient medications vs. outpatient medications.  Within the order entry API, we are focused on orders, so "active" refers to those things that have been ordered, should have already started, and have not yet ended/expired.  Knowledge about which orders are actually being followed (e.g., medication adherence, prescription dispensing data, etc.) are outside of the scope of the first pass at a generic order entry API.  For example, medication reconciliation can be a complete project in its own right, taking into consideration adherence, dispensing data, orders from external systems, and orders placed through the order entry API.


"Activated" vs. "Active"


It's possible for an order to be "activated" (available for filling, no longer modifiable) but not yet "active."  For example, an order can be signed & activated with a start date two weeks in the future; in this case, the order is "activated" (signed & can no longer be modified, only discontinued & replaced if needed) but may not be considered an "active" order until the start date is reached.  We may end up wanting to consider future tests (with a future start date) as "active" (or let implementations decide on which behavior they prefer, if that can be done without complicating the API).


Structured Dosing vs. Unstructured Dosing


Drug orders include dosing information that explains how much, in what manner, and in what frequency the medication should be administered.  The dosing information can be collected in either a structured (discrete values for each component) or unstructured (free text) format.  While structured dosing information allows for valuable calculations (e.g., how much medicine the patient will need and/or how much the pharmacy must order to maintain inventory), not all implementations need this level of detail.  Some implementations will never need the detailed dosing information and can function fine with free text instructions for all orders, some implementations may wish to pick & choose when they structure information vs. use free text, and other implementation will expect fully structured dosing information for every drug order.  Allowing for both structured & unstructured dosing of medication allows OpenMRS to adapt to the needs of the implementation and prevents our API from assuming everyone will order medications with the same level of detail.  Allowing for unstructured dosing also provides a mechanism for handling complex dosing instructions that cannot be expressed in simple terms (e.g., take 2 pills in the morning and 1 pill in the evening).


Requirements


1.10


  • Allow creation of simple drug orders.
  • Revise orders.
  • Discontinue orders.
  • Allow grouping of orders (to support regimens and/or arbitrary groupings)
  • Get orderable concept(s) ± limited by query string
  • Get active order(s) by patient ± as of a specific date.
  • Get order(s) by patient ± within date range.
  • Get order(s) by encounter.
  • Get order(s) by concept.
  • Get order(s) by ordering user.
  • Get order by order number.
  • Get order(s) by indication.
  • Get order(s) by group
  • Get all order set(s), order set(s) by name, or order set(s) by concept.
  • Proof of concept of a module adding its own new type of order, with proper inheritance


Post-1.10


  • Advanced order set definitions (e.g., exclusion criteria)
  • Ability to filter orders by care setting – e.g., get all inpatient orders vs. all outpatient orders.
  • Support for order alerts (drug-drug interaction, drug-diagnosis interaction, allergy, etc.)
  • Support for additional order types (diet orders, referrals, activities, etc.)
  • HL7 support (inbound and outbound orders)
  • Order tagging
  • Mapping to standardized drug terminologies
  • Mapping to standardized drug terminologies
  • Support for multiple dosing clauses for drug orders (e.g., with AND/OR/THEN conjunctions like the NHS Dose Syntax).
  • ... and much more.


Design


  • The base "order" object represents the foundation shared by all orders.  Some types of orders – e.g., medications and tests – extend the base orders object to add type-specific attributes.
    * Despite the convention of singular table names in OpenMRS (e.g., person, patient), we use the plural form for the orders table, since "order" is an SQL keyword (just as we've done with the users table).


Orders Data Model


The orders tables define the base order and those types of orders that extend the base: drug orders and test orders.

Orders Data Model

Orders


  • orderId (int 11) – primary key
  • orderNumber (varchar 50) -- a unique identifier shared by all versions of a given order. this is the identifier sent to external systems when referring to this order.
  • orderVersion (int) – a 1-based revision count for tracking revisions within the same order number
  • latestVersion (boolean) – use to mark the latest version for any order number (with each new revision, this is set to false for any existing versions and the new version gets latestVersion = true. this exists solely to allow the maximum version for any order number to be found quickly
  • previousOrderNumber (varchar 50) – when a new order is created from an existing, previously activated order (e.g., a discontinuation or change in dose), this property links back to the order that was cloned. note that once an order has been activated, it cannot be revised as the same order, so any edits to the instructions/dosing or an order to discontinue an existing order gets a new order number. this property provides a mechanism to link related orders across order numbers.
  • patient (FK to patient)
  • encounter (FK to encounter)
  • orderType (int) – a discriminator that defines the type of order (e.g., drug order vs. test order)
  • orderAction (varchar 50) – a selection from an enumeration of possible actions (e.g., NEW, REVISE, DISCONTINUE, CONTINUE, etc.).  See Order Actions section below.
  • concept (FK to orderable concept) – if we are ordering AMPICILLIN, this points to the ampicillin concept
  • noncodedName (varchar 255) – for orders where a specific concept does not exist, this property holds the name of the order (e.g., concept = OTHER DRUG ORDER #1 and noncodedName = "Foobaricillin", used when Foobaricillin was just released and hasn't made it into the concept dictionary but still needs to be ordered).
  • urgency (varchar 50) – defines the urgency/priority of the order, e.g., STAT, NOW, ROUTINE, ON DATE, BEFORE DATE, AFTER DATE, CONDITIONAL.
  • conditionality (varchar 255) – for orders with a CONDITIONAL urgency, this property contains free text describing the condition(s) under which the order should be performed, e.g., "when the patient returns from surgery"
  • instructions (text) – free text instructions for the order (e.g., details about a referral, justification for a cardiac stress test, etc.)
  • frequency (varchar 50) – described the frequency of repeats for an order (note: eventually, we may want to draw these from a table of possible values)
  • indication (a concept) – the reason for the order
  • comment (text) – free text comments
  • startDate (datetime) – when the order should begin
  • autoExpireDate (datetime) – when the order should be discontinued if it hasn't already
  • signedBy (user) – user responsible for the order
  • dateSigned (datetime) – when order was signed
  • activatedBy (user) – user who activate the order so that it could be carried out (may be different from signing user in some cases)
  • dateActivated (datetime) -- when order was activated
  • filledBy (varchar 255) -- unique reference to the party responsible for filling or carrying out the order, e.g., the lab that reported the result or the pharmacy the filled the prescription (note: we will need a convention for formatting this)
  • dateFilled (datetime) – when order was filled
  • dateDiscontinued (datetime) – when the order was discontinued
  • discontinuedReason (varchar 255) – the reason for discontinuing the order
  • creator (user)
  • dateCreated (datetime)
  • voided (boolean)
  • voidedBy (user)
  • dateVoided (datetime)
  • uuid (varchar 38)


DrugOrder extends Order


  • order (super.order_id)
  • drug (FK to drug) – the specific drug prescribed
  • brandName (varchar 255) -- the brand name, when applicable, of the drug being prescribed
  • strength (double) – specifies the strength of a single dose of the medication (e.g., "20" for a 20 milligram pill)
  • strengthUnits (varchar 255) – specifies the units of a single dose of the medication (e.g., "milligrams" for a 20 milligram pill) (note: eventually we will probably want to constrain this to values within a separate table)
  • dose (double) – specifies the amount for a single dose (e.g., "2" in 2 tablets or "100" in 100 milligrams)
  • dosageForm (varchar 50) – specifies the units for a single dose (e.g., "tablets" in 2 tablets)
  • route (varchar 50) – the way in which the medication enters the body (e.g., PO for per oral == by mouth)
  • unstructuredDosing (varchar 1024) – dosing instructions provided as free text either because fully specifying dose & frequency are not needed by the implementation or the instructions are too complex to fit into the simplified model of dose & frequency properties.
  • duration (double) – specifies the value for the prescription's duration (e.g., "14" in 14 days), may be null when duration duration value does not apply (e.g., indefinite prescriptions or one-time-only prescriptions)
  • durationUnits (varchar 50) – specifies the units for the prescription's duration (e.g., the "days" in 14 days)
  • asNeeded (boolean) – true for "PRN" prescriptions, i.e., medications that are taken "as needed"
  • asNeededCondition (varchar 255) – for PRN prescriptions, specifies when the medication should be taken (e.g., "cough" for a cough medication or "insomnia" for a sleeping aid)
  • additionalInstructions (varchar 1024) – additional information, usually for the patient, e.g., "take while sitting" or "take with a full glass of water"
  • quantity (double) – amount to be dispensed (e.g., "100" in 100 pills)
  • quantityUnits (varchar 50) – specifies the dispensing units (e.g., "pills" in 100 pills). (note: we will eventually want a separate table to constrain these values)
  • numRefills (int) – the number of times the medication can be refilled
  • order_id is a unique, internal id
  • order_number, order_version, and latest_version indicate the order number (shared with ancillary systems) and revisions to an order before it is finalized
  • previous_order_number allows orders to be linked to a previous order – e.g., an order discontinue ampicillin linked to the original ampicillin order (the D/C gets its own order number)
  • order_group allows orders to be grouped – e.g., drug regimens 
  • order_type would be an enumeration of order types – e.g., DRUG, TEST, REFERRAL, DIET, etc.
  • order_status hold the state of the order within pre-defined workflows – e.g., SIGNED, PENDING, ACTIVATED, FILLED, etc.  (deferred for now)
  • date_activated: an order is considered "activated" (order is currently active or has ever been active) if the date_activated is not null
  • order_action represents the action being taken on an order – e.g., DISCONTINUE, CARRY-OVER, etc.
  • noncoded_name allows for orders to be created for items that are not yet in the dictionary – e.g., OTHER DRUG ORDER #1 with non-coded name "CANE".
  • urgency and conditionality describe when an order should be carried out: STAT, ROUTINE, WHEN "patient arrives on the ward."
  • filler is an optional URI to a person or process that fulfilled the order – possibly even a pointer to the object/resource that represents the result
  • discontinued_reason is optional text that would go on the D/C order (this was a coded answer in previous versions of openmrs)
  • date_discontinued is set when an order is explicitly discontinued or auto-expired
    • In order to set the date_discontinued when orders automatically expire, we will need mechanism to perform this task in the background in an efficient – yet ideally real-time – manner.  For example, registering the order_id with an auto-expriation process whenever auto-expiration is set/changed and/or a cron job to scan for passed auto-expiration dates ± register upcoming auto-expirations.
  • strength_units, dosage_form, route, duration_units, quantity_units, and frequency should (at least eventually) be drawn from explicit code sets
    • We could use concepts, but this would require mapping or creation of specific concepts before ordering would work.  While units, route, and even dosage form might work as concepts, we might want specific tables for frequency to allow for (1) frequency patterns – like "every x hours" – and (2) representing computer-understandable versions.
  • We may want to add an optional specimen or specimen_identifier to order_test to accommodate for a specimen identifier sent back from a lab.  Alternatively, we may be able to get to this information via select accession_number from obs where order_id = ?.


Order Sets Data Model


Order sets are used to pre-define sets of orders in order to make the ordering process easier – i.e., pick from a list instead of having to manually enter orders for common orders or groups of orders.  Order sets can contain 0-to-n members; each member can be a reference to an orderable concept, an order template (pre-defined order), or another order set.

Order Set Model

  • order_set_id and order_set_member_id are unique internal ids
  • order_set_status indicates the state of the order set – e.g., DRAFT, READY FOR REVIEW, PUBLISHED.
  • operator represents how members of the set can be selected: ANY, ONE, or ALL: ANY allows for multiple selection, ONE forces single selection amongst members, and ALL means that you must either order all members or none.
  • name is used for administration of order sets & would be a fully specified name to support organization/searching among order sets.  Name is optional, since there can be anonymous order sets used for grouping of members within another order set.


OrderService API


OpenMRS already has an early version of an OrderService with basic CRUD support for orders.


Existing OrderService methods


  • saveOrder(Order)
    • TODO: should not let you change an Order.  can only do an sql insert from here.
  • voidOrder(Order)
  • unvoidOrder(Order order)
  • purgeOrder(Order)
  • discontinueOrder(Order order, Concept discontinueReason, Date discontinueDate)
    • TODO: creates a new order with a new order number that is a "discontinue" order.  previous_order_number on this should point to old Order
    • TODO: also finds old Order and marks it as discontinued with the given parameters
  • undiscontinueOrder(Order order)
    • TODO:
  • createOrdersAndEncounter(Patient p, Collection<Order> orders)
    • TODO: activates the orders given
  • getOrder(Integer orderId)
  • getOrderByUuid(String uuid)
  • getOrder(Integer orderId, Class<Ord> orderClassType)
  • getOrders(Class<Ord> orderClassType, List<Patient> patients, List<Concept> concepts, ORDER_STATUS status, List<User> orderers, List<Encounter> encounters, List<OrderType> orderTypes)
  • getOrdersByUser(User user)
  • getOrdersByPatient(Patient patient)
  • getStandardRegimens()
  • getDrugOrdersByPatient(Patient patient, ORDER_STATUS orderStatus)
  • getDrugOrdersByPatient(Patient patient, ORDER_STATUS orderStatus, boolean includeVoided)
  • getDrugOrdersByPatient(Patient patient)
  • getOrdersByEncounter(Encounter encounter)


Suggested new OrderService methods


  • saveOrder(...all required params...no Order object...)
    • used for inserts mainly
    • if called with a previously saved order, creates a new one with the new fields, doens't change the old one, and links the two orders using previous_order_number
    • (similar to saveObs())
  • modifyOrder(Order old, Order new)
    • (implement this or no?)
  • saveActivatedOrder(___, Provider/User?) ?? (or name this documentOrder() or saveDocumentOrder() or saveHistoricalOrder())
    • calls saveOrder, signOrder, activateOrder
  • signOrder(Order, Provider)
    • Can we discern if the Provider is a Nurse vs MD here, or do we need multiple signOrder methods?
    • means setting date signed and signed by
  • activateOrder(Order)
  • fillOrder(Order, User)
    • calls following method with a urn
  • fillOrder(Order, String) // if filler is not a user
    • means it was completed
    • if the order is not signed yet, throw an exception
  • Order getOrderByOrderNumber(String orderNumber)
    • Gets the 'latest_version=true' order with this orderNumber
  • List<Order> getOrderHistoryByOrderNumber(String orderNumber)  // or by Order object?
    • returns all orders, even ones discontinued, even old versions of the order
  • List<Order> getOrderHistoryByConcept(Concept)
    • similar to previous, gets all Order objects that use this Concept
    • create and use an OrderHistory object for this?  Would keep the sequence/history of the Orders and convenience methods for how to look at them.
  • discontinueOrder(Concept)
    • finds all active orders with this drug/concept and discontinues them



Order Actions


  • NEW -- creating a new order
  • REVISE -- modifying an existing order (e.g., changing dose of a medication, edits to instructions, etc.)
  • CONTINUE -- continue an existing order (e.g., providing another prescription for a chronic medication when refills run out)
  • DISCONTINUE -- stopping an order


This list could be extended to include HOLD, to indicate an order that should be held for one or more doses; however, we have seen too many medical errors from mistakes involving "HOLD" orders and would prefer not to promote the practice (i.e., it's safer to discontinue the order and then rewrite it when it should be resumed).


Orders can be discontinued whether or not they are active.  This is necessary, because we cannot assume that the computer will always know about all active prescriptions.  For example, if a patient shows up to clinic already taking a prescription that is not in the computer records and you want them to stop, it's helpful to be able to explicitly write a DISCONTINUE order for that medication even though it's not an active order.  The workaround of writing for the medication and then immediately discontinuing is not viable, since it could imply that were ordering the medication for the patient at some point.


TODO (and notes)


  • Rename "Regimens" tab to "Drug Orders"
  • "standard drug regimens" replaced by order sets and and templates in them
  • When initially creating orders via a saveEncounter call, the orders should be in draft state.  A second call to sign all the orders is needed
  • order_number, order_version, latest version are internally maintained, not to be entered by a user
  • Don't link to the admin page edit screen from the dashboard.  add a small popup that only lets the user edit certain properties
  • On dashboard, can change the dosage to "change" an order. (aka orders are linked via discontinue and new order)
    • aka, should not be able to change an activated order
  • Make saveOrder smarter so that we can link/dc/etc orders if there are other ones that are related?
  • Mutability needs to be researched, may be done for API 2.0, but not here
    • Order object properties should be mostly immutable. 
    • Encounter.orders should not contain mutable Order objects


Interested Parties



Assigned Developers



Work Items


  1. Add new objects and attributes to current order and drug order objects
  2. Determine the feasibility of transitioning from current Orders to new orders
    1. If doable, add liquibase changesets, etc
    2. If impossible, investigate writing a one-time-use script or module to help implementations with the upgrade.  PIH has a lot of experience with orders, get feedback from them
  3. Modify the Regimens tab to work with new order templating system
  4. Update the simple order jsp pages to work with the new attributes
  5. TBD: Write a module with more complex workflow possibilities. 


Other Questions


  • How do we identify orderable concepts?  By class(es)?
  • Do we treat the orders table as a transactional table (essentially write-only) vs. creating separate table(s) for storing revision history?
  • Can we support draft orders & encounters & visits – i.e., unsigned work – within the same tables?  Or do we persist these data elsewhere until signed?
    • PROS:
      • Avoid creating separate table(s) for persisting drafts
      • Increases potential in the future to see or react to concurrent drafts
    • CONS:
      • Drafts must be filtered by API
      • Old drafts will need to be cleaned
  • We'll need to agree on order workflows – i.e., what are the valid states of an order.
  • Our first pass at medication orders assumes a single clause for structured dosing.  Eventually, we may want to support multiple clauses linked with AND/OR/THEN to allow for structured representation of more complex medication orders.
    • Support for multiple clause structured dosing could be supported within the data model by adding preceding_order_drug_id (to link to preceding clause) and conjunction (to represent join as AND vs. OR vs. THEN).  More complete representation of structured dosing clauses would probably require moving structured dose into a separate order_drug_dosing table.


See Also



Associated Tickets

type key summary assignee reporter priority status resolution created updated due

Data cannot be retrieved due to an unexpected error.

View these issues in Jira

Notes

16 Comments

  1. If we end up needing to put the business to determine which orders are active in more than one place within the DAO layer, then we should re-visit adding an "active" flag on orders so that determining active orders is much simpler.

  2. Comments from Roger Friedman...

    Requirements

    • Need to anticipate that some orders will have a destination outside of the current system

    Design

    • Hibernate doesn't handle extensions of concrete classes well.  I think we would be better off having an OrderBase table with extension tables for each order type, including SimpleOrder which has no additional data.  We could use a discriminator column in OrderBase and share order IDs between OrderBase and the particular extension table.
    • Please add Concept and Drug tables to the orders data model diagram to show interactions.
  3. Comment from Dave Thomas:

    DT: How would you recognize that a group of orders had been created through an OrderSet? Like, for example, recognizing a group of drugOrders (that would be ordered by order_group) as corresponding to the template for a given standard regimen? Maybe the orders table needs an order_set_id column?

    We've pulled order_group into its own table and order_set_id is an optional attribute of the order group.

  4. Need to investigate the "action by" in ORC – Saptarshi brought up the use case of being able to indicate who (e.g., which department) should perform the order.

  5. Comment from Roger:

    Re Referral as an order type, here is some definitional stuff from HL7 ch. 11 sec. 2.1.1:

    There are clear distinctions between a referral and an order.  An order is almost always an intra-enterprise transaction and represents a request from a patient's active provider to supporting providers for clearly defined services and/or results.  While the supporting provider may exercise great discretion in the performance of an order, overall responsibility for the patient's plan of treatment remains with the ordering provider.  ...  A referral, on the other hand, can be either an intra- or an interenterprise transaction and represents not only a request for additional provider support but also a transfer of a portion or all of the responsibility for the patient's plan of treatment.  Once the referral is made, the referring provider, during the transfer period, retains almost no control of any resulting actions. 

    Is this a distinction that we want to make?  Or should we use the referral as a model and consider referrals as out of scope for orders?

    1. We've benefited from modeling most of the action requested by a provider as types of orders, including consults to other services.  It's true that referrals or typically routed differently; however, the difference between referrals & other orders isn't much more than the difference between medications & tests – e.g., some laboratory tests are sent outside of the enterprise to be resulted.

      That said, referrals does not need to be a 1.0 feature.

  6. Burke --

       How about standing orders?  At one time, these were an important tool for improving immunization coverage.

    1. You're correct that standing orders can be an important tool.  These can be handled by order sets – e.g., NEW HIV PATIENT ORDERS or STANDARD ADMISSION ORDERS – or entered into the system through an application.

      FWIW, for some standing orders, specifically immunizations, we've found that the most effective approach can be to bypass the doctors altogether – e.g., build these into the standard workflow of nurses outside of the order entry system.

      1. Burke --  From your state diagrams for the verbal and student cases, I thought one thing you were trying to achieve was accountability for orders.  While an order set might say what to do, it doesn't handle the authorization issue.

        1. The state diagrams were more about understanding different workflows – e.g., verbal orders get activated _before_ being signed by the provider who gave them.  Authorization (who can write verbal orders, who can activate orders, etc.) will be handled through privileges.

  7. Burke, when a Gliffy diagram changes, there is no way to tell what has changed.  Maybe change the text of the field descriptions at the same time so there's a normal confluence change.  Confluence has changed the Gliffy linkage, it used to ask for what has been changed, but I don't think it worked, my watchers never got notified when I changed the diagram. 

    Are the filled items really of cardinality 1?  Certainly not in the pharmacy, certainly not in physical therapy.  Since all the order feedback is expacted to be in encounters/observations, you could ditch the filled items and rely on the order link in the feedback.

    HL7 has code tables for both dosage units and frequency.

  8. Burke, I tried to use this data model for lab orders and had some problems. (1) Multiple lab panels/tests can be ordered at the same time, but orders allow only one. Not an insurmountable problem, but complicated by (2) the relationship between orders and specimens is 1..m:1..n and we would like to track clinic specimen ID and lab specimen ID. (3) The urgency field needs to be coded or have a stat boolean and/or a timestamp. (Is there a need for more categories than high, normal and low priority?) (4) There is no way to relate retests that require new specimens to the original test or even to mark the test as a retest. (5) Many elements of the conceptual model simply don't apply to lab orders.

    I think this is a case where we have to do more detailed design of the subtypes (lab orders, drug orders, diagnostic test orders, diet orders, physical therapy orders, referrals) before we define the core data elements of the order supertype. I need to hit the books on HL7 order segment.

    We should make sure the implementation is Hibernate-friendly. Concretely, I think the UUID and audit information belongs in the order supertype; but do we have/need an OpenMRSObject subtype to accomodate a table of subtype specific information? How will inheritance affect the synch module?

    1. Doesn't having an OrderGroup that includes multiple orders cover the case of multiple lab panels/tests ordered at a time?

      1. I thought that order group was only for an instance of an order set. Here the tests/panels are selected independently but simultaneously.

        1. I think Burke's idea is that in this case you'd have created an order set that includes the (optional) tests in the panel. But he should really answer this.

          1. Just to clarify, I am already considering order sets as a single test (or single-result tests as comprising a one-element set). So a urinalysis set might include pH and sugar content, but the doctor could also order a urine pregnancy test; it's not my intention to require the doctor to order "urinalysis + pregnancy" or "urinalysis w/o pregnancy" (which ramifies quickly when you have several additional tests). Yet both tests could be run on the same specimen.