MedicationStatement drug_exposure implemented primary

Patient self-reported medication events. Each MedicationStatement produces one drug_exposure row with drug_type_concept_id defaulting to 44787730 (Patient Self-Reported Medication). This is the only FHIR medication resource with a normative HL7 IG FML mapping. Dynamic type concept adjustment is possible based on basedOn/partOf references (omoponfhir behavior).

A FHIR instance converts to drug_exposure iff it validates against this profile.
Path Card Type Binding / Fixed Comment
MedicationStatement.status 1..*MS fhir/medication-statement-statusrequired
MedicationStatement.medication[x] 1..*MS CodeableConcept omop-drug-codesrequired
MedicationStatement.subject 1..1 Reference Required for drug_exposure.person_id.
MedicationStatement.effective[x] 1..1MS Required for drug_exposure.drug_exposure_start_date / _end_date. May be dateTime or Period.
ViewDefinition (Stage 1 flattener) omop-medicationstatement-drug-exposure
20 columns · resource MedicationStatement
column name FHIRPath type
id MedicationStatement.id id
drug_rxnorm MedicationStatement.medicationCodeableConcept.coding.where(system='http://www.nlm.nih.gov/research/umls/rxnorm').first().code code
drug_ndc MedicationStatement.medicationCodeableConcept.coding.where(system='http://hl7.org/fhir/sid/ndc').first().code code
drug_atc MedicationStatement.medicationCodeableConcept.coding.where(system='http://www.whocc.no/atc').first().code code
drug_snomed MedicationStatement.medicationCodeableConcept.coding.where(system='http://snomed.info/sct').first().code code
drug_text MedicationStatement.medicationCodeableConcept.text string
subject_id MedicationStatement.subject Reference(Patient)
drug_exposure_start_date MedicationStatement.effectiveDateTime dateTime
drug_exposure_start_datetime MedicationStatement.effectiveDateTime dateTime
drug_exposure_end_date MedicationStatement.effectivePeriod.end dateTime
drug_exposure_end_datetime MedicationStatement.effectivePeriod.end dateTime
verbatim_end_date MedicationStatement.effectivePeriod.end dateTime
stop_reason MedicationStatement.statusReason CodeableConcept
quantity MedicationStatement.dosage[].doseAndRate[].doseQuantity.value decimal
sig MedicationStatement.dosage[].text string
route MedicationStatement.dosage[].route CodeableConcept
route_text MedicationStatement.dosage[].route.text string
performer_id MedicationStatement.informationSource Reference(Practitioner)
encounter_id MedicationStatement.context Reference(Encounter)
dose_unit_text MedicationStatement.dosage[].doseAndRate[].doseQuantity.unit string
Implementation: src/mapper/medication-statement.ts

Fields (23)

  • drug_exposure_id integer · id
    PKrequired
    Surrogate key. HL7 IG FML leaves this as a commented-out TODO. omoponfhir uses IdMapping.getOMOPfromFHIR().
    2 sources ▾
  • person_id MedicationStatement.subject integer · Reference(Patient)
    FK→PERSONrequired
    Resolve Patient reference. HL7 IG FML leaves this as a commented-out TODO.
  • drug_concept_id MedicationStatement.medication[x] integer · CodeableConcept/Reference
    FK→CONCEPTrequired
    RxNorm / ATC / NDC mapped to OMOP standard concept. HL7 IG FML maps from medication.concept.coding.code. Placeholder: 0 when concept lookup unavailable.
  • drug_exposure_start_date MedicationStatement.effectiveDateTime | MedicationStatement.effectivePeriod.start | MedicationStatement.dateAsserted date · dateTime
    required
    transform:effectiveDateTime -> effectivePeriod.start -> dateAsserted (tertiary fallback)
    Tertiary fallback chain unique to MedicationStatement. omoponfhir falls back to new Date() instead of dateAsserted.
    2 sources ▾
  • drug_exposure_start_datetime MedicationStatement.effectiveDateTime | MedicationStatement.effectivePeriod.start | MedicationStatement.dateAsserted datetime · dateTime
    Full ISO datetime.
  • drug_exposure_end_date MedicationStatement.effectivePeriod.end date · dateTime
    required
    transform:effectivePeriod.end; fallback to start_date when effectiveDateTime is used (point in time) or period.end is absent
    When effectiveDateTime is used, end = start. When effectivePeriod has start but no end, end = start.
  • drug_exposure_end_datetime MedicationStatement.effectivePeriod.end datetime · dateTime
    Full ISO datetime. Null if no period end.
  • verbatim_end_date MedicationStatement.effectivePeriod.end date · dateTime
    Raw end date from source before any inference. HL7 IG FML maps effectivePeriod.end here. Most other implementations leave null.
    2 sources ▾
  • drug_type_concept_id constant integer
    FK→CONCEPTrequiredmap:drug_type=44787730
    Default 44787730 (Patient Self-Reported Medication). omoponfhir dynamically adjusts based on basedOn/partOf references. ETL-German uses 32817 (CLAIM). HL7 IG FML derives from category.coding.code.
    3 sources ▾
  • stop_reason MedicationStatement.statusReason varchar(20) · CodeableConcept
    Reason for discontinuation. omoponfhir truncates to 20 chars and only populates when status=stopped. HL7 IG FML maps from reason.concept.coding.code.
    2 sources ▾
  • refills integer
    Not applicable to MedicationStatement (MedicationRequest-only). Leave null.
  • quantity MedicationStatement.dosage[].doseAndRate[].doseQuantity.value float · decimal
    Dose amount per administration. ETL-German computes mean of Range when doseRange is used.
    2 sources ▾
  • days_supply integer
    Not directly available. Could be computed from period length / dosing frequency, but no reference implementation does this for MedicationStatement.
  • sig MedicationStatement.dosage[].text | MedicationStatement.dosage[].patientInstruction varchar(MAX) · string
    Free-text dosage instructions.
  • route_concept_id MedicationStatement.dosage[].route integer · CodeableConcept
    FK→CONCEPT
    SNOMED route code mapped to OMOP Route domain concept. omoponfhir performs full vocabulary lookup. ETL-German uses date-aware concept lookup. This project hardcodes null.
    2 sources ▾
  • route_source_value MedicationStatement.dosage[].route.text | MedicationStatement.dosage[].route.coding[0].display varchar(50) · string
    Raw route text. omoponfhir prefers route.text, falls back to coding[0].display.
  • lot_number varchar(50)
    Vaccine-only field; not applicable to MedicationStatement.
  • provider_id MedicationStatement.informationSource integer · Reference(Practitioner)
    FK→PROVIDER
    Reporter of the medication statement. omoponfhir filters to Practitioner-typed references only. ETL-German does not map provider for MedicationStatement.
    2 sources ▾
  • visit_occurrence_id MedicationStatement.context integer · Reference(Encounter)
    FK→VISIT_OCCURRENCE
    Encounter reference. R4 uses 'context'; renamed to 'encounter' in R5.
  • visit_detail_id integer
    FK→VISIT_DETAIL
    Not mapped. Null in all reviewed implementations.
  • drug_source_value MedicationStatement.medication[x].coding[best].code varchar(50) · code
    Best code by vocabulary priority. omoponfhir uses identifier.value as source value. ETL-German uses ATC code.
    2 sources ▾
  • drug_source_concept_id constant integer
    FK→CONCEPT=0
    Source vocabulary concept. Placeholder: 0.
  • dose_unit_source_value MedicationStatement.dosage[].doseAndRate[].doseQuantity.unit | MedicationStatement.dosage[].doseAndRate[].doseQuantity.code varchar(50) · string
    Raw dose unit string. omoponfhir prefers .code, falls back to .unit.

Vocabularies

drug_type

Source Display Concept ID Concept Name
(default) No basedOn / partOf reference 44787730 Patient Self-Reported Medication
basedOn -> MedicationRequest basedOn references MedicationRequest 38000177 Prescription written
partOf -> MedicationAdministration partOf references MedicationAdministration 38000179 Physician administered drug
partOf -> MedicationDispense partOf references MedicationDispense 38000175 Prescription dispensed in pharmacy

Edge Cases

status = entered-in-error
Skip -- do not create drug_exposure row. Consensus across all implementations.
status = stopped
omoponfhir populates stop_reason from statusReason and still creates the row. This project skips.
status = on-hold / intended / not-taken / unknown
This project skips. omoponfhir maps all statuses except entered-in-error.
effectiveDateTime (point in time)
Start and end date are the same. omoponfhir: setDrugExposureStartDate(date); setDrugExposureEndDate(date).
effectivePeriod with start but no end
End date = start date.
dateAsserted but no effective[x]
This project falls back to dateAsserted. omoponfhir sets new Date() (current time) if no date found.
basedOn references MedicationRequest
omoponfhir dynamically sets drug_type_concept_id to 38000177 (Prescription written). This project leaves at 44787730.
partOf references MedicationAdministration / MedicationDispense
omoponfhir dynamically sets drug_type_concept_id to 38000179 / 38000175 respectively. This project does not implement.
medicationReference to contained Medication
omoponfhir iterates contained[]. ETL-German pre-indexes via medication_id_map. This project skips (returns null).
Multiple dosage entries
This project takes first. ETL-German creates one drug_exposure per dosage entry (fan-out).
Multiple codings in medication[x]
This project uses selectBestCoding() by vocabulary priority. omoponfhir uses CodeableConceptUtil.searchConcept().
drug_source_value exceeds 50 chars
omoponfhir truncates medicationCodeableConcept.getText() to 50 chars. OMOP CDM field is varchar(50).
stop_reason exceeds 20 chars
omoponfhir truncates to 20. OMOP CDM field is varchar(20).

Reference Implementations