Skip to content

Commit

Permalink
Update US Core device profile and remove MedicationStatement.
Browse files Browse the repository at this point in the history
  • Loading branch information
jawalonoski committed Nov 21, 2019
1 parent ebd08c4 commit d215ebf
Showing 1 changed file with 19 additions and 127 deletions.
146 changes: 19 additions & 127 deletions src/main/java/org/mitre/synthea/export/FhirR4.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@
import org.hl7.fhir.r4.model.MedicationRequest;
import org.hl7.fhir.r4.model.MedicationRequest.MedicationRequestIntent;
import org.hl7.fhir.r4.model.MedicationRequest.MedicationRequestStatus;
import org.hl7.fhir.r4.model.MedicationStatement;
import org.hl7.fhir.r4.model.MedicationStatement.MedicationStatementStatus;
import org.hl7.fhir.r4.model.Meta;
import org.hl7.fhir.r4.model.Money;
import org.hl7.fhir.r4.model.Narrative;
Expand Down Expand Up @@ -273,12 +271,7 @@ public static Bundle convertToFHIR(Person person, long stopTime) {
}

for (Medication medication : encounter.medications) {
BundleEntryComponent medicationRequestEntry =
medicationRequest(person, personEntry, bundle, encounterEntry, medication);
if (USE_US_CORE_IG) {
medicationStatement(person, personEntry, bundle, encounterEntry, medication,
medicationRequestEntry);
}
medicationRequest(person, personEntry, bundle, encounterEntry, medication);
}

for (HealthRecord.Entry immunization : encounter.immunizations) {
Expand Down Expand Up @@ -1605,7 +1598,7 @@ private static BundleEntryComponent device(BundleEntryComponent personEntry, Bun
Device deviceResource = new Device();
if (USE_US_CORE_IG) {
Meta meta = new Meta();
meta.addProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-device");
meta.addProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-implantable-device");
deviceResource.setMeta(meta);
}
deviceResource.addUdiCarrier()
Expand Down Expand Up @@ -1747,6 +1740,23 @@ private static BundleEntryComponent medicationRequest(
: RXNORM_URI;
medicationResource.setMedication(mapCodeToCodeableConcept(code, system));

if (USE_US_CORE_IG && medication.administration) {
// Occasionally, rather than use medication codes, we want to use a Medication
// Resource. We only want to do this when we use US Core, to make sure we
// sometimes produce a resource for the us-core-medication profile, and the
// 'administration' flag is an arbitrary way to decide without flipping a coin.
org.hl7.fhir.r4.model.Medication drugResource =
new org.hl7.fhir.r4.model.Medication();
Meta meta = new Meta();
meta.addProfile(
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-medication");
drugResource.setMeta(meta);
drugResource.setCode(mapCodeToCodeableConcept(code, system));
drugResource.setStatus(MedicationStatus.ACTIVE);
BundleEntryComponent drugEntry = newEntry(bundle, drugResource);
medicationResource.setMedication(new Reference(drugEntry.getFullUrl()));
}

medicationResource.setAuthoredOn(new Date(medication.start));
medicationResource.setIntent(MedicationRequestIntent.ORDER);
org.hl7.fhir.r4.model.Encounter encounter =
Expand Down Expand Up @@ -1914,124 +1924,6 @@ private static BundleEntryComponent medicationAdministration(
private static final CodeableConcept PRESCRIPTION_OF_DRUG_CC =
mapCodeToCodeableConcept(PRESCRIPTION_OF_DRUG_CODE, SNOMED_URI);

/**
* Map the given Medication to a FHIR Medication and MedicationStatement resource,
* and add them to the given Bundle.
*
* @param person The person being prescribed medication
* @param personEntry The Entry for the Person
* @param bundle Bundle to add the Medication to
* @param encounterEntry Current Encounter entry
* @param medication The Medication
* @return The added Entry
*/
private static BundleEntryComponent medicationStatement(
Person person, BundleEntryComponent personEntry, Bundle bundle,
BundleEntryComponent encounterEntry, Medication medication,
BundleEntryComponent medicationRequestEntry) {

org.hl7.fhir.r4.model.Medication medicationResource =
new org.hl7.fhir.r4.model.Medication();
if (USE_US_CORE_IG) {
Meta meta = new Meta();
meta.addProfile(
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-medication");
medicationResource.setMeta(meta);
}
Code code = medication.codes.get(0);
String system = code.system.equals("SNOMED-CT")
? SNOMED_URI
: RXNORM_URI;
medicationResource.setCode(mapCodeToCodeableConcept(code, system));
medicationResource.setStatus(MedicationStatus.ACTIVE);
BundleEntryComponent medicationEntry = newEntry(bundle, medicationResource);

MedicationStatement medicationStatement = new MedicationStatement();
if (USE_US_CORE_IG) {
Meta meta = new Meta();
meta.addProfile(
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-medicationstatement");
medicationStatement.setMeta(meta);
}
medicationStatement.setSubject(new Reference(personEntry.getFullUrl()));
medicationStatement.setContext(new Reference(encounterEntry.getFullUrl()));
medicationStatement.setMedication(new Reference(medicationEntry.getFullUrl()));
medicationStatement.addDerivedFrom(new Reference(medicationRequestEntry.getFullUrl()));

if (medication.stop != 0L) {
Period period = new Period();
period.setStart(new Date(medication.start));
period.setEnd(new Date(medication.stop));
medicationStatement.setEffective(period);
medicationStatement.setStatus(MedicationStatementStatus.STOPPED);
} else {
medicationStatement.setEffective(new DateTimeType(new Date(medication.start)));
medicationStatement.setStatus(MedicationStatementStatus.ACTIVE);
}
medicationStatement.setDateAsserted(new Date(medication.start));

if (medication.reasons != null && !medication.reasons.isEmpty()) {
for (Code code1 : medication.reasons) {
medicationStatement.addReasonCode(mapCodeToCodeableConcept(code1, SNOMED_URI));
}
}

if (medication.prescriptionDetails != null) {
JsonObject rxInfo = medication.prescriptionDetails;
Dosage dosage = new Dosage();

dosage.setSequence(1);
// as_needed is true if present
dosage.setAsNeeded(new BooleanType(rxInfo.has("as_needed")));

// as_needed is true if present
if ((rxInfo.has("dosage")) && (!rxInfo.has("as_needed"))) {
Timing timing = new Timing();
TimingRepeatComponent timingRepeatComponent = new TimingRepeatComponent();
timingRepeatComponent.setFrequency(
rxInfo.get("dosage").getAsJsonObject().get("frequency").getAsInt());
timingRepeatComponent.setPeriod(
rxInfo.get("dosage").getAsJsonObject().get("period").getAsDouble());
timingRepeatComponent.setPeriodUnit(
convertUcumCode(rxInfo.get("dosage").getAsJsonObject().get("unit").getAsString()));
timing.setRepeat(timingRepeatComponent);
dosage.setTiming(timing);

Quantity dose = new SimpleQuantity().setValue(
rxInfo.get("dosage").getAsJsonObject().get("amount").getAsDouble());

DosageDoseAndRateComponent dosageDetails = new DosageDoseAndRateComponent();
dosageDetails.setType(new CodeableConcept().addCoding(
new Coding().setCode(DoseRateType.ORDERED.toCode())
.setSystem(DoseRateType.ORDERED.getSystem())
.setDisplay(DoseRateType.ORDERED.getDisplay())));
dosageDetails.setDose(dose);
List<DosageDoseAndRateComponent> details = new ArrayList<DosageDoseAndRateComponent>();
details.add(dosageDetails);
dosage.setDoseAndRate(details);

if (rxInfo.has("instructions")) {
for (JsonElement instructionElement : rxInfo.get("instructions").getAsJsonArray()) {
JsonObject instruction = instructionElement.getAsJsonObject();
Code instructionCode = new Code(
SNOMED_URI,
instruction.get("code").getAsString(),
instruction.get("display").getAsString()
);

dosage.addAdditionalInstruction(mapCodeToCodeableConcept(instructionCode, SNOMED_URI));
}
}
}

List<Dosage> dosages = new ArrayList<Dosage>();
dosages.add(dosage);
medicationStatement.setDosage(dosages);
}

return newEntry(bundle, medicationStatement);
}

/**
* Map the given Report to a FHIR DiagnosticReport resource, and add it to the given Bundle.
*
Expand Down

1 comment on commit d215ebf

@jawalonoski
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was there a discussion about removing MedicationStatement that I could catch up with?

MedicationStatement was dropped in the US Core update (see HL7 standards process).

In general, we prefer to use as little FHIR resources as possible where there might be duplicative information. I don't want to have a debate about the uses and meaning of all the Medication* FHIR resources, but generally speaking Synthea uses MedicationRequest for prescriptions and MedicationAdministration for administrations. When we use MedicationAdministration together with US Core we also produce the unadorned Medication resource.

If you'd like to continue this conversation, please create a new issue and take this out of general comments on commits.

Please sign in to comment.