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 Statement

From OHC Network Wiki
Revision as of 04:15, 5 July 2026 by Admin (talk | contribs) (OHC identity seed)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
referencemedicationsCARE 3.0+

A MedicationStatement records a medication the patient is taking, has taken, or intends to take, as reported by the patient, a relative, or a clinician rather than actively prescribed or dispensed. Reach for it when you're capturing a medication history rather than driving an order. It aligns with the FHIR MedicationStatement resource.

The Django model stores medication and effective_period as opaque JSONFields. Their real structure comes from the Pydantic resource specs in care/emr/resources/medication/statement/, which define the enums, nested JSON shapes, validation, the value-set binding on medication, and the read/write API schemas. This page covers both layers.

Source:

Models

Model Purpose
MedicationStatement A record of a medication the patient is taking, has taken, or intends to take — as reported rather than actively prescribed

MedicationStatement extends EMRBaseModel, the shared Care EMR base that supplies external_id, audit fields created_by/updated_by, created_date/modified_date, history/meta JSON, and soft-delete semantics.

MedicationStatement fields

Type is the Django storage type. Spec shape is the structured shape the Pydantic resource spec enforces when reading and writing over the API.

Statement details

Field Type Spec shape Notes
status CharField(100) MedicationStatementStatus enum
reason CharField(100) str
medication JSONField (default=dict) Coding bound to the system-medication value set
information_source CharField(100) MedicationStatementInformationSourceType enum
effective_period JSONField (default=dict) PeriodSpec
dosage_text TextField str
note TextField str

Relationships

Field Type Notes
patient FK → Patient on_delete=CASCADE. The patient the statement is about. Derived server-side from the encounter — never accepted from clients.
encounter FK → Encounter on_delete=CASCADE. The encounter the statement was recorded in. Supplied as a UUID on create.
patient   → FK Patient   (CASCADE)
encounter → FK Encounter (CASCADE)

Deleting a patient or encounter deletes its medication statements.

Enum values

MedicationStatementStatus values

MedicationStatementStatus(str, Enum) in spec.py, bound to status.

Value Meaning
active The medication is being taken
on_hold Taking has been paused
completed The course has finished
stopped The medication was stopped
unknown Status is not known
entered_in_error The record was entered in error
not_taken The patient is not taking the medication
intended The patient intends to take the medication

MedicationStatementInformationSourceType values

MedicationStatementInformationSourceType(str, Enum) in spec.py, bound to information_source.

Value Meaning
related_person A relative or related person reported it
practitioner A clinician reported it
patient The patient self-reported it

Nested JSON shapes

Coding shape

medication is stored as JSON but typed as a single Coding (from care/emr/resources/common/coding.py), not a CodeableConcept. The spec sets extra="forbid", so unrecognized keys are rejected.

Field Type Notes
system str Code system URI (e.g. http://snomed.info/sct)
version str Code-system version
code str Required. Validated against the bound value set
display str Human-readable label

Bound value set

medication is declared as ValueSetBoundCoding[CARE_MEDICATION_VALUESET.slug]. On write, code is validated against the system-medication value set ([https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/medication/valueset/medication.py medication.py]), which includes SNOMED CT concepts under the constraint << 763158003 |Medicinal product|. Any code outside the set is rejected.

The care/emr/resources/medication/valueset/ directory holds further value sets for other medication resources (route, body site, administration method, additional instruction, as-needed reason, medication-not-given reason). MedicationStatement binds only medicationsystem-medication.

PeriodSpec shape

effective_period is stored as JSON but typed as PeriodSpec (from care/emr/resources/base.py).

Field Type Notes
start datetime Must be timezone-aware if present; naive datetimes are rejected
end datetime Must be timezone-aware if present

validate_period (mode after) rejects a naive start/end and requires start to be no greater than end.

Resource specs (API schema)

Every spec subclasses EMRResource (care/emr/resources/base.py), which provides serialize (DB object → pydantic) and de_serialize (pydantic → DB object). __model__ = MedicationStatement, and __exclude__ = ["patient", "encounter"] holds those two fields out of the generic field copy so the extra hooks set them instead.

Spec class Role Fields exposed
BaseMedicationStatementSpec shared base id, status, reason, medication, dosage_text, effective_period, encounter, information_source, note
MedicationStatementSpec write · create Inherits BaseMedicationStatementSpec; adds encounter existence validation + extra deserialization
MedicationStatementUpdateSpec write · update status, effective_period, note only
MedicationStatementReadSpec read · list & detail Inherits base; adds created_by, updated_by (UserSpec), created_date, modified_date

What the specs validate and maintain on your behalf:

  • encounter must existMedicationStatementSpec.validate_encounter_exists, a field_validator on encounter, raises "Encounter not found" unless an Encounter with that external_id exists.
  • patient is derived server-sideMedicationStatementSpec.perform_extra_deserialization runs only on create (is_update false): it resolves the Encounter from the supplied UUID and sets obj.patient = obj.encounter.patient. Clients never send patient.
  • Updates are narrowMedicationStatementUpdateSpec accepts only status, effective_period, and note. medication, reason, dosage_text, information_source, and encounter can't be changed through it.
  • Read serializationMedicationStatementReadSpec.perform_extra_serialization sets id = obj.external_id, encounter = obj.encounter.external_id, and serializes audit users via serialize_audit_users (created_by/updated_by as UserSpec).
  • medication value-set check — runs at validation time against Coding.code (see Bound value set).
  • effective_period tz-awareness and ordering — enforced by PeriodSpec (see PeriodSpec shape).

There is no status_history. status is a single current value, not an appended log.

Methods & save behaviour

  • From EMRBaseModel: external_id (UUID), audit fields, soft delete. Deletes are soft — a removed statement stays in the table with deleted=True and is hidden by the default manager.
  • Create flow: client sends MedicationStatementSpecde_serialize copies scalar/JSON fields → perform_extra_deserialization resolves encounter and back-fills patient → model saved.
  • Read flow: MedicationStatementReadSpec.serialize(obj) copies fields, then perform_extra_serialization injects id, encounter (as UUIDs), and audit users.

API integration notes

  • Exposed through Care's REST API, aligned with FHIR MedicationStatement. Use the spec field names above for payloads.
  • medication is a single SNOMED CT Coding object whose code must be in the system-medication value set — not a free CodeableConcept, and not a scalar string.
  • effective_period datetimes must be timezone-aware and ordered (start ≤ end).
  • encounter goes in as a UUID; patient is derived from it server-side and must not be sent.
  • Updates flow through MedicationStatementUpdateSpec and can touch only status, effective_period, and note.
  • information_source is what separates a self-reported or third-party statement from an actively managed prescription (MedicationRequest).
  • external_id (UUID), created_by/updated_by, created_date/modified_date, history, and meta are platform-maintained — don't set them from clients.

Pages that link here: