Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

References/Medication Administration

From OHC Network Wiki
referencemedicationsCARE 3.0+

MedicationAdministration records that a medication was given to a patient — or that giving it was attempted — fulfilling a MedicationRequest. You write one each time a dose is administered against an order. The Django model is the storage layer; several columns are opaque JSONFields whose structure comes from the Pydantic resource specs in care/emr/resources/medication/administration/. Both layers are documented below.

Source:

Models

Model Purpose
MedicationAdministration The administration event that fulfils a [[References/Medication Request

MedicationAdministration extends EMRBaseModel, the shared Care EMR base that provides external_id, audit fields, and soft-delete semantics (see Base model). It maps to the FHIR [https://hl7.org/fhir/medicationadministration.html MedicationAdministration] resource.

MedicationAdministration fields

Each row lists the storage column type and, where the column is a JSONField, the structured shape the resource spec enforces.

Status & classification

Field Storage Spec shape Notes
status CharField(100) MedicationAdministrationStatus enum Required. Administration event status — see [[#medicationadministrationstatus-values
status_reason JSONField (null) Coding bound to system-medication value set Optional. Coded reason for the status. The spec binds this to the medication value set, not the "not given" reason set you might expect
category CharField(100) (null) MedicationAdministrationCategory enum Optional. Administration setting — see [[#medicationadministrationcategory-values

Medication & product

Field Storage Spec shape Notes
medication JSONField (default {}) Coding bound to system-medication value set Optional in spec. { system, version?, code, display? }. Mutually exclusive with administered_product (model validator)
administered_product FK → ProductKnowledge (null, CASCADE) UUID4 (write) / nested ProductKnowledgeReadSpec (read) Optional. The specific catalog product administered. Cannot be set together with medication
dosage JSONField (null) Dosage nested spec Optional. Dose, rate, route, site, and method actually administered — see [[#dosage-nested-spec

Subject & context

Field Storage Spec shape Notes
patient FK → Patient (CASCADE) not in spec (server-derived) The patient who received the medication. Set server-side from the encounter's patient on create — never accepted from the client
encounter FK → Encounter (null, CASCADE) UUID4 (required, write) The encounter during which the medication was administered. Validated to exist; read schema returns the encounter's external_id
request FK → MedicationRequest (null, CASCADE) UUID4 (required, write) The order this administration fulfils. Validated to exist; read schema returns the request's external_id

Timing & attribution

Field Storage Spec shape Notes
authored_on DateTimeField (null) datetime Optional. When the record was authored, distinct from when the dose was given
occurrence_period_start DateTimeField (default datetime.now) datetime (required) When the administration began. Required on create; defaults to now at the model level
occurrence_period_end DateTimeField (null) datetime Optional. End of the administration, for infusions and extended doses. Updatable via MedicationAdministrationUpdateSpec
recorded DateTimeField (null) datetime Optional. When the event was entered into the system, distinct from occurrence_period_start
performer JSONField (default []) list[MedicationAdministrationPerformer] Optional. Actors who performed the administration and their function — see [[#medicationadministrationperformer-nested-spec
note TextField (null) str Optional. Free-text annotation. Updatable via MedicationAdministrationUpdateSpec

Enum values

MedicationAdministrationStatus values

str enum (care/emr/resources/medication/administration/spec.py). These use underscores (e.g. not_done), not the FHIR hyphenated forms.

Value
completed
not_done
entered_in_error
stopped
in_progress
on_hold
unknown
cancelled

MedicationAdministrationCategory values

Value
inpatient
outpatient
community
discharge

MedicationAdministrationPerformerFunction values

Value
performer
verifier
witness

Nested specs (JSON-field shapes)

Dosage (nested spec)

Structured shape of the dosage JSONField. Every field is optional.

Field Type Notes
text str Free-text dosage instructions
site Coding Bound to system-body-site value set (SNOMED CT << 91723000)
route Coding Bound to system-route value set (SNOMED CT << 284009009)
method Coding Bound to system-administration-method value set (SNOMED CT << 736665006)
dose Quantity The amount of medication administered
rate Quantity The speed of administration

Quantity shape (care/emr/resources/common/quantity.py, extra="forbid"): { value: Decimal? (max_digits 20, decimal_places 6), unit: Coding?, code: Coding?, meta: dict? }.

Coding shape (care/emr/resources/common/coding.py, extra="forbid"): { system: str?, version: str?, code: str (required), display: str? }.

MedicationAdministrationPerformer (nested spec)

Element shape of the performer JSONField list.

Field Type Notes

{{Field|model=MedicationAdministration|section=MedicationAdministrationPerformer (nested spec)|name=actor|type=UUID4 (required)|notes=The user who performed the administration. Validated server-side to reference an existing [[References/User & Skills}} {{Field|model=MedicationAdministration|section=MedicationAdministrationPerformer (nested spec)|name=function|type=MedicationAdministrationPerformerFunction | None|notes=The performer's function — see [[#medicationadministrationperformerfunction-values}}

Bound value sets

Coded fields bind to Care system value sets (SNOMED CT). ValueSetBoundCoding rejects any code outside the bound set.

Field Value set Slug SNOMED CT constraint
medication, status_reason Medication system-medication << 763158003 (Medicinal product)
dosage.site Body Site system-body-site is-a 91723000
dosage.route Route system-route is-a 284009009
dosage.method Administration Method system-administration-method is-a 736665006

Three more medication value sets are defined alongside these but go unreferenced by this resource's specs: Medication Not Given Reason (system-medication-not-given, is-a 242990004 + is-a 182895007), Additional Instruction (system-additional-instruction, is-a 419492006), and As Needed (system-as-needed-reason, is-a 404684003).

Resource specs (API schema)

All specs build on EMRResource (care/emr/resources/base.py), which provides serialize (DB object → read schema) and de_serialize (write schema → DB object), each with a perform_extra_serialization / perform_extra_deserialization hook. __exclude__ lists the fields those hooks handle manually rather than copying field-for-field.

Spec class Role Key fields / behaviour
BaseMedicationAdministrationSpec shared base All common fields: status, status_reason, category, medication, authored_on, occurrence_period_start, occurrence_period_end, recorded, encounter, request, performer, dosage, note. __exclude__ = ["patient", "encounter", "request", "administered_product"]
MedicationAdministrationSpec write · create None. Validates encounter and request exist; rejects medication + administered_product set together
MedicationAdministrationUpdateSpec write · update Narrow update schema: only status, note, occurrence_period_end. __exclude__ = ["patient", "encounter", "request"] — those are immutable after create
MedicationAdministrationReadSpec read · detail/list Extends base; adds audit fields created_by, updated_by, created_date, modified_date, and nested administered_product: dict
Dosage nested Shape of the dosage JSON field (see above)
MedicationAdministrationPerformer nested Element of the performer JSON list (see above)

Validation rules

  • Mutual exclusion (MedicationAdministrationSpec.validate_administered_product, model_validator(mode="after")): medication and administered_product cannot both be set.
  • Existence checks (field validators, create): encounter must reference an existing Encounter; request must reference an existing MedicationRequest; each performer.actor must reference an existing User.
  • Bound codings: medication, status_reason, and dosage.{site,route,method} are validated against their bound value sets; unknown codes raise.
  • Required on create: status, occurrence_period_start, encounter, request.

Server-maintained behaviour

MedicationAdministrationSpec.perform_extra_deserialization (create only, is_update == False):

  • Resolves encounter from the supplied external_id and sets obj.encounter.
  • Derives obj.patient from obj.encounter.patientpatient is never taken from the client.
  • Resolves request from its external_id and sets obj.request.
  • If administered_product is supplied, resolves the ProductKnowledge and sets obj.administered_product.

MedicationAdministrationReadSpec.perform_extra_serialization:

  • Sets id to external_id; flattens encounter and request to their external_ids.
  • Serializes administered_product (when present) via ProductKnowledgeReadSpec.
  • Adds created_by / updated_by via serialize_audit_users.

administered_product references the supply-side catalog rather than carrying a nested record:

administered_product → FK ProductKnowledge (nullable, CASCADE)
patient              → FK Patient (CASCADE)
encounter            → FK Encounter (nullable, CASCADE)
request              → FK MedicationRequest (nullable, CASCADE)

medication, dosage, status_reason, and performer are stored inline as JSONFields rather than in separate tables, mirroring the FHIR MedicationAdministration structure; their real shape comes from the resource specs above.

Methods & save behaviour

  • de_serialize(obj?) dumps the write schema with model_dump(exclude_defaults=True), so unset fields never overwrite existing values — the same path handles both create and update.
  • Audit and soft-delete fields (external_id, created_by, created_date, modified_date, deleted, etc.) are inherited from EMRBaseModel and maintained by the platform; clients never set them.

API integration notes

  • Write requests use MedicationAdministrationSpec (create) and MedicationAdministrationUpdateSpec (update); reads return MedicationAdministrationReadSpec. Field names mostly match the model; occurrence_period_start / occurrence_period_end map to the FHIR occurence[x] period.
  • Send coded fields (medication, status_reason, dosage.site/route/method) as Coding objects (system / code / display) drawn from the bound value sets — free strings and out-of-set codes are rejected.
  • status values use underscores (in_progress, not_done, on_hold, entered_in_error), not the FHIR hyphenated spellings.
  • Provide encounter and request as external_id UUIDs; patient is derived server-side from the encounter and must not be sent.
  • Set either medication or administered_product, never both. Use administered_product when a specific catalogued product was given, so the administration reconciles against inventory; use medication for a coded drug with no catalog product.
  • After create, only status, note, and occurrence_period_end are updatable; encounter, request, and patient are immutable.

Pages that link here: