A plain-language reference for product folks scoping work that touches order entry in the O3 patient chart — medications and lab/test orders. The doc walks through the experience end to end: what the clinician does, what O3 sends to the backend, what gets validated and saved, and where the data ends up downstream (pharmacy, external systems via FHIR).
Audience: Product managers, designers, and analysts working on O3 medications, orders, or pharmacy. Engineering teammates can use this as a jumping-off point but should consult the codebase for implementation details.
1. What the clinician can do in O3
In the O3 patient chart, a clinician working with a patient's medications or lab orders has four actions available. Three of them appear as menu items on each existing order (Modify, Discontinue, Renew); the fourth is "place a new order" via the order basket.
Action in the UI | What the clinician is doing | What happens to the existing order |
|---|---|---|
Order basket (new order) | Placing a fresh order via the basket workspace | n/a — there is no existing order |
Modify | Editing an existing medication order, usually active or upcoming (e.g., adjusting the dose) | The original is automatically stopped when the edit saves. |
Discontinue | Stopping an active order | The original is marked stopped. |
Renew | Continuing an order past its end date | Nothing. The original keeps running until it expires or is discontinued separately. See Section 3. |
Renew is the action with the most surprising end-to-end behavior, so it gets its own section. The rest of this doc covers what's common to all four (validation in Section 2) and the renewal-specific story in Section 3.
Medication orders can also be scheduled to start in the future. Future-start medication orders appear in an Upcoming Medications section until their scheduled start date passes, at which point they move into the active medications view.
1.5 A note on care settings
Several rules later in the doc are scoped by care setting — the clinical context an order belongs to. The default OpenMRS configuration ships with two care settings: Inpatient (e.g., a hospital ward stay) and Outpatient (e.g., a clinic visit). Implementations can define their own — for example "Emergency Department" or "Ambulatory Surgery" — via the system configuration layer.
For PM scoping, three things are worth knowing:
The "outpatient quantity & refills required" rule (see Section 2.5) only fires for orders placed in an outpatient care setting. Inpatient orders aren't subject to it.
The "no two active orders for the same drug" check is scoped to a single care setting. A patient can have an active inpatient Paracetamol prescription and an active outpatient Paracetamol prescription simultaneously without the system flagging a conflict.
A renewal can't change the care setting. If a patient transitions from inpatient to outpatient, the outpatient prescription is a fresh new order, not a renewal of the inpatient one.
2. What gets checked when an order is saved
When the clinician saves the order basket, O3 sends each order to the OpenMRS backend, which runs validation before persisting. If a rule fails, O3 surfaces the error message back to the clinician and the save doesn't go through. The rules fall into a few groups.
2.1 Required fields (always)
The clinician must provide all of these. Missing any one of them blocks the save with "Cannot be empty or null."
Field | Notes |
|---|---|
Patient | Set automatically by O3 from the patient chart context. |
Encounter | O3 attaches the order to the active visit / encounter. |
Orderer | The clinician placing the order. |
Urgency | Routine, STAT, or "on a scheduled date." |
Action | One of the four from Section 1 — set by O3 from the menu the clinician clicked. |
What's being ordered | For a lab order, a concept (e.g., "CBC"). For a drug order, the drug. |
Several of these are handled automatically by O3 (patient, encounter, orderer come from chart context) so the clinician rarely sees errors on them. The fields they typically see errors on are urgency, the orderable, and any drug-specific fields below.
2.2 Sanity checks on the dates
OpenMRS stores two date concepts that product teams should keep separate:
dateActivated: when the order record is activated in OpenMRS. This cannot be in the future.
scheduledDate: when a scheduled order should clinically start. This is only valid when urgency is ON_SCHEDULED_DATE.
For medication orders in O3:
Past and same-day starts are posted as dateActivated.
Future starts are posted as scheduledDate with urgency ON_SCHEDULED_DATE.
Active-medication revisions cannot be scheduled for a future start. They must start today or earlier because the backend stops the previous order immediately before the replacement order's dateActivated.
The backend still enforces these date rules:
dateActivated cannot be in the future.
dateActivated cannot be after the stop date.
dateActivated cannot be after the auto-expiry date.
dateActivated cannot be before the encounter date.
If urgency is ON_SCHEDULED_DATE, scheduledDate must be provided.
If scheduledDate is provided, urgency must be ON_SCHEDULED_DATE.
2.3 Consistency checks
The encounter must belong to the same patient as the order. (O3 sets these from the same context, so this only fires on data corruption.)
If urgency is "on a scheduled date," a scheduled date must be provided. If a scheduled date is provided, urgency must be set to "on a scheduled date."
If the order is part of an order group (multiple orders saved together), the group's encounter and patient must match the order's.
2.4 Drug-order-specific rules
Drug orders have additional rules on top of the ones above.
Rule | Error the clinician sees |
|---|---|
"As needed?" flag must be answered (yes/no) | Cannot be empty or null |
Dosing type (simple or free-text instructions) must be selected | Cannot be empty or null |
If a dose is filled in, dose units must be too — and the dose must be greater than zero | Dose Units is required when dose is specified / Dose should be greater than 0 |
If quantity is filled in, quantity units must be too | Quantity units is required when quantity is specified |
If duration is filled in, duration units must be too | Durations units is required when duration is specified |
The chosen units must be from the allowed list configured for the implementation | The units concept must be among allowed concepts |
The chosen route must be from the allowed list | The route concept must be among allowed concepts |
For simple dosing (the default), the clinician must also fill in dose, dose units, route, and frequency.
For free-text dosing (where the clinician types instructions like "take with food twice daily"), the instructions field is required.
2.5 Rules that depend on configuration
Some rules are turned on or off via system-level settings. Implementations can change these without code changes.
Outpatient quantity & refills (default: required): for outpatient drug orders, quantity and number of refills must be filled in. Implementations that don't manage outpatient dispensing can disable this.
Drug formulation requirement (default: off): if turned on, the clinician must pick a specific drug formulation (e.g., "paracetamol 500mg tablet") rather than just a generic concept ("paracetamol"). Off by default because many implementations don't maintain a full drug formulary.
2.6 Rules with missing translations
A handful of edge-case rules have error keys defined in the system but no English translation registered, so if they fire the clinician sees a raw key like Order.error.orderEncounterAndOrderGroupEncounterMismatch instead of a readable message. These are rare to hit in practice but worth knowing if your team gets a confused user report.
3. Renewal end-to-end
Renewal looks simple in the UI but has a few product-important details because it creates a new order that points back to the order being continued.
3.1 The clinician's experience in O3
The clinician opens the patient's medications list in the chart.
They click the overflow menu on an active medication and choose Renew.
The order basket opens with a basket item pre-filled from the original prescription: drug, dose, route, frequency, duration, instructions, quantity, and related fields.
The clinician adjusts whatever needs changing, including the start date.
They save the basket.
3.2 What O3 sends to the backend
When the basket is saved, O3 sends the medication renewal as action = RENEW and includes previousOrder, which points to the original prescription.
The start-date fields follow the same model as new medication orders:
If the selected start is today or in the past, O3 sends dateActivated.
If the selected start is in the future, O3 sends scheduledDate and urgency = ON_SCHEDULED_DATE.
3.3 What the backend does with it
Saves a new order linked to the original through previousOrder.
Does not automatically stop the original order. The original keeps running until it expires or is discontinued separately.
Runs the standard validation rules from Section 2.
Allows the renewal to coexist with its direct previous order. For unrelated active prescriptions of the same drug, the system still blocks overlapping schedules with the duplicate-active-order error described in Section 5.
3.4 What's allowed to change on renewal
Field | Can it change on renewal? |
|---|---|
Dose, frequency, route, duration | Yes |
Quantity, refills | Yes |
Instructions (patient or free-text) | Yes |
Indication / reason for the order | Yes |
Start date | Yes, including a future scheduled start |
The drug itself | No. The O3 form does not expose the drug field on Renew. |
Order type (drug vs. test vs. referral) | No |
Care setting (inpatient vs. outpatient) | No |
If a clinician needs to switch to a different drug, that's a discontinue + new order, not a renewal.
3.5 What this means for the rest of the system
Renewals are distinguishable in the OpenMRS order action.
O3 now sends RENEW to the backend for medication renewals, with a previousOrder link to the original prescription. Reporting that reads OpenMRS orders directly can use those fields to distinguish renewals from unrelated new orders.Same-day renewal is still allowed.
A clinician can place a 7-day prescription in the morning and renew it in the afternoon. The system saves both, leaving the original to expire naturally unless it is discontinued separately.Pharmacy and integration behavior still needs product validation.
Any downstream product that needs to show continuity, prevent double-dispensing, or analyze renewal chains should verify whether it reads action and previousOrder from the OpenMRS REST representation or whether its integration layer drops that relationship.
4. Implications for adjacent products
The order-entry behavior above matters for reporting, FHIR consumers, and pharmacy workflows.
4.1 Reporting and integrations should preserve renewal links
Medication renewals are represented in OpenMRS with action = RENEW and a previousOrder link. Consumers that need continuity analysis should preserve both fields. If a reporting pipeline, FHIR mapping, or analytics extract only carries the standalone medication request without the previous-order relationship, renewals may still look like separate prescriptions downstream even though OpenMRS itself has the link.
If a stakeholder asks "can we report on chronic medication continuity?" or "can we measure adherence across renewals?", confirm which data source they plan to use and whether that source exposes the renewal relationship.
4.2 Pharmacy needs awareness of overlapping and future-start orders
The pharmacy app should be explicit about whether a prescription is active now, upcoming, renewed from a prior prescription, or overlapping with another prescription for the same drug.
Two product risks to watch:
Double-dispensing: if a clinician renews a prescription before the original is discontinued or expired, pharmacy users need enough context to avoid dispensing duplicate supply.
Future starts: an upcoming prescription should not be treated the same as one that is active today.
Both are addressable, but require pharmacy-side workflows to read the order schedule and renewal relationship rather than treating each prescription in isolation.
5. Common errors and what they mean
A short reference for triaging support tickets or stakeholder questions where someone has quoted an error verbatim. Not exhaustive — the ones below are the errors most likely to surface in real conversations. For the full validation matrix, see Section 2.
Error message the clinician sees | What it means / when it fires | Resolution |
|---|---|---|
Cannot have more than one active order for the same orderable and care setting at same time | The clinician tried to place a new (or revise/renew an unrelated) drug order for a drug that already has an active prescription in the same care setting, with overlapping schedules. Doesn't fire when renewing against the specific prior prescription the new order points to, or when discontinuing. If the patient has multiple active orders for the same drug - for example an original and an earlier renewal both still running - the save will still be rejected; the system only exempts the direct prior-order link, not the whole chain. | Discontinue any active prescriptions for the same drug other than the one being directly renewed (or wait for them to expire) before placing a new one. Note: "same orderable" means the same drug regardless of dose, route, or frequency — two active Paracetamol orders at different doses still count as a duplicate. |
Quantity is required for out patient drug orders | Outpatient drug orders require quantity by default. Fires when the clinician saves a basket order without filling in quantity. | Fill in quantity. Implementations that don't manage outpatient dispensing can disable this requirement at the system level (see Section 2.5). |
Number of refills is required for out patient drug orders | Same as above — outpatient orders require refills count by default. | Fill in number of refills. Implementations can disable this at the system level. |
Date activated cannot be in the future | The order payload sent a future value in dateActivated. Normal future medication starts should not hit this anymore because O3 sends them as scheduledDate with urgency ON_SCHEDULED_DATE. This can still happen with malformed clients, clock drift, | For medication future starts, use the start-date field normally so O3 sends a scheduled order. For active-medication revisions, choose today or an earlier valid date. For integrations, send future starts as scheduledDate with urgency ON_SCHEDULED_DATE, not as future dateActivated. |
Date activated cannot be before that of the associated encounter | The order's start date is earlier than the encounter it's attached to. Hit during retrospective entry when the encounter date and the order date drift apart. | Either align the encounter date with the order, or move the order onto a different encounter. |
Dose Units is required when dose is specified / Quantity units is required when quantity is specified / Durations units is required when duration is specified | Partial-fill errors — the clinician filled in a number but not the matching unit. The fields are paired and the backend enforces both being present together. | Fill in the matching unit. (Worth flagging to UX if it happens often — pairing the fields visually in the form would prevent it.) |
Dose should be greater than 0 | The dose field was filled in with zero or a negative number. Common data-entry slip when a clinician is pasting from another system or types ahead. | Enter a dose greater than zero. |
The route concept must be among allowed concepts / The units concept must be among allowed concepts | The selected route or unit isn't in the implementation's configured allowed-concepts list. This usually means the form is offering choices that haven't been registered in the relevant system-level setting, or the implementation's concept dictionary is partially set up. | Configuration issue, not a clinician issue. The implementation administrator needs to add the concept to the appropriate allowed-list global property (see Section 2.5 / drug units & routes configuration). |