Medication Dispense Data Model
We will need to add a new "medication_dispense" table (and companion domain object MedicationDispense) modeled after the MedicationDispense FHIR resource:
https://www.hl7.org/fhir/medicationdispense.html#resource
The domain object should extend BaseOpenmrsData and provide the standard audit visits of that class.
Beyond that, the table/domain object should contain the fields below. (Note the "Phase 1" column, which denotes if this field should be added in the initial implementation. Fields with a "no" here are fields that will be delegated to a later phase. I have grouped those fields to the bottom of the table)
"Related Order/Drug Order Property" is a reference to the related fields on a DrugOrder domain object. (ie, theoretically, if you created a MedicationDispense from DrugOrder without any modifications, the values in these fields could be copied from the Drug Order to the MedicationDispense)
When we create the new domain object, we should make sure that for each property we add a comment noting which FHIR field it maps to (perhaps even with a link) so that we remember the reasoning behind each field.
Column Name | Column Datatype | Required | Foreign Key | Java Variable Name | Java Variable Class | Mapped FHIR Field | Related Order/Drug Order Property | Phase One? | Notes |
---|---|---|---|---|---|---|---|---|---|
concept_id | int | Yes | concept.concept_id | concept | Concept | medication.medicationCodeableConcept | Order.Concept | Yes | |
drug_id | int | No | drug.drug_id | drug | Drug | medication.reference(Medication) | DrugOrder.drug | Yes | May need to clarify how this actually gets transformed in FHIR |
patient_id | int | Yes | patient.patient_id | patient | Patient | subject | Patient | Yes | |
location_id | int | No | location.location_id | location | Location | location | N/A | Yes | where the dispensed event occurred |
encounter_id | int | No | encounter.encounter_id | encounter | Encounter | context | N/A | Yes | encounter when the dispensing event occurred |
provider_id | int | No | provider.provider_id | provider | Provider | performer.actor | N/A_ | Yes | Note that FHIR provides support for 0..x "performers" and each performer may have a "performer.function" where "function" is a codeable concept and reflects a role like "packager"or "checker"; we will start with support for just a single 0..1 "provider" |
drug_order_id | int | No | drug_order.drug_order_id | drugOrder | DrugOrder | authorizingPrescription | Order.orderId | Yes | the drug order that led to this dispensing event; note that authorizing prescription maps to a "MedicationRequest" FHIR resource |
status | int | Yes | status | Concept | status | N/A | Yes | preparation | in-progress | cancelled | on-hold | completed | entered-in-error | stopped | declined | unknown (see: https://www.hl7.org/fhir/valueset-medicationdispense-status.html) | |
statusReason | int | No | concept.concept_id | statusReason | Concept | statusReason.statusReasonCodeableConcept | N/A | Yes | For allowed coded answers, see: https://www.hl7.org/fhir/valueset-medicationdispense-status-reason.html Note that these include things like "Stock Out" which we will likely be building some business logic around them. |
type | int | No | concept.concept_id | type | Concept | type.codeableConcept | N/A | Yes | For potential example concepts, see: https://www.hl7.org/fhir/v3/ActPharmacySupplyType/vs.html Note that these include things like "Refill" and "Partial Fill" which we will likely be building some business logic around them. |
quantity | double | No | quantity | Double | quantity.value | DrugOrder.quantity | Yes | Not required by FHIR | |
quantity_units | int | No | concept.concept_id | quantityUnits | Concept | quantity.unit and/or quanity.code | DrugOrder.quantityUnits | Yes | See: |
dose | double | No | dose | Double | dosageInstructions.doseAndRate.dose.doseQuantity | DrugOrder.dose | Yes | ||
dose_units | int | No | concept.concept_id | doseUnits | int | DosageInstructions.doseAndRate.dose.Quantity.unit and/or code | DrugOrder.doseUnits | Yes | See: |
route | int | No | concept.concept_id | route | int | DosageInstructions.route | DrugOrder.route | Yes | |
frequency | int | No | order_frequency.order_frequency_id | frequency | int | DosageInstructions.timing.repeat.frequency DosageInstructions.timing.repeat.period DosageInstructions.timing.repeat.periodUnit | DrugOrder.frequency | Yes | https://build.fhir.org/datatypes.html#Timing Note that we will continue to map this as a single "frequency" concept, although it doesn't map well to FHIR, to make consistent with DrugOrder in OpenMRS |
as_needed | tinyint(1) | No | asNeeded | Boolean | DosageInstructions.AsNeeded.asNeededBoolean | DrugOrder.asNeeded | Yes | ||
dosing_instructions | text | No | dosingInstructions | String | DosageInstructions.patientInstructions | DrugOrder.dosingInstructions_ | Yes | ||
date_prepared | datetime | No | datePrepared | Datetime | whenPrepared | N/A | Yes | From FHIR: "When product was packaged and reviewed" I used "datePrepared" instead of "whenPrepared" because it seemed more in-line with OpenMRS conventions. Happy to debate. | |
date_handed_over | datetime | No | dateHandedOver | Datetime | whenHandedOver | N/A | Yes | From FHIR: "When product was given out" I used "dateHandedOver" instead of "whenHandedOver" because it seemed more in-line with OpenMRS conventions. Happy to debate. | |
note | varchar(1024) | No | note | String | note.text | N/A | Yes | FHIR supports 0..n but we will only support 0..1 for starters? It also supports the author and the time via the "annotation" type. Should this be a clob, see comment from Ian below | |
was_substituted | tinyint(1) | No | wasSubstituted | Boolean | substitution.wasSubstituted | N/A | Yes | True/false whether a substitution was made during this dispense event | |
substitution_type_id | int | No | concept.concept_id | substitutionType | Concept | substitution.type | N/A | Yes | For valid FHIR concepts, see: https://www.hl7.org/fhir/v3/ActSubstanceAdminSubstitutionCode/vs.html We also could punt on building this in Phase 1, and make the distinction between enum and concept when we have an actual use case. Let @Andrew Kanter know if we need these as concepts. |
substitution_reason_id | int | No | concept.concept_id | substitutionReason | Concept | substitution.reason | N/A | Yes | For valid FHIR concepts, see: https://www.hl7.org/fhir/v3/SubstanceAdminSubstitutionReason/vs.html We also could punt on building this in Phase 1, and make the distinction between enum and concept when we have an actual use case. Let @Andrew Kanter know if we need these as concepts. |
substitution.responsibleParty | N/A | No | |||||||
days_supply | int | No | daysSupply | int | daysSupply.value | N/A | No | From FHIR: The amount of medication expressed as a timing amount. It might be best to drop support for this an only support quantity, at least at a first pass (technically quantity can have a units of days) | |
category_id | int | No | concept.concept_id | category | Concept | category | N/A | No | ie, Inpatient, Outpatient, Discharge, Community For valid FHIR concepts, see: https://www.hl7.org/fhir/valueset-medicationdispense-category.html Let @Andrew Kanter know if we need these as concepts. |
destination_id | int | No | location.location_id | destination | Location | destination | N/A | No | From FHIR: "Where the medication was sent". Do we want this for "phase 1"? |
receiver_id | int | No | person.person_id | receiver | Person | receiver | N/A | No | From FHIR: "Who collected the medication" Do we want this for "phase 1"? FHIR supports a receiver of a "Practioner" or "Patient", so "Person" is the only current way in OpenMRS to support this (0...n in FHIR, but we currently only support 0..1) |
identifier | No | External identifier | |||||||
partOf | No | Event that dispense is a part of (maps to a FHIR Procedure) | |||||||
supportingInformation | No | ||||||||
detectedIssue | No | ||||||||
eventHistory | No |