Search in sources :

Example 31 with Section

use of org.hl7.fhir.utilities.xml.SchematronWriter.Section in project eCRNow by drajer-health.

the class CdaProblemGenerator method generateProblemSection.

public static String generateProblemSection(R4FhirData data, LaunchDetails details) {
    StringBuilder sb = new StringBuilder(2000);
    List<Condition> conds = data.getConditions();
    if (conds != null && !conds.isEmpty()) {
        // Generate the component and section end tags
        sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.COMP_EL_NAME));
        sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.SECTION_EL_NAME));
        sb.append(CdaGeneratorUtils.getXmlForTemplateId(CdaGeneratorConstants.PROB_SEC_TEMPLATE_ID));
        sb.append(CdaGeneratorUtils.getXmlForTemplateId(CdaGeneratorConstants.PROB_SEC_TEMPLATE_ID, CdaGeneratorConstants.PROB_SEC_TEMPLATE_ID_EXT));
        sb.append(CdaGeneratorUtils.getXmlForCD(CdaGeneratorConstants.CODE_EL_NAME, CdaGeneratorConstants.PROB_SEC_CODE, CdaGeneratorConstants.LOINC_CODESYSTEM_OID, CdaGeneratorConstants.LOINC_CODESYSTEM_NAME, CdaGeneratorConstants.PROB_SEC_NAME));
        // Add Title
        sb.append(CdaGeneratorUtils.getXmlForText(CdaGeneratorConstants.TITLE_EL_NAME, CdaGeneratorConstants.PROB_SEC_TITLE));
        // Add Narrative Text
        sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.TEXT_EL_NAME));
        // Create Table Header.
        List<String> list = new ArrayList<>();
        list.add(CdaGeneratorConstants.PROB_TABLE_COL_1_TITLE);
        list.add(CdaGeneratorConstants.PROB_TABLE_COL_2_TITLE);
        sb.append(CdaGeneratorUtils.getXmlForTableHeader(list, CdaGeneratorConstants.TABLE_BORDER, CdaGeneratorConstants.TABLE_WIDTH));
        // Add Table Body
        sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.TABLE_BODY_EL_NAME));
        // Add Body Rows
        int rowNum = 1;
        for (Condition prob : conds) {
            String probDisplayName = CdaGeneratorConstants.UNKNOWN_VALUE;
            if (prob.getCode() != null && prob.getCode().getCodingFirstRep() != null && !StringUtils.isEmpty(prob.getCode().getCodingFirstRep().getDisplay())) {
                probDisplayName = prob.getCode().getCodingFirstRep().getDisplay();
            }
            Map<String, String> bodyvals = new LinkedHashMap<>();
            bodyvals.put(CdaGeneratorConstants.PROB_TABLE_COL_1_BODY_CONTENT, probDisplayName);
            if (prob.getClinicalStatus() != null && prob.getClinicalStatus().getCodingFirstRep() != null && !StringUtils.isEmpty(prob.getClinicalStatus().getCodingFirstRep().getCode()) && (prob.getClinicalStatus().getCodingFirstRep().getCode().contentEquals(ConditionClinical.ACTIVE.toCode()) || prob.getClinicalStatus().getCodingFirstRep().getCode().contentEquals(ConditionClinical.RELAPSE.toCode()))) {
                bodyvals.put(CdaGeneratorConstants.PROB_TABLE_COL_2_BODY_CONTENT, CdaGeneratorConstants.TABLE_ACTIVE_STATUS);
            } else {
                bodyvals.put(CdaGeneratorConstants.PROB_TABLE_COL_2_BODY_CONTENT, CdaGeneratorConstants.TABLE_RESOLVED_STATUS);
            }
            sb.append(CdaGeneratorUtils.addTableRow(bodyvals, rowNum));
            // TODO: ++rowNum or rowNum++
            ++rowNum;
        }
        sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.TABLE_BODY_EL_NAME));
        // End Table.
        sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.TABLE_EL_NAME));
        sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.TEXT_EL_NAME));
        for (Condition pr : conds) {
            // Add the Entries.
            sb.append(CdaGeneratorUtils.getXmlForActEntry(CdaGeneratorConstants.TYPE_CODE_DEF));
            // Add the problem Concern Act
            sb.append(CdaGeneratorUtils.getXmlForAct(CdaGeneratorConstants.ACT_EL_NAME, CdaGeneratorConstants.ACT_CLASS_CODE, CdaGeneratorConstants.MOOD_CODE_DEF));
            sb.append(CdaGeneratorUtils.getXmlForTemplateId(CdaGeneratorConstants.PROB_CONCERN_TEMPLATE_ID));
            sb.append(CdaGeneratorUtils.getXmlForTemplateId(CdaGeneratorConstants.PROB_CONCERN_TEMPLATE_ID, CdaGeneratorConstants.PROB_CONCERN_TEMPLATE_ID_EXT));
            sb.append(CdaGeneratorUtils.getXmlForIIUsingGuid());
            sb.append(CdaGeneratorUtils.getXmlForCD(CdaGeneratorConstants.CODE_EL_NAME, CdaGeneratorConstants.PROB_CONC_ACT_CODE, CdaGeneratorConstants.HL7_ACT_CLASS_OID, CdaGeneratorConstants.HL7_ACT_CLASS_NAME, CdaGeneratorConstants.PROB_CONC_ACT_NAME));
            if (pr.getClinicalStatus() != null && pr.getClinicalStatus().getCodingFirstRep() != null && !StringUtils.isEmpty(pr.getClinicalStatus().getCodingFirstRep().getCode()) && (pr.getClinicalStatus().getCodingFirstRep().getCode().contentEquals(ConditionClinical.ACTIVE.toCode()) || pr.getClinicalStatus().getCodingFirstRep().getCode().contentEquals(ConditionClinical.RELAPSE.toCode()))) {
                sb.append(CdaGeneratorUtils.getXmlForCD(CdaGeneratorConstants.STATUS_CODE_EL_NAME, CdaGeneratorConstants.ACTIVE_STATUS));
            } else {
                sb.append(CdaGeneratorUtils.getXmlForCD(CdaGeneratorConstants.STATUS_CODE_EL_NAME, CdaGeneratorConstants.COMPLETED_STATUS));
            }
            Pair<Date, TimeZone> onset = CdaFhirUtilities.getActualDate(pr.getOnset());
            Pair<Date, TimeZone> abatement = CdaFhirUtilities.getActualDate(pr.getAbatement());
            Pair<Date, TimeZone> recordedDate = null;
            if (pr.getRecordedDateElement() != null) {
                recordedDate = new Pair<>(pr.getRecordedDate(), pr.getRecordedDateElement().getTimeZone());
            }
            sb.append(CdaGeneratorUtils.getXmlForIVLWithTS(CdaGeneratorConstants.EFF_TIME_EL_NAME, recordedDate, abatement, true));
            // Add the Problem Observation
            sb.append(CdaGeneratorUtils.getXmlForEntryRelationship(CdaGeneratorConstants.ENTRY_REL_SUBJ_CODE));
            sb.append(CdaGeneratorUtils.getXmlForAct(CdaGeneratorConstants.OBS_ACT_EL_NAME, CdaGeneratorConstants.OBS_CLASS_CODE, CdaGeneratorConstants.MOOD_CODE_DEF));
            sb.append(CdaGeneratorUtils.getXmlForTemplateId(CdaGeneratorConstants.PROB_OBS_TEMPLATE_ID));
            sb.append(CdaGeneratorUtils.getXmlForTemplateId(CdaGeneratorConstants.PROB_OBS_TEMPLATE_ID, CdaGeneratorConstants.PROB_OBS_TEMPALTE_ID_EXT));
            sb.append(CdaGeneratorUtils.getXmlForII(details.getAssigningAuthorityId(), pr.getId()));
            sb.append(CdaGeneratorUtils.getXmlForCDWithoutEndTag(CdaGeneratorConstants.CODE_EL_NAME, CdaGeneratorConstants.DIAGNOSIS_SNOMED, CdaGeneratorConstants.SNOMED_CODESYSTEM_OID, CdaGeneratorConstants.SNOMED_CODESYSTEM_NAME, CdaGeneratorConstants.DIAGNOSIS_DISPLAY_NAME));
            sb.append(CdaGeneratorUtils.getXmlForCD(CdaGeneratorConstants.TRANSLATION_EL_NAME, CdaGeneratorConstants.DIAGNOSIS_LOINC, CdaGeneratorConstants.LOINC_CODESYSTEM_OID, CdaGeneratorConstants.LOINC_CODESYSTEM_NAME, CdaGeneratorConstants.DIAGNOSIS_DISPLAY_NAME));
            sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.CODE_EL_NAME));
            sb.append(CdaGeneratorUtils.getXmlForCD(CdaGeneratorConstants.STATUS_CODE_EL_NAME, CdaGeneratorConstants.COMPLETED_STATUS));
            sb.append(CdaGeneratorUtils.getXmlForIVLWithTS(CdaGeneratorConstants.EFF_TIME_EL_NAME, onset, abatement, true));
            List<CodeableConcept> cds = new ArrayList<>();
            cds.add(pr.getCode());
            String codeXml = CdaFhirUtilities.getCodeableConceptXmlForCodeSystem(cds, CdaGeneratorConstants.VAL_EL_NAME, true, CdaGeneratorConstants.FHIR_SNOMED_URL, false);
            if (!codeXml.isEmpty()) {
                sb.append(codeXml);
            } else {
                sb.append(CdaFhirUtilities.getCodeableConceptXml(cds, CdaGeneratorConstants.VAL_EL_NAME, true));
            }
            // End Tag for Entry Relationship
            sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.OBS_ACT_EL_NAME));
            sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.ENTRY_REL_EL_NAME));
            logger.debug("Add Trigger Codes to Problem Observation if applicable {}", pr.getId());
            sb.append(addTriggerCodes(details, pr, onset, abatement));
            logger.debug("Completed adding Trigger Codes ");
            // End Tags for Entries
            sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.ACT_EL_NAME));
            sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.ENTRY_EL_NAME));
        }
        // Complete the section end tags.
        sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.SECTION_EL_NAME));
        sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.COMP_EL_NAME));
    } else {
        sb.append(generateEmptyProblemSection());
    }
    return sb.toString();
}
Also used : Condition(org.hl7.fhir.r4.model.Condition) ArrayList(java.util.ArrayList) Date(java.util.Date) LinkedHashMap(java.util.LinkedHashMap) TimeZone(java.util.TimeZone) CodeableConcept(org.hl7.fhir.r4.model.CodeableConcept)

Example 32 with Section

use of org.hl7.fhir.utilities.xml.SchematronWriter.Section in project eCRNow by drajer-health.

the class CdaPlanOfTreatmentGenerator method generatePlanOfTreatmentSection.

public static String generatePlanOfTreatmentSection(R4FhirData data, LaunchDetails details) {
    StringBuilder sb = new StringBuilder(2000);
    List<ServiceRequest> sr = getValidServiceRequests(data);
    if (sr != null && !sr.isEmpty()) {
        logger.debug("Found a total of {} service request objects to translate to CDA.", sr.size());
        // Generate the component and section end tags
        sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.COMP_EL_NAME));
        sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.SECTION_EL_NAME));
        sb.append(CdaGeneratorUtils.getXmlForTemplateId(CdaGeneratorConstants.CAREPLAN_SEC_TEMPLATE_ID));
        sb.append(CdaGeneratorUtils.getXmlForTemplateId(CdaGeneratorConstants.CAREPLAN_SEC_TEMPLATE_ID, CdaGeneratorConstants.CAREPLAN_SEC_TEMPLATE_ID_EXT));
        sb.append(CdaGeneratorUtils.getXmlForCD(CdaGeneratorConstants.CODE_EL_NAME, CdaGeneratorConstants.CAREPLAN_SEC_CODE, CdaGeneratorConstants.LOINC_CODESYSTEM_OID, CdaGeneratorConstants.LOINC_CODESYSTEM_NAME, CdaGeneratorConstants.CAREPLAN_SEC_NAME));
        // Add Title
        sb.append(CdaGeneratorUtils.getXmlForText(CdaGeneratorConstants.TITLE_EL_NAME, CdaGeneratorConstants.CAREPLAN_SEC_TITLE));
        // Add Narrative Text
        sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.TEXT_EL_NAME));
        // Create Table Header.
        List<String> list = new ArrayList<>();
        list.add(CdaGeneratorConstants.POT_OBS_TABLE_COL_1_TITLE);
        list.add(CdaGeneratorConstants.POT_OBS_TABLE_COL_2_TITLE);
        sb.append(CdaGeneratorUtils.getXmlForTableHeader(list, CdaGeneratorConstants.TABLE_BORDER, CdaGeneratorConstants.TABLE_WIDTH));
        // Add Table Body
        sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.TABLE_BODY_EL_NAME));
        int rowNum = 1;
        StringBuilder potObsXml = new StringBuilder();
        for (ServiceRequest s : sr) {
            Pair<String, Boolean> srDisplayName = CdaFhirUtilities.getCodeableConceptDisplayForCodeSystem(s.getCode(), CdaGeneratorConstants.FHIR_LOINC_URL, false);
            if (srDisplayName.getValue0().isEmpty()) {
                srDisplayName.setAt0(CdaGeneratorConstants.UNKNOWN_VALUE);
            }
            String serviceDate = CdaFhirUtilities.getStringForType(s.getOccurrence());
            logger.debug("Service Date for display {} ", serviceDate);
            if (serviceDate.isEmpty() && s.getAuthoredOnElement() != null) {
                serviceDate = CdaFhirUtilities.getDisplayStringForDateTimeType(s.getAuthoredOnElement());
            }
            Map<String, String> bodyvals = new LinkedHashMap<>();
            bodyvals.put(CdaGeneratorConstants.POT_OBS_TABLE_COL_1_BODY_CONTENT, srDisplayName.getValue0());
            bodyvals.put(CdaGeneratorConstants.POT_OBS_TABLE_COL_2_BODY_CONTENT, serviceDate);
            sb.append(CdaGeneratorUtils.addTableRow(bodyvals, rowNum));
            String contentRef = CdaGeneratorConstants.POT_OBS_TABLE_COL_1_BODY_CONTENT + Integer.toString(rowNum);
            rowNum++;
            potObsXml.append(getPlannedObservationXml(s, details, contentRef));
        }
        // Close the Text Element
        sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.TABLE_BODY_EL_NAME));
        sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.TABLE_EL_NAME));
        sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.TEXT_EL_NAME));
        // Add Entries
        sb.append(potObsXml);
        // Complete the section end tags.
        sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.SECTION_EL_NAME));
        sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.COMP_EL_NAME));
    } else {
        sb.append(generateEmptyPlanOfTreatmentSection());
    }
    return sb.toString();
}
Also used : ArrayList(java.util.ArrayList) ServiceRequest(org.hl7.fhir.r4.model.ServiceRequest) LinkedHashMap(java.util.LinkedHashMap)

Example 33 with Section

use of org.hl7.fhir.utilities.xml.SchematronWriter.Section in project eCRNow by drajer-health.

the class CdaReasonForVisitGenerator method generateReasonForVisitSection.

public static String generateReasonForVisitSection(R4FhirData data) {
    StringBuilder sb = new StringBuilder(2000);
    Encounter encounter = data.getEncounter();
    // Will have to wait to discuss with vendors on Reason For Visit and how to obtain that
    // information reliably..
    // Then we can generate better text.
    sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.COMP_EL_NAME));
    sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.SECTION_EL_NAME));
    sb.append(CdaGeneratorUtils.getXmlForTemplateId(CdaGeneratorConstants.REASON_FOR_VISIT_SEC_TEMPLATE_ID));
    sb.append(CdaGeneratorUtils.getXmlForCD(CdaGeneratorConstants.CODE_EL_NAME, CdaGeneratorConstants.REASON_FOR_VISIT_SEC_CODE, CdaGeneratorConstants.LOINC_CODESYSTEM_OID, CdaGeneratorConstants.LOINC_CODESYSTEM_NAME, CdaGeneratorConstants.REASON_FOR_VISIT_SEC_CODE_NAME));
    // Add Title
    sb.append(CdaGeneratorUtils.getXmlForText(CdaGeneratorConstants.TITLE_EL_NAME, CdaGeneratorConstants.REASON_FOR_VISIT_SEC_TITLE));
    // Add Narrative Text
    // Need to Discuss with vendors on how to best get this information.
    sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.TEXT_EL_NAME));
    // Create Table Header.
    List<String> list = new ArrayList<>();
    list.add(CdaGeneratorConstants.TEXT_EL_NAME);
    sb.append(CdaGeneratorUtils.getXmlForTableHeader(list, CdaGeneratorConstants.TABLE_BORDER, CdaGeneratorConstants.TABLE_WIDTH));
    // Add Table Body
    sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.TABLE_BODY_EL_NAME));
    // Add Body Rows
    int rowNum = 1;
    String text = CdaGeneratorConstants.UNKNOWN_REASON_FOR_VISIT;
    if (encounter != null && encounter.getReasonCodeFirstRep() != null) {
        if (!StringUtils.isEmpty(encounter.getReasonCodeFirstRep().getText())) {
            text = encounter.getReasonCodeFirstRep().getText();
        } else if (encounter.getReasonCodeFirstRep().getCodingFirstRep() != null && !StringUtils.isEmpty(encounter.getReasonCodeFirstRep().getCodingFirstRep().getDisplay())) {
            text = encounter.getReasonCodeFirstRep().getCodingFirstRep().getDisplay();
        }
    }
    Map<String, String> bodyvals = new LinkedHashMap<>();
    bodyvals.put(CdaGeneratorConstants.TEXT_EL_NAME, text);
    sb.append(CdaGeneratorUtils.addTableRow(bodyvals, rowNum));
    sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.TABLE_BODY_EL_NAME));
    // End Table.
    sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.TABLE_EL_NAME));
    sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.TEXT_EL_NAME));
    // Complete the section end tags.
    sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.SECTION_EL_NAME));
    sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.COMP_EL_NAME));
    return sb.toString();
}
Also used : ArrayList(java.util.ArrayList) Encounter(org.hl7.fhir.r4.model.Encounter) LinkedHashMap(java.util.LinkedHashMap)

Example 34 with Section

use of org.hl7.fhir.utilities.xml.SchematronWriter.Section in project eCRNow by drajer-health.

the class CdaSocialHistoryGenerator method generateSocialHistorySection.

public static String generateSocialHistorySection(R4FhirData data, LaunchDetails details) {
    StringBuilder sb = new StringBuilder(2000);
    // Will have to wait to discuss with vendors on Travel History, Pregnancy, and Birth Sex
    // Observations.
    // Then we can generte the entries. Till then it will be empty section.
    CodeType birthSex = CdaFhirUtilities.getCodeExtension(data.getPatient().getExtension(), CdaGeneratorConstants.FHIR_USCORE_BIRTHSEX_EXT_URL);
    List<Observation> pregObs = data.getPregnancyObs();
    List<Condition> pregCond = data.getPregnancyConditions();
    List<Observation> travelHistory = data.getTravelObs();
    List<Observation> occHistory = data.getOccupationObs();
    if (birthSex != null || (pregObs != null && !pregObs.isEmpty()) || (pregCond != null && !pregCond.isEmpty()) || (occHistory != null && !occHistory.isEmpty()) || (travelHistory != null && !travelHistory.isEmpty())) {
        sb.append(generateSocialHistorySectionHeader(""));
        sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.TEXT_EL_NAME));
        // Create Table Header.
        List<String> list = new ArrayList<>();
        list.add(CdaGeneratorConstants.SOC_HISTORY_TABLE_COL_1_TITLE);
        list.add(CdaGeneratorConstants.SOC_HISTORY_TABLE_COL_2_TITLE);
        sb.append(CdaGeneratorUtils.getXmlForTableHeader(list, CdaGeneratorConstants.TABLE_BORDER, CdaGeneratorConstants.TABLE_WIDTH));
        // Add Table Body
        sb.append(CdaGeneratorUtils.getXmlForStartElement(CdaGeneratorConstants.TABLE_BODY_EL_NAME));
        String birthSexXml = "";
        String pregObsXml = "";
        StringBuilder pregCondXml = new StringBuilder();
        StringBuilder occHistoryXml = new StringBuilder();
        StringBuilder travelHistoryXml = new StringBuilder();
        int index = 0;
        Map<String, String> bodyvals = new LinkedHashMap<>();
        if (birthSex != null) {
            logger.info("Found Birth Sex");
            bodyvals.put(CdaGeneratorConstants.SOC_HISTORY_TABLE_COL_1_BODY_CONTENT, CdaGeneratorConstants.BIRTH_SEX_DISPLAY);
            bodyvals.put(CdaGeneratorConstants.SOC_HISTORY_TABLE_COL_2_BODY_CONTENT, CdaFhirUtilities.getStringForType(birthSex));
            sb.append(CdaGeneratorUtils.addTableRow(bodyvals, index));
            index++;
            birthSexXml = generateBirthSexEntry(birthSex);
        }
        if (pregCond != null && !pregCond.isEmpty()) {
            logger.info("Pregnancy Condition Found");
            for (Condition c : pregCond) {
                bodyvals.put(CdaGeneratorConstants.SOC_HISTORY_TABLE_COL_1_BODY_CONTENT, CdaGeneratorConstants.PREGNANCY_CONDITION_DISPLAY);
                bodyvals.put(CdaGeneratorConstants.SOC_HISTORY_TABLE_COL_2_BODY_CONTENT, CdaFhirUtilities.getCodeableConceptDisplayForCodeSystem(c.getCode(), CdaGeneratorConstants.FHIR_SNOMED_URL, true).getValue0());
                sb.append(CdaGeneratorUtils.addTableRow(bodyvals, index));
                index++;
                pregCondXml.append(generatePregnancyEntry(c));
            }
        }
        if (pregObs != null && !pregObs.isEmpty()) {
            logger.info("Pregnancy Status Observation Found - Will be added as needed.");
        // These are not available in FHIR right now reliably, so nothing to process until further
        // discussion with vendors.
        // Setup Table Text Entries
        // Setup XML Entries
        }
        if (occHistory != null && !occHistory.isEmpty()) {
            logger.info("Occupation History Observation Found");
            for (Observation obs : occHistory) {
                if (obs.getValue() != null && (obs.getValue() instanceof StringType || obs.getValue() instanceof CodeableConcept)) {
                    bodyvals.put(CdaGeneratorConstants.SOC_HISTORY_TABLE_COL_1_BODY_CONTENT, CdaGeneratorConstants.OCCUPATION_HISTORY_DISPLAY);
                    String display = CdaFhirUtilities.getStringForType(obs.getValue());
                    bodyvals.put(CdaGeneratorConstants.SOC_HISTORY_TABLE_COL_2_BODY_CONTENT, display);
                    sb.append(CdaGeneratorUtils.addTableRow(bodyvals, index));
                    index++;
                    occHistoryXml.append(generateOccHistoryEntry(obs));
                }
            }
        }
        if (travelHistory != null && !travelHistory.isEmpty()) {
            logger.info("Travel History Observation Found ");
            for (Observation obs : travelHistory) {
                bodyvals.put(CdaGeneratorConstants.SOC_HISTORY_TABLE_COL_1_BODY_CONTENT, CdaGeneratorConstants.TRAVEL_HISTORY_DISPLAY);
                String display = CdaFhirUtilities.getCombinationStringForCodeSystem(obs.getCode(), obs.getValue(), CdaGeneratorConstants.FHIR_SNOMED_URL, true);
                bodyvals.put(CdaGeneratorConstants.SOC_HISTORY_TABLE_COL_2_BODY_CONTENT, display);
                sb.append(CdaGeneratorUtils.addTableRow(bodyvals, index));
                index++;
                travelHistoryXml.append(generateTravelHistoryEntry(obs, display));
            }
        }
        // Close the Table.
        sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.TABLE_BODY_EL_NAME));
        sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.TABLE_EL_NAME));
        sb.append(CdaGeneratorUtils.getXmlForEndElement(CdaGeneratorConstants.TEXT_EL_NAME));
        // Add entry
        if (!StringUtils.isEmpty(birthSexXml)) {
            sb.append(birthSexXml);
        }
        if (!StringUtils.isEmpty(pregCondXml)) {
            sb.append(pregCondXml);
        }
        if (!StringUtils.isEmpty(pregObsXml)) {
            sb.append(pregObsXml);
        }
        if (!StringUtils.isEmpty(occHistoryXml)) {
            sb.append(occHistoryXml);
        }
        if (!StringUtils.isEmpty(travelHistoryXml)) {
            sb.append(travelHistoryXml);
        }
        sb.append(generateSocialHistorySectionEndHeader());
    } else {
        sb.append(generateEmptySocialHistorySection());
    }
    return sb.toString();
}
Also used : Condition(org.hl7.fhir.r4.model.Condition) StringType(org.hl7.fhir.r4.model.StringType) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Observation(org.hl7.fhir.r4.model.Observation) CodeType(org.hl7.fhir.r4.model.CodeType) CodeableConcept(org.hl7.fhir.r4.model.CodeableConcept)

Example 35 with Section

use of org.hl7.fhir.utilities.xml.SchematronWriter.Section in project synthea by synthetichealth.

the class FhirStu3 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) {
    boolean inpatient = false;
    boolean outpatient = false;
    EncounterType type = EncounterType.fromString(encounter.type);
    if (type == EncounterType.INPATIENT) {
        inpatient = true;
    // Provider enum doesn't include outpatient, but it can still be
    // an encounter type.
    } else if (type == EncounterType.AMBULATORY || type == EncounterType.WELLNESS) {
        outpatient = true;
    }
    ExplanationOfBenefit eob = new ExplanationOfBenefit();
    org.hl7.fhir.dstu3.model.Encounter encounterResource = (org.hl7.fhir.dstu3.model.Encounter) encounterEntry.getResource();
    // will have to deal with different claim types (e.g. inpatient vs outpatient)
    if (inpatient) {
        // https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/AcuteInpatientPPS/Indirect-Medical-Education-IME
        // Extra cost for educational hospitals
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-ime-op-clm-val-amt-extension", 400));
        // DSH payment-- Massachusetts does not make DSH payments at all, so set to 0 for now
        // https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/AcuteInpatientPPS/dsh
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-dsh-op-clm-val-amt-extension", 0));
        // The pass through per diem rate
        // not really defined by CMS
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-clm-pass-thru-per-diem-amt-extension", 0));
        // Professional charge
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-nch-profnl-cmpnt-chrg-amt-extension", 0));
        // total claim PPS charge
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-clm-tot-pps-cptl-amt-extension", 0));
        // Deductible Amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-nch-bene-ip-ddctbl-amt-extension", 0));
        // Coinsurance Liability
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-nch-bene-pta-coinsrnc-lblty-amt-extension", 0));
        // Non-covered Charge Amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-nch-ip-ncvrd-chrg-amt-extension", 0));
        // Total Deductible/Coinsurance Amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-nch-ip-tot-ddctn-amt-extension", 0));
        // PPS Capital DSH Amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-clm-pps-cptl-dsprprtnt-shr-amt-extension", 0));
        // PPS Capital Exception Amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-clm-pps-cptl-excptn-amt-extension", 0));
        // PPS FSP
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-clm-pps-cptl-fsp-amt-extension", 0));
        // PPS IME
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-clm-pps-cptl-ime-amt-extension", 400));
        // PPS Capital Outlier Amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-clm-pps-cptl-outlier-amt-extension", 0));
        // Old capital hold harmless amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-clm-pps-old-cptl-hld-hrmls-amt-extension", 0));
        // NCH DRG Outlier Approved Payment Amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-nch-drg-outlier-aprvd-pmt-amt-extension", 0));
        // NCH Beneficiary Blood Deductible Liability Amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-nch-bene-blood-ddctbl-lblty-am-extension", 0));
        // Non-payment reason
        eob.addExtension().setUrl("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-clm-mdcr-non-pmt-rsn-cd-extension").setValue(new Coding().setSystem("https://bluebutton.cms.gov/assets/ig/CodeSystem-clm-mdcr-non-pmt-rsn-cd").setDisplay("All other reasons for non-payment").setCode("N"));
        // Prepayment
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-prpayamt-extension", 0));
        // FI or MAC number
        eob.addExtension().setUrl("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-fi-num-extension").setValue(new Identifier().setValue("002000").setSystem("https://bluebutton.cms.gov/assets/ig/CodeSystem-fi-num"));
    } else if (outpatient) {
        // Professional component charge amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-outpatient-nch-profnl-cmpnt-chrg-amt-extension", 0));
        // Deductible amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-outpatient-nch-bene-ptb-ddctbl-amt-extension", 0));
        // Coinsurance amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-outpatient-nch-bene-ptb-coinsrnc-amt-extension", 0));
        // Provider Payment
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-outpatient-clm-op-prvdr-pmt-amt-extension", 0));
        // Beneficiary payment
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-outpatient-clm-op-bene-pmt-amt-extension", 0));
        // Beneficiary Blood Deductible Liability Amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-outpatient-nch-bene-blood-ddctbl-lblty-am-extension", 0));
        // Claim Medicare Non Payment Reason Code
        eob.addExtension().setUrl("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-outpatient-clm-mdcr-non-pmt-rsn-cd-extension").setValue(new Coding().setDisplay("All other reasons for non-payment").setSystem("https://bluebutton.cms.gov/assets/ig/CodeSystem-clm-mdcr-non-pmt-rsn-cd").setCode("N"));
        // NCH Primary Payer Claim Paid Amount
        eob.addExtension(createMoneyExtension("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-outpatient-prpayamt-extension", 0));
        // FI or MAC number
        eob.addExtension().setUrl("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-outpatient-fi-num-extension").setValue(new Identifier().setValue("002000").setSystem("https://bluebutton.cms.gov/assets/ig/CodeSystem-fi-num"));
    }
    // 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());
    if (inpatient) {
        billablePeriod.addExtension(new Extension().setUrl("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-claim-query-cd-extension").setValue(new Coding().setCode("3").setSystem("https://bluebutton.cms.gov/assets/ig/ValueSet-claim-query-cd").setDisplay("Final Bill")));
    } else if (outpatient) {
        billablePeriod.addExtension(new Extension().setUrl("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-outpatient-claim-query-cd-extension").setValue(new Coding().setCode("3").setSystem("https://bluebutton.cms.gov/assets/ig/ValueSet-claim-query-cd").setDisplay("Final Bill")));
    }
    eob.setBillablePeriod(billablePeriod);
    // cost is hardcoded to be USD in claim so this should be fine as well
    Money totalCost = new Money();
    totalCost.setSystem("urn:iso:std:iso:4217");
    totalCost.setCode("USD");
    totalCost.setValue(encounter.claim.getTotalClaimCost());
    eob.setTotalCost(totalCost);
    // Set References
    eob.setPatient(new Reference(personEntry.getFullUrl()));
    if (encounter.provider != null) {
        // This is what should happen if BlueButton 2.0 wasn't needlessly restrictive
        // String providerUrl = findProviderUrl(encounter.provider, bundle);
        // eob.setOrganization(new Reference().setReference(providerUrl));
        // Instead, we'll create the BlueButton 2.0 reference via identifier...
        Identifier identifier = new Identifier();
        identifier.setValue(encounter.provider.getResourceID());
        eob.setOrganization(new Reference().setIdentifier(identifier));
    }
    String npi = "9999999999";
    if (encounter.clinician != null) {
        npi = encounter.clinician.npi;
    } else if (encounter.provider != null) {
        npi = encounter.provider.npi;
    }
    // Get the insurance info at the time that the encounter happened.
    Payer payer = encounter.claim.payer;
    Coverage coverage = new Coverage();
    coverage.setId("coverage");
    coverage.setType(new CodeableConcept().setText(payer.getName()));
    eob.addContained(coverage);
    ExplanationOfBenefit.InsuranceComponent insuranceComponent = new ExplanationOfBenefit.InsuranceComponent();
    insuranceComponent.setCoverage(new Reference("#coverage"));
    eob.setInsurance(insuranceComponent);
    org.hl7.fhir.dstu3.model.Claim claim = (org.hl7.fhir.dstu3.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.setStatus(org.hl7.fhir.dstu3.model.ExplanationOfBenefit.ExplanationOfBenefitStatus.ACTIVE);
    if (!inpatient && !outpatient) {
        eob.setClaim(new Reference().setReference(claimEntry.getFullUrl()));
        List<Reference> recipientList = new ArrayList<>();
        recipientList.add(new Reference().setIdentifier(new Identifier().setSystem("http://hl7.org/fhir/sid/us-npi").setValue(npi)));
        eob.addContained(new ReferralRequest().setStatus(ReferralRequest.ReferralRequestStatus.COMPLETED).setIntent(ReferralRequest.ReferralCategory.ORDER).setSubject(new Reference(personEntry.getFullUrl())).setRequester(new ReferralRequest.ReferralRequestRequesterComponent().setAgent(new Reference().setIdentifier(new Identifier().setSystem("http://hl7.org/fhir/sid/us-npi").setValue(npi)))).setRecipient(recipientList).setId("referral"));
        eob.setReferral(new Reference("#referral"));
        eob.setCreated(encounterResource.getPeriod().getEnd());
    }
    eob.setType(claim.getType());
    List<ExplanationOfBenefit.DiagnosisComponent> eobDiag = new ArrayList<>();
    for (org.hl7.fhir.dstu3.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("https://bluebutton.cms.gov/resources/codesystem/diagnosis-type")));
        diagnosisComponent.setSequence(claimDiagnosis.getSequence());
        diagnosisComponent.setPackageCode(claimDiagnosis.getPackageCode());
        diagnosisComponent.addExtension().setUrl("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-clm-poa-ind-sw1-extension").setValue(new Coding().setCode("Y").setSystem("https://bluebutton.cms.gov/assets/ig/CodeSystem-clm-poa-ind-sw1").setDisplay("Diagnosis present at time of admission"));
        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;
    for (ItemComponent item : claim.getItem()) {
        ExplanationOfBenefit.ItemComponent itemComponent = new ExplanationOfBenefit.ItemComponent();
        itemComponent.setSequence(item.getSequence());
        itemComponent.setQuantity(item.getQuantity());
        itemComponent.setUnitPrice(item.getUnitPrice());
        itemComponent.setCareTeamLinkId(item.getCareTeamLinkId());
        if (item.hasService()) {
            itemComponent.setService(item.getService());
        }
        if (!inpatient && !outpatient) {
            itemComponent.setDiagnosisLinkId(item.getDiagnosisLinkId());
            itemComponent.setInformationLinkId(item.getInformationLinkId());
            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")));
        }
        if (inpatient) {
            itemComponent.addExtension(new Extension().setUrl("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-inpatient-rev-cntr-ndc-qty-extension").setValue(new Quantity().setValue(0)));
        } else if (outpatient) {
            itemComponent.addExtension(new Extension().setUrl("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-outpatient-rev-cntr-ndc-qty-extension").setValue(new Quantity().setValue(0)));
            if (itemComponent.hasService()) {
                itemComponent.getService().addExtension(new Extension().setUrl("https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-outpatient-rev-cntr-ide-ndc-upc-num-extension").setValue(new Coding().setSystem("https://www.accessdata.fda.gov/scripts/cder/ndc").setDisplay("Dummy").setCode("0624")));
            }
        }
        // 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 = "23";
                display = "Emergency Room";
                break;
            case INPATIENT:
                code = "21";
                display = "Inpatient Hospital";
                break;
            case URGENTCARE:
                code = "20";
                display = "Urgent Care Facility";
                break;
            case WELLNESS:
                code = "22";
                display = "Outpatient Hospital";
                break;
            default:
                code = "21";
                display = "Inpatient Hospital";
        }
        location.addCoding().setCode(code).setSystem("https://bluebutton.cms.gov/resources/variables/line_place_of_srvc_cd").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()).setSystem(// USD
            "urn:iso:std:iso:4217").setCode("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()).setSystem("urn:iso:std:iso:4217").setCode("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()).setSystem("urn:iso:std:iso:4217").setCode("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()).setSystem("urn:iso:std:iso:4217").setCode("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"));
            if (!inpatient && !outpatient) {
                indicatorCode.getReason().addCoding().setCode("A").setSystem("https://bluebutton.cms.gov/resources/variables/line_prcsg_ind_cd");
                indicatorCode.getReason().getCodingFirstRep().setDisplay("Allowed");
            }
            // 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).setSystem("urn:iso:std:iso:4217").setCode("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).setSystem("urn:iso:std:iso:4217").setCode("USD");
    eob.setPayment(new ExplanationOfBenefit.PaymentComponent().setAmount(payment));
    if (encounter.clinician != null) {
        // This is what should happen if BlueButton 2.0 wasn't needlessly restrictive
        // String practitionerFullUrl = findPractitioner(encounter.clinician, bundle);
        // eob.setProvider(new Reference().setReference(practitionerFullUrl));
        // Instead, we'll create the BlueButton 2.0 reference via identifier...
        Identifier identifier = new Identifier();
        identifier.setValue(encounter.clinician.getResourceID());
        eob.setProvider(new Reference().setIdentifier(identifier));
    } else {
        Identifier identifier = new Identifier();
        identifier.setValue("Unknown");
        eob.setProvider(new Reference().setIdentifier(identifier));
    }
    eob.addCareTeam(new ExplanationOfBenefit.CareTeamComponent().setSequence(1).setProvider(new Reference().setIdentifier(new Identifier().setSystem("http://hl7.org/fhir/sid/us-npi").setValue(npi))).setRole(new CodeableConcept().addCoding(new Coding().setCode("primary").setSystem("http://hl7.org/fhir/claimcareteamrole").setDisplay("Primary Care Practitioner"))));
    eob.setType(new CodeableConcept().addCoding(new Coding().setSystem("https://bluebutton.cms.gov/resources/variables/nch_clm_type_cd").setCode("71").setDisplay("Local carrier non-durable medical equipment, prosthetics, orthotics, " + "and supplies (DMEPOS) claim")).addCoding(new Coding().setSystem("https://bluebutton.cms.gov/resources/codesystem/eob-type").setCode("CARRIER").setDisplay("EOB Type")).addCoding(new Coding().setSystem("http://hl7.org/fhir/ex-claimtype").setCode("professional").setDisplay("Claim Type")).addCoding(new Coding().setSystem("https://bluebutton.cms.gov/resources/variables/nch_near_line_rec_ident_cd").setCode("O").setDisplay("Part B physician/supplier claim record (processed by local " + "carriers; can include DMEPOS services)")));
    return newEntry(person, bundle, eob);
}
Also used : ReferralRequest(org.hl7.fhir.dstu3.model.ReferralRequest) ArrayList(java.util.ArrayList) ExplanationOfBenefit(org.hl7.fhir.dstu3.model.ExplanationOfBenefit) ProcedureComponent(org.hl7.fhir.dstu3.model.Claim.ProcedureComponent) Money(org.hl7.fhir.dstu3.model.Money) Identifier(org.hl7.fhir.dstu3.model.Identifier) Coding(org.hl7.fhir.dstu3.model.Coding) ItemComponent(org.hl7.fhir.dstu3.model.Claim.ItemComponent) SupplyDeliverySuppliedItemComponent(org.hl7.fhir.dstu3.model.SupplyDelivery.SupplyDeliverySuppliedItemComponent) Encounter(org.mitre.synthea.world.concepts.HealthRecord.Encounter) Payer(org.mitre.synthea.world.agents.Payer) Reference(org.hl7.fhir.dstu3.model.Reference) Calendar(java.util.Calendar) Period(org.hl7.fhir.dstu3.model.Period) SimpleQuantity(org.hl7.fhir.dstu3.model.SimpleQuantity) Quantity(org.hl7.fhir.dstu3.model.Quantity) Coverage(org.hl7.fhir.dstu3.model.Coverage) Extension(org.hl7.fhir.dstu3.model.Extension) EncounterType(org.mitre.synthea.world.concepts.HealthRecord.EncounterType) Claim(org.mitre.synthea.world.concepts.Claim) CodeableConcept(org.hl7.fhir.dstu3.model.CodeableConcept)

Aggregations

ArrayList (java.util.ArrayList)21 Element (org.w3c.dom.Element)11 IOException (java.io.IOException)10 LinkedHashMap (java.util.LinkedHashMap)9 Section (org.hl7.fhir.utilities.xml.SchematronWriter.Section)9 POCDMT000002UK01Section (uk.nhs.connect.iucds.cda.ucr.POCDMT000002UK01Section)8 Rule (org.hl7.fhir.utilities.xml.SchematronWriter.Rule)7 POCDMT000002UK01Component3 (uk.nhs.connect.iucds.cda.ucr.POCDMT000002UK01Component3)7 Reference (org.hl7.fhir.dstu3.model.Reference)6 XhtmlNode (org.hl7.fhir.utilities.xhtml.XhtmlNode)6 SectionComponent (org.hl7.fhir.dstu3.model.Composition.SectionComponent)5 CodeableConcept (org.hl7.fhir.r4.model.CodeableConcept)5 BeforeEach (org.junit.jupiter.api.BeforeEach)5 HashMap (java.util.HashMap)4 NotImplementedException (org.apache.commons.lang3.NotImplementedException)4 IdType (org.hl7.fhir.dstu3.model.IdType)4 Section (org.hl7.fhir.utilities.turtle.Turtle.Section)4 Subject (org.hl7.fhir.utilities.turtle.Turtle.Subject)4 POCDMT000002UK01Component5 (uk.nhs.connect.iucds.cda.ucr.POCDMT000002UK01Component5)4 FileNotFoundException (java.io.FileNotFoundException)3