Search in sources :

Example 76 with Encounter

use of org.mitre.synthea.world.concepts.HealthRecord.Encounter in project synthea by synthetichealth.

the class FhirR4 method explanationOfBenefit.

/**
 * Create an explanation of benefit resource for each claim, detailing insurance
 * information.
 *
 * @param personEntry Entry for the person
 * @param bundle The Bundle to add to
 * @param encounterEntry The current Encounter
 * @param claimEntry the Claim object
 * @param person the person the health record belongs to
 * @param encounter the current Encounter as an object
 * @return the added entry
 */
private static BundleEntryComponent explanationOfBenefit(BundleEntryComponent personEntry, Bundle bundle, BundleEntryComponent encounterEntry, Person person, BundleEntryComponent claimEntry, Encounter encounter) {
    ExplanationOfBenefit eob = new ExplanationOfBenefit();
    eob.setStatus(org.hl7.fhir.r4.model.ExplanationOfBenefit.ExplanationOfBenefitStatus.ACTIVE);
    eob.setType(new CodeableConcept().addCoding(new Coding().setSystem("http://terminology.hl7.org/CodeSystem/claim-type").setCode("professional").setDisplay("Professional")));
    eob.setUse(Use.CLAIM);
    eob.setOutcome(RemittanceOutcome.COMPLETE);
    org.hl7.fhir.r4.model.Encounter encounterResource = (org.hl7.fhir.r4.model.Encounter) encounterEntry.getResource();
    // according to CMS guidelines claims have 12 months to be
    // billed, so we set the billable period to 1 year after
    // services have ended (the encounter ends).
    Calendar cal = Calendar.getInstance();
    cal.setTime(encounterResource.getPeriod().getEnd());
    cal.add(Calendar.YEAR, 1);
    Period billablePeriod = new Period().setStart(encounterResource.getPeriod().getEnd()).setEnd(cal.getTime());
    eob.setBillablePeriod(billablePeriod);
    // cost is hardcoded to be USD in claim so this should be fine as well
    Money totalCost = new Money();
    totalCost.setCurrency("USD");
    totalCost.setValue(encounter.claim.getTotalClaimCost());
    TotalComponent total = eob.addTotal();
    total.setAmount(totalCost);
    Code submitted = new Code("http://terminology.hl7.org/CodeSystem/adjudication", "submitted", "Submitted Amount");
    total.setCategory(mapCodeToCodeableConcept(submitted, "http://terminology.hl7.org/CodeSystem/adjudication"));
    // Set References
    eob.setPatient(new Reference(personEntry.getFullUrl()));
    if (USE_US_CORE_IG) {
        eob.setFacility(encounterResource.getLocationFirstRep().getLocation());
    }
    ServiceRequest referral = (ServiceRequest) new ServiceRequest().setStatus(ServiceRequest.ServiceRequestStatus.COMPLETED).setIntent(ServiceRequest.ServiceRequestIntent.ORDER).setSubject(new Reference(personEntry.getFullUrl())).setId("referral");
    CodeableConcept primaryCareRole = new CodeableConcept().addCoding(new Coding().setCode("primary").setSystem("http://terminology.hl7.org/CodeSystem/claimcareteamrole").setDisplay("Primary Care Practitioner"));
    Reference providerReference = new Reference().setDisplay("Unknown");
    if (encounter.clinician != null) {
        String practitionerFullUrl = TRANSACTION_BUNDLE ? ExportHelper.buildFhirNpiSearchUrl(encounter.clinician) : findPractitioner(encounter.clinician, bundle);
        if (practitionerFullUrl != null) {
            providerReference = new Reference(practitionerFullUrl);
        }
    } else if (encounter.provider != null) {
        String providerUrl = TRANSACTION_BUNDLE ? ExportHelper.buildFhirSearchUrl("Location", encounter.provider.getResourceLocationID()) : findProviderUrl(encounter.provider, bundle);
        if (providerUrl != null) {
            providerReference = new Reference(providerUrl);
        }
    }
    eob.setProvider(providerReference);
    eob.addCareTeam(new ExplanationOfBenefit.CareTeamComponent().setSequence(1).setProvider(providerReference).setRole(primaryCareRole));
    referral.setRequester(providerReference);
    referral.addPerformer(providerReference);
    eob.addContained(referral);
    eob.setReferral(new Reference().setReference("#referral"));
    // Get the insurance info at the time that the encounter occurred.
    Payer payer = encounter.claim.payer;
    Coverage coverage = new Coverage();
    coverage.setId("coverage");
    coverage.setStatus(CoverageStatus.ACTIVE);
    coverage.setType(new CodeableConcept().setText(payer.getName()));
    coverage.setBeneficiary(new Reference(personEntry.getFullUrl()));
    coverage.addPayor(new Reference().setDisplay(payer.getName()));
    eob.addContained(coverage);
    ExplanationOfBenefit.InsuranceComponent insuranceComponent = new ExplanationOfBenefit.InsuranceComponent();
    insuranceComponent.setFocal(true);
    insuranceComponent.setCoverage(new Reference("#coverage").setDisplay(payer.getName()));
    eob.addInsurance(insuranceComponent);
    eob.setInsurer(new Reference().setDisplay(payer.getName()));
    org.hl7.fhir.r4.model.Claim claim = (org.hl7.fhir.r4.model.Claim) claimEntry.getResource();
    eob.addIdentifier().setSystem("https://bluebutton.cms.gov/resources/variables/clm_id").setValue(claim.getId());
    // Hardcoded group id
    eob.addIdentifier().setSystem("https://bluebutton.cms.gov/resources/identifier/claim-group").setValue("99999999999");
    eob.setClaim(new Reference().setReference(claimEntry.getFullUrl()));
    eob.setCreated(encounterResource.getPeriod().getEnd());
    eob.setType(claim.getType());
    List<ExplanationOfBenefit.DiagnosisComponent> eobDiag = new ArrayList<>();
    for (org.hl7.fhir.r4.model.Claim.DiagnosisComponent claimDiagnosis : claim.getDiagnosis()) {
        ExplanationOfBenefit.DiagnosisComponent diagnosisComponent = new ExplanationOfBenefit.DiagnosisComponent();
        diagnosisComponent.setDiagnosis(claimDiagnosis.getDiagnosis());
        diagnosisComponent.getType().add(new CodeableConcept().addCoding(new Coding().setCode("principal").setSystem("http://terminology.hl7.org/CodeSystem/ex-diagnosistype")));
        diagnosisComponent.setSequence(claimDiagnosis.getSequence());
        diagnosisComponent.setPackageCode(claimDiagnosis.getPackageCode());
        eobDiag.add(diagnosisComponent);
    }
    eob.setDiagnosis(eobDiag);
    List<ExplanationOfBenefit.ProcedureComponent> eobProc = new ArrayList<>();
    for (ProcedureComponent proc : claim.getProcedure()) {
        ExplanationOfBenefit.ProcedureComponent p = new ExplanationOfBenefit.ProcedureComponent();
        p.setDate(proc.getDate());
        p.setSequence(proc.getSequence());
        p.setProcedure(proc.getProcedure());
    }
    eob.setProcedure(eobProc);
    List<ExplanationOfBenefit.ItemComponent> eobItem = new ArrayList<>();
    double totalPayment = 0;
    // Get all the items info from the claim
    for (ItemComponent item : claim.getItem()) {
        ExplanationOfBenefit.ItemComponent itemComponent = new ExplanationOfBenefit.ItemComponent();
        itemComponent.setSequence(item.getSequence());
        itemComponent.setQuantity(item.getQuantity());
        itemComponent.setUnitPrice(item.getUnitPrice());
        itemComponent.setCareTeamSequence(item.getCareTeamSequence());
        itemComponent.setDiagnosisSequence(item.getDiagnosisSequence());
        itemComponent.setInformationSequence(item.getInformationSequence());
        itemComponent.setNet(item.getNet());
        itemComponent.setEncounter(item.getEncounter());
        itemComponent.setServiced(encounterResource.getPeriod());
        itemComponent.setCategory(new CodeableConcept().addCoding(new Coding().setSystem("https://bluebutton.cms.gov/resources/variables/line_cms_type_srvc_cd").setCode("1").setDisplay("Medical care")));
        itemComponent.setProductOrService(item.getProductOrService());
        // Location of service, can use switch statement based on
        // encounter type
        String code;
        String display;
        CodeableConcept location = new CodeableConcept();
        EncounterType encounterType = EncounterType.fromString(encounter.type);
        switch(encounterType) {
            case AMBULATORY:
                code = "21";
                display = "Inpatient Hospital";
                break;
            case EMERGENCY:
                code = "20";
                display = "Urgent Care Facility";
                break;
            case INPATIENT:
                code = "21";
                display = "Inpatient Hospital";
                break;
            case URGENTCARE:
                code = "20";
                display = "Urgent Care Facility";
                break;
            case WELLNESS:
                code = "19";
                display = "Off Campus-Outpatient Hospital";
                break;
            default:
                code = "21";
                display = "Inpatient Hospital";
        }
        location.addCoding().setCode(code).setSystem("http://terminology.hl7.org/CodeSystem/ex-serviceplace").setDisplay(display);
        itemComponent.setLocation(location);
        // Adjudication
        if (item.hasNet()) {
            // Assume that the patient has already paid deductible and
            // has 20/80 coinsurance
            ExplanationOfBenefit.AdjudicationComponent coinsuranceAmount = new ExplanationOfBenefit.AdjudicationComponent();
            coinsuranceAmount.getCategory().getCoding().add(new Coding().setCode("https://bluebutton.cms.gov/resources/variables/line_coinsrnc_amt").setSystem("https://bluebutton.cms.gov/resources/codesystem/adjudication").setDisplay("Line Beneficiary Coinsurance Amount"));
            coinsuranceAmount.getAmount().setValue(// 20% coinsurance
            0.2 * item.getNet().getValue().doubleValue()).setCurrency("USD");
            ExplanationOfBenefit.AdjudicationComponent lineProviderAmount = new ExplanationOfBenefit.AdjudicationComponent();
            lineProviderAmount.getCategory().getCoding().add(new Coding().setCode("https://bluebutton.cms.gov/resources/variables/line_prvdr_pmt_amt").setSystem("https://bluebutton.cms.gov/resources/codesystem/adjudication").setDisplay("Line Provider Payment Amount"));
            lineProviderAmount.getAmount().setValue(0.8 * item.getNet().getValue().doubleValue()).setCurrency("USD");
            // assume the allowed and submitted amounts are the same for now
            ExplanationOfBenefit.AdjudicationComponent submittedAmount = new ExplanationOfBenefit.AdjudicationComponent();
            submittedAmount.getCategory().getCoding().add(new Coding().setCode("https://bluebutton.cms.gov/resources/variables/line_sbmtd_chrg_amt").setSystem("https://bluebutton.cms.gov/resources/codesystem/adjudication").setDisplay("Line Submitted Charge Amount"));
            submittedAmount.getAmount().setValue(item.getNet().getValue()).setCurrency("USD");
            ExplanationOfBenefit.AdjudicationComponent allowedAmount = new ExplanationOfBenefit.AdjudicationComponent();
            allowedAmount.getCategory().getCoding().add(new Coding().setCode("https://bluebutton.cms.gov/resources/variables/line_alowd_chrg_amt").setSystem("https://bluebutton.cms.gov/resources/codesystem/adjudication").setDisplay("Line Allowed Charge Amount"));
            allowedAmount.getAmount().setValue(item.getNet().getValue()).setCurrency("USD");
            ExplanationOfBenefit.AdjudicationComponent indicatorCode = new ExplanationOfBenefit.AdjudicationComponent();
            indicatorCode.getCategory().getCoding().add(new Coding().setCode("https://bluebutton.cms.gov/resources/variables/line_prcsg_ind_cd").setSystem("https://bluebutton.cms.gov/resources/codesystem/adjudication").setDisplay("Line Processing Indicator Code"));
            // assume deductible is 0
            ExplanationOfBenefit.AdjudicationComponent deductibleAmount = new ExplanationOfBenefit.AdjudicationComponent();
            deductibleAmount.getCategory().getCoding().add(new Coding().setCode("https://bluebutton.cms.gov/resources/variables/line_bene_ptb_ddctbl_amt").setSystem("https://bluebutton.cms.gov/resources/codesystem/adjudication").setDisplay("Line Beneficiary Part B Deductible Amount"));
            deductibleAmount.getAmount().setValue(0).setCurrency("USD");
            List<ExplanationOfBenefit.AdjudicationComponent> adjudicationComponents = new ArrayList<>();
            adjudicationComponents.add(coinsuranceAmount);
            adjudicationComponents.add(lineProviderAmount);
            adjudicationComponents.add(submittedAmount);
            adjudicationComponents.add(allowedAmount);
            adjudicationComponents.add(deductibleAmount);
            adjudicationComponents.add(indicatorCode);
            itemComponent.setAdjudication(adjudicationComponents);
            // the total payment is what the insurance ends up paying
            totalPayment += 0.8 * item.getNet().getValue().doubleValue();
        }
        eobItem.add(itemComponent);
    }
    eob.setItem(eobItem);
    // This will throw a validation error no matter what.  The
    // payment section is required, and it requires a value.
    // The validator will complain that if there is a value, the payment
    // needs a code, but it will also complain if there is a code.
    // There is no way to resolve this error.
    Money payment = new Money();
    payment.setValue(totalPayment).setCurrency("USD");
    eob.setPayment(new ExplanationOfBenefit.PaymentComponent().setAmount(payment));
    return newEntry(person, bundle, eob);
}
Also used : TotalComponent(org.hl7.fhir.r4.model.ExplanationOfBenefit.TotalComponent) DiagnosisComponent(org.hl7.fhir.r4.model.Claim.DiagnosisComponent) ArrayList(java.util.ArrayList) ExplanationOfBenefit(org.hl7.fhir.r4.model.ExplanationOfBenefit) ProcedureComponent(org.hl7.fhir.r4.model.Claim.ProcedureComponent) Money(org.hl7.fhir.r4.model.Money) Coding(org.hl7.fhir.r4.model.Coding) SupplyDeliverySuppliedItemComponent(org.hl7.fhir.r4.model.SupplyDelivery.SupplyDeliverySuppliedItemComponent) ItemComponent(org.hl7.fhir.r4.model.Claim.ItemComponent) DiagnosisComponent(org.hl7.fhir.r4.model.Claim.DiagnosisComponent) Encounter(org.mitre.synthea.world.concepts.HealthRecord.Encounter) Payer(org.mitre.synthea.world.agents.Payer) Reference(org.hl7.fhir.r4.model.Reference) DocumentReference(org.hl7.fhir.r4.model.DocumentReference) Calendar(java.util.Calendar) Period(org.hl7.fhir.r4.model.Period) Coverage(org.hl7.fhir.r4.model.Coverage) InsuranceComponent(org.hl7.fhir.r4.model.Claim.InsuranceComponent) Code(org.mitre.synthea.world.concepts.HealthRecord.Code) ServiceRequest(org.hl7.fhir.r4.model.ServiceRequest) EncounterType(org.mitre.synthea.world.concepts.HealthRecord.EncounterType) Claim(org.mitre.synthea.world.concepts.Claim) CodeableConcept(org.hl7.fhir.r4.model.CodeableConcept)

Example 77 with Encounter

use of org.mitre.synthea.world.concepts.HealthRecord.Encounter in project synthea by synthetichealth.

the class FhirR4 method medicationClaim.

/**
 * Create an entry for the given Claim, which references a Medication.
 *
 * @param person         The person being prescribed medication
 * @param personEntry     Entry for the person
 * @param bundle          The Bundle to add to
 * @param encounterEntry  The current Encounter
 * @param claim           the Claim object
 * @param medicationEntry The Entry for the Medication object, previously created
 * @return the added Entry
 */
private static BundleEntryComponent medicationClaim(Person person, BundleEntryComponent personEntry, Bundle bundle, BundleEntryComponent encounterEntry, Claim claim, BundleEntryComponent medicationEntry) {
    org.hl7.fhir.r4.model.Claim claimResource = new org.hl7.fhir.r4.model.Claim();
    org.hl7.fhir.r4.model.Encounter encounterResource = (org.hl7.fhir.r4.model.Encounter) encounterEntry.getResource();
    claimResource.setStatus(ClaimStatus.ACTIVE);
    CodeableConcept type = new CodeableConcept();
    type.getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/claim-type").setCode("pharmacy");
    claimResource.setType(type);
    claimResource.setUse(org.hl7.fhir.r4.model.Claim.Use.CLAIM);
    // Get the insurance info at the time that the encounter occurred.
    InsuranceComponent insuranceComponent = new InsuranceComponent();
    insuranceComponent.setSequence(1);
    insuranceComponent.setFocal(true);
    insuranceComponent.setCoverage(new Reference().setDisplay(claim.payer.getName()));
    claimResource.addInsurance(insuranceComponent);
    // duration of encounter
    claimResource.setBillablePeriod(encounterResource.getPeriod());
    claimResource.setCreated(encounterResource.getPeriod().getEnd());
    claimResource.setPatient(new Reference(personEntry.getFullUrl()));
    claimResource.setProvider(encounterResource.getServiceProvider());
    // set the required priority
    CodeableConcept priority = new CodeableConcept();
    priority.getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/processpriority").setCode("normal");
    claimResource.setPriority(priority);
    // add item for encounter
    claimResource.addItem(new ItemComponent(new PositiveIntType(1), encounterResource.getTypeFirstRep()).addEncounter(new Reference(encounterEntry.getFullUrl())));
    // add prescription.
    claimResource.setPrescription(new Reference(medicationEntry.getFullUrl()));
    Money moneyResource = new Money();
    moneyResource.setValue(claim.getTotalClaimCost());
    moneyResource.setCurrency("USD");
    claimResource.setTotal(moneyResource);
    return newEntry(person, bundle, claimResource);
}
Also used : Reference(org.hl7.fhir.r4.model.Reference) DocumentReference(org.hl7.fhir.r4.model.DocumentReference) InsuranceComponent(org.hl7.fhir.r4.model.Claim.InsuranceComponent) PositiveIntType(org.hl7.fhir.r4.model.PositiveIntType) Money(org.hl7.fhir.r4.model.Money) SupplyDeliverySuppliedItemComponent(org.hl7.fhir.r4.model.SupplyDelivery.SupplyDeliverySuppliedItemComponent) ItemComponent(org.hl7.fhir.r4.model.Claim.ItemComponent) Encounter(org.mitre.synthea.world.concepts.HealthRecord.Encounter) Claim(org.mitre.synthea.world.concepts.Claim) CodeableConcept(org.hl7.fhir.r4.model.CodeableConcept)

Example 78 with Encounter

use of org.mitre.synthea.world.concepts.HealthRecord.Encounter in project synthea by synthetichealth.

the class FhirR4 method procedure.

/**
 * Map the given Procedure into a FHIR Procedure resource, and add it to the given Bundle.
 *
 * @param rand           Source of randomness to use when generating ids etc
 * @param personEntry    The Person entry
 * @param bundle         Bundle to add to
 * @param encounterEntry The current Encounter entry
 * @param procedure      The Procedure
 * @return The added Entry
 */
private static BundleEntryComponent procedure(RandomNumberGenerator rand, BundleEntryComponent personEntry, Bundle bundle, BundleEntryComponent encounterEntry, Procedure procedure) {
    org.hl7.fhir.r4.model.Procedure procedureResource = new org.hl7.fhir.r4.model.Procedure();
    if (USE_US_CORE_IG) {
        Meta meta = new Meta();
        meta.addProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-procedure");
        procedureResource.setMeta(meta);
    }
    procedureResource.setStatus(ProcedureStatus.COMPLETED);
    procedureResource.setSubject(new Reference(personEntry.getFullUrl()));
    procedureResource.setEncounter(new Reference(encounterEntry.getFullUrl()));
    if (USE_US_CORE_IG) {
        org.hl7.fhir.r4.model.Encounter encounterResource = (org.hl7.fhir.r4.model.Encounter) encounterEntry.getResource();
        procedureResource.setLocation(encounterResource.getLocationFirstRep().getLocation());
    }
    Code code = procedure.codes.get(0);
    CodeableConcept procCode = mapCodeToCodeableConcept(code, SNOMED_URI);
    procedureResource.setCode(procCode);
    if (procedure.stop != 0L) {
        Date startDate = new Date(procedure.start);
        Date endDate = new Date(procedure.stop);
        procedureResource.setPerformed(new Period().setStart(startDate).setEnd(endDate));
    } else {
        procedureResource.setPerformed(convertFhirDateTime(procedure.start, true));
    }
    if (!procedure.reasons.isEmpty()) {
        // Only one element in list
        Code reason = procedure.reasons.get(0);
        for (BundleEntryComponent entry : bundle.getEntry()) {
            if (entry.getResource().fhirType().equals("Condition")) {
                Condition condition = (Condition) entry.getResource();
                // Only one element in list
                Coding coding = condition.getCode().getCoding().get(0);
                if (reason.code.equals(coding.getCode())) {
                    procedureResource.addReasonReference().setReference(entry.getFullUrl()).setDisplay(reason.display);
                }
            }
        }
    }
    if (USE_SHR_EXTENSIONS) {
        procedureResource.setMeta(new Meta().addProfile(SHR_EXT + "shr-procedure-ProcedurePerformed"));
        // required fields for this profile are action-PerformedContext-extension,
        // status, code, subject, performed[x]
        Extension performedContext = new Extension();
        performedContext.setUrl(SHR_EXT + "shr-action-PerformedContext-extension");
        performedContext.addExtension(SHR_EXT + "shr-action-Status-extension", new CodeType("completed"));
        procedureResource.addExtension(performedContext);
    }
    BundleEntryComponent procedureEntry = newEntry(rand, bundle, procedureResource);
    procedure.fullUrl = procedureEntry.getFullUrl();
    return procedureEntry;
}
Also used : Condition(org.hl7.fhir.r4.model.Condition) Meta(org.hl7.fhir.r4.model.Meta) Reference(org.hl7.fhir.r4.model.Reference) DocumentReference(org.hl7.fhir.r4.model.DocumentReference) Period(org.hl7.fhir.r4.model.Period) Code(org.mitre.synthea.world.concepts.HealthRecord.Code) Date(java.util.Date) Extension(org.hl7.fhir.r4.model.Extension) BundleEntryComponent(org.hl7.fhir.r4.model.Bundle.BundleEntryComponent) Coding(org.hl7.fhir.r4.model.Coding) Procedure(org.mitre.synthea.world.concepts.HealthRecord.Procedure) Encounter(org.mitre.synthea.world.concepts.HealthRecord.Encounter) CodeType(org.hl7.fhir.r4.model.CodeType) CodeableConcept(org.hl7.fhir.r4.model.CodeableConcept)

Example 79 with Encounter

use of org.mitre.synthea.world.concepts.HealthRecord.Encounter in project synthea by synthetichealth.

the class FhirR4 method encounter.

/**
 * Map the given Encounter into a FHIR Encounter resource, and add it to the given Bundle.
 *
 * @param personEntry Entry for the Person
 * @param bundle      The Bundle to add to
 * @param encounter   The current Encounter
 * @return The added Entry
 */
private static BundleEntryComponent encounter(Person person, BundleEntryComponent personEntry, Bundle bundle, Encounter encounter) {
    org.hl7.fhir.r4.model.Encounter encounterResource = new org.hl7.fhir.r4.model.Encounter();
    if (USE_US_CORE_IG) {
        Meta meta = new Meta();
        meta.addProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter");
        encounterResource.setMeta(meta);
    } else if (USE_SHR_EXTENSIONS) {
        encounterResource.setMeta(new Meta().addProfile(SHR_EXT + "shr-encounter-EncounterPerformed"));
        Extension performedContext = new Extension();
        performedContext.setUrl(SHR_EXT + "shr-action-PerformedContext-extension");
        performedContext.addExtension(SHR_EXT + "shr-action-Status-extension", new CodeType("finished"));
        encounterResource.addExtension(performedContext);
    }
    Patient patient = (Patient) personEntry.getResource();
    encounterResource.setSubject(new Reference().setReference(personEntry.getFullUrl()).setDisplay(patient.getNameFirstRep().getNameAsSingleString()));
    encounterResource.setStatus(EncounterStatus.FINISHED);
    if (encounter.codes.isEmpty()) {
        // wellness encounter
        encounterResource.addType().addCoding().setCode("185349003").setDisplay("Encounter for check up").setSystem(SNOMED_URI);
    } else {
        Code code = encounter.codes.get(0);
        encounterResource.addType(mapCodeToCodeableConcept(code, SNOMED_URI));
    }
    Coding classCode = new Coding();
    classCode.setCode(EncounterType.fromString(encounter.type).code());
    classCode.setSystem("http://terminology.hl7.org/CodeSystem/v3-ActCode");
    encounterResource.setClass_(classCode);
    encounterResource.setPeriod(new Period().setStart(new Date(encounter.start)).setEnd(new Date(encounter.stop)));
    if (encounter.reason != null) {
        encounterResource.addReasonCode().addCoding().setCode(encounter.reason.code).setDisplay(encounter.reason.display).setSystem(SNOMED_URI);
    }
    Provider provider = encounter.provider;
    if (provider == null) {
        // no associated provider, patient goes to wellness provider
        provider = person.getProvider(EncounterType.WELLNESS, encounter.start);
    }
    if (TRANSACTION_BUNDLE) {
        encounterResource.setServiceProvider(new Reference(ExportHelper.buildFhirSearchUrl("Organization", provider.getResourceID())));
    } else {
        String providerFullUrl = findProviderUrl(provider, bundle);
        if (providerFullUrl != null) {
            encounterResource.setServiceProvider(new Reference(providerFullUrl));
        } else {
            BundleEntryComponent providerOrganization = provider(person, bundle, provider);
            encounterResource.setServiceProvider(new Reference(providerOrganization.getFullUrl()));
        }
    }
    encounterResource.getServiceProvider().setDisplay(provider.name);
    if (USE_US_CORE_IG) {
        String referenceUrl;
        String display;
        if (TRANSACTION_BUNDLE) {
            if (encounter.type.equals(EncounterType.VIRTUAL.toString())) {
                referenceUrl = ExportHelper.buildFhirSearchUrl("Location", FhirR4PatientHome.getPatientHome().getId());
                display = "Patient's Home";
            } else {
                referenceUrl = ExportHelper.buildFhirSearchUrl("Location", provider.getResourceLocationID());
                display = provider.name;
            }
        } else {
            if (encounter.type.equals(EncounterType.VIRTUAL.toString())) {
                referenceUrl = addPatientHomeLocation(bundle);
                display = "Patient's Home";
            } else {
                referenceUrl = findLocationUrl(provider, bundle);
                display = provider.name;
            }
        }
        encounterResource.addLocation().setLocation(new Reference().setReference(referenceUrl).setDisplay(display));
    }
    if (encounter.clinician != null) {
        if (TRANSACTION_BUNDLE) {
            encounterResource.addParticipant().setIndividual(new Reference(ExportHelper.buildFhirNpiSearchUrl(encounter.clinician)));
        } else {
            String practitionerFullUrl = findPractitioner(encounter.clinician, bundle);
            if (practitionerFullUrl != null) {
                encounterResource.addParticipant().setIndividual(new Reference(practitionerFullUrl));
            } else {
                BundleEntryComponent practitioner = practitioner(person, bundle, encounter.clinician);
                encounterResource.addParticipant().setIndividual(new Reference(practitioner.getFullUrl()));
            }
        }
        encounterResource.getParticipantFirstRep().getIndividual().setDisplay(encounter.clinician.getFullname());
        encounterResource.getParticipantFirstRep().addType(mapCodeToCodeableConcept(new Code("http://terminology.hl7.org/CodeSystem/v3-ParticipationType", "PPRF", "primary performer"), null));
        encounterResource.getParticipantFirstRep().setPeriod(encounterResource.getPeriod());
    }
    if (encounter.discharge != null) {
        EncounterHospitalizationComponent hospitalization = new EncounterHospitalizationComponent();
        Code dischargeDisposition = new Code(DISCHARGE_URI, encounter.discharge.code, encounter.discharge.display);
        hospitalization.setDischargeDisposition(mapCodeToCodeableConcept(dischargeDisposition, DISCHARGE_URI));
        encounterResource.setHospitalization(hospitalization);
    }
    BundleEntryComponent entry = newEntry(person, bundle, encounterResource);
    if (USE_US_CORE_IG) {
        // US Core Encounters should have an identifier to support the required
        // Encounter.identifier search parameter
        encounterResource.addIdentifier().setUse(IdentifierUse.OFFICIAL).setSystem(SYNTHEA_IDENTIFIER).setValue(encounterResource.getId());
    }
    return entry;
}
Also used : Meta(org.hl7.fhir.r4.model.Meta) Reference(org.hl7.fhir.r4.model.Reference) DocumentReference(org.hl7.fhir.r4.model.DocumentReference) Patient(org.hl7.fhir.r4.model.Patient) Period(org.hl7.fhir.r4.model.Period) EncounterHospitalizationComponent(org.hl7.fhir.r4.model.Encounter.EncounterHospitalizationComponent) Code(org.mitre.synthea.world.concepts.HealthRecord.Code) Date(java.util.Date) Provider(org.mitre.synthea.world.agents.Provider) Extension(org.hl7.fhir.r4.model.Extension) BundleEntryComponent(org.hl7.fhir.r4.model.Bundle.BundleEntryComponent) Coding(org.hl7.fhir.r4.model.Coding) Encounter(org.mitre.synthea.world.concepts.HealthRecord.Encounter) CodeType(org.hl7.fhir.r4.model.CodeType)

Example 80 with Encounter

use of org.mitre.synthea.world.concepts.HealthRecord.Encounter in project synthea by synthetichealth.

the class FhirR4 method medicationRequest.

/**
 * Map the given Medication to a FHIR MedicationRequest resource, and add it 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 medicationRequest(Person person, BundleEntryComponent personEntry, Bundle bundle, BundleEntryComponent encounterEntry, Medication medication) {
    MedicationRequest medicationResource = new MedicationRequest();
    if (USE_US_CORE_IG) {
        Meta meta = new Meta();
        meta.addProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-medicationrequest");
        medicationResource.setMeta(meta);
    } else if (USE_SHR_EXTENSIONS) {
        medicationResource.addExtension().setUrl(SHR_EXT + "shr-base-ActionCode-extension").setValue(PRESCRIPTION_OF_DRUG_CC);
        medicationResource.setMeta(new Meta().addProfile(SHR_EXT + "shr-medication-MedicationRequested"));
        Extension requestedContext = new Extension();
        requestedContext.setUrl(SHR_EXT + "shr-action-RequestedContext-extension");
        requestedContext.addExtension(SHR_EXT + "shr-action-Status-extension", new CodeType("completed"));
        requestedContext.addExtension(SHR_EXT + "shr-action-RequestIntent-extension", new CodeType("original-order"));
        medicationResource.addExtension(requestedContext);
    }
    medicationResource.setSubject(new Reference(personEntry.getFullUrl()));
    medicationResource.setEncounter(new Reference(encounterEntry.getFullUrl()));
    Code code = medication.codes.get(0);
    String system = code.system.equals("SNOMED-CT") ? SNOMED_URI : 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(person, 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 = (org.hl7.fhir.r4.model.Encounter) encounterEntry.getResource();
    medicationResource.setRequester(encounter.getParticipantFirstRep().getIndividual());
    if (medication.stop != 0L) {
        medicationResource.setStatus(MedicationRequestStatus.STOPPED);
    } else {
        medicationResource.setStatus(MedicationRequestStatus.ACTIVE);
    }
    if (!medication.reasons.isEmpty()) {
        // Only one element in list
        Code reason = medication.reasons.get(0);
        for (BundleEntryComponent entry : bundle.getEntry()) {
            if (entry.getResource().fhirType().equals("Condition")) {
                Condition condition = (Condition) entry.getResource();
                // Only one element in list
                Coding coding = condition.getCode().getCoding().get(0);
                if (reason.code.equals(coding.getCode())) {
                    medicationResource.addReasonReference().setReference(entry.getFullUrl());
                }
            }
        }
    }
    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")));
        if (rxInfo.has("as_needed")) {
            dosage.setText("Take as needed.");
        }
        // as_needed is false
        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")) {
                String text = "";
                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());
                    text += instructionCode.display + "\n";
                    dosage.addAdditionalInstruction(mapCodeToCodeableConcept(instructionCode, SNOMED_URI));
                }
                dosage.setText(text);
            }
        }
        List<Dosage> dosageInstruction = new ArrayList<Dosage>();
        dosageInstruction.add(dosage);
        medicationResource.setDosageInstruction(dosageInstruction);
    }
    BundleEntryComponent medicationEntry = newEntry(person, bundle, medicationResource);
    // create new claim for medication
    medicationClaim(person, personEntry, bundle, encounterEntry, medication.claim, medicationEntry);
    // Create new administration for medication, if needed
    if (medication.administration) {
        medicationAdministration(person, personEntry, bundle, encounterEntry, medication, medicationResource);
    }
    return medicationEntry;
}
Also used : Meta(org.hl7.fhir.r4.model.Meta) DosageDoseAndRateComponent(org.hl7.fhir.r4.model.Dosage.DosageDoseAndRateComponent) ArrayList(java.util.ArrayList) JsonObject(com.google.gson.JsonObject) Dosage(org.hl7.fhir.r4.model.Dosage) Coding(org.hl7.fhir.r4.model.Coding) Medication(org.mitre.synthea.world.concepts.HealthRecord.Medication) Encounter(org.mitre.synthea.world.concepts.HealthRecord.Encounter) TimingRepeatComponent(org.hl7.fhir.r4.model.Timing.TimingRepeatComponent) Condition(org.hl7.fhir.r4.model.Condition) MedicationRequest(org.hl7.fhir.r4.model.MedicationRequest) Reference(org.hl7.fhir.r4.model.Reference) DocumentReference(org.hl7.fhir.r4.model.DocumentReference) BooleanType(org.hl7.fhir.r4.model.BooleanType) SimpleQuantity(org.hl7.fhir.r4.model.SimpleQuantity) SimpleQuantity(org.hl7.fhir.r4.model.SimpleQuantity) Quantity(org.hl7.fhir.r4.model.Quantity) Code(org.mitre.synthea.world.concepts.HealthRecord.Code) Date(java.util.Date) Extension(org.hl7.fhir.r4.model.Extension) BundleEntryComponent(org.hl7.fhir.r4.model.Bundle.BundleEntryComponent) JsonElement(com.google.gson.JsonElement) CodeType(org.hl7.fhir.r4.model.CodeType) Timing(org.hl7.fhir.r4.model.Timing) CodeableConcept(org.hl7.fhir.r4.model.CodeableConcept)

Aggregations

Encounter (org.mitre.synthea.world.concepts.HealthRecord.Encounter)99 Test (org.junit.Test)54 Code (org.mitre.synthea.world.concepts.HealthRecord.Code)51 HealthRecord (org.mitre.synthea.world.concepts.HealthRecord)29 Person (org.mitre.synthea.world.agents.Person)28 ProviderTest (org.mitre.synthea.world.agents.ProviderTest)22 DeathModule (org.mitre.synthea.modules.DeathModule)17 QualityOfLifeModule (org.mitre.synthea.modules.QualityOfLifeModule)17 ArrayList (java.util.ArrayList)16 CardiovascularDiseaseModule (org.mitre.synthea.modules.CardiovascularDiseaseModule)16 EncounterModule (org.mitre.synthea.modules.EncounterModule)16 LifecycleModule (org.mitre.synthea.modules.LifecycleModule)16 WeightLossModule (org.mitre.synthea.modules.WeightLossModule)16 Provider (org.mitre.synthea.world.agents.Provider)16 Medication (org.mitre.synthea.world.concepts.HealthRecord.Medication)16 Observation (org.mitre.synthea.world.concepts.HealthRecord.Observation)16 Procedure (org.mitre.synthea.world.concepts.HealthRecord.Procedure)16 Report (org.mitre.synthea.world.concepts.HealthRecord.Report)14 Date (java.util.Date)13 Claim (org.mitre.synthea.world.concepts.Claim)12