Search in sources :

Example 1 with CARRIER

use of org.mitre.synthea.export.BB2RIFStructure.CARRIER in project synthea by synthetichealth.

the class BB2RIFExporterTest method testStaticFieldConfig.

@Test
public void testStaticFieldConfig() throws IOException, NoSuchMethodException {
    RandomNumberGenerator rand = new Person(System.currentTimeMillis());
    assertEquals("foo", StaticFieldConfig.processCell("foo", rand));
    String randomVal = StaticFieldConfig.processCell("1, 2, 3", rand);
    assertTrue(randomVal.equalsIgnoreCase("1") || randomVal.equalsIgnoreCase("2") || randomVal.equalsIgnoreCase("3"));
    StaticFieldConfig config = new StaticFieldConfig();
    assertEquals("INSERT", config.getValue("DML_IND", INPATIENT.class));
    assertEquals("82 (DMEPOS)", config.getValue("NCH_CLM_TYPE_CD", DME.class));
    assertEquals("71 (local carrier, non-DME)", config.getValue("NCH_CLM_TYPE_CD", CARRIER.class));
    HashMap<BENEFICIARY, String> values = new HashMap<>();
    config.setValues(values, BENEFICIARY.class, rand);
    assertEquals("INSERT", values.get(BENEFICIARY.DML_IND));
    String sexIdent = values.get(BENEFICIARY.BENE_SEX_IDENT_CD);
    assertTrue(sexIdent.equals("1") || sexIdent.equals("2"));
}
Also used : BENEFICIARY(org.mitre.synthea.export.BB2RIFStructure.BENEFICIARY) RandomNumberGenerator(org.mitre.synthea.helpers.RandomNumberGenerator) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) StaticFieldConfig(org.mitre.synthea.export.BB2RIFExporter.StaticFieldConfig) Person(org.mitre.synthea.world.agents.Person) DME(org.mitre.synthea.export.BB2RIFStructure.DME) INPATIENT(org.mitre.synthea.export.BB2RIFStructure.INPATIENT) CARRIER(org.mitre.synthea.export.BB2RIFStructure.CARRIER) Test(org.junit.Test)

Example 2 with CARRIER

use of org.mitre.synthea.export.BB2RIFStructure.CARRIER in project synthea by synthetichealth.

the class BB2RIFExporter method exportCarrier.

/**
 * Export carrier claims details for a single person.
 * @param person the person to export
 * @param startTime earliest claim date to export
 * @param stopTime end time of simulation
 * @throws IOException if something goes wrong
 */
private void exportCarrier(Person person, long startTime, long stopTime) throws IOException {
    HashMap<CARRIER, String> fieldValues = new HashMap<>();
    double latestHemoglobin = 0;
    for (HealthRecord.Encounter encounter : person.record.encounters) {
        if (encounter.stop < startTime) {
            continue;
        }
        boolean isPrimary = (ProviderType.PRIMARY == encounter.provider.type);
        boolean isWellness = encounter.type.equals(EncounterType.WELLNESS.toString());
        boolean isUrgent = encounter.type.equals(EncounterType.URGENTCARE.toString());
        // IHS facilities have valid 6 digit id, IHS centers don't
        boolean isIHSCenter = (ProviderType.IHS == encounter.provider.type) && encounter.provider.id.length() != 6;
        boolean isVA = (ProviderType.VETERAN == encounter.provider.type);
        if (isVA || !(isIHSCenter || isPrimary || isWellness || isUrgent)) {
            continue;
        }
        long claimId = BB2RIFExporter.claimId.getAndDecrement();
        int claimGroupId = BB2RIFExporter.claimGroupId.getAndDecrement();
        long carrClmId = BB2RIFExporter.carrClmCntlNum.getAndDecrement();
        for (HealthRecord.Observation observation : encounter.observations) {
            if (observation.containsCode("718-7", "http://loinc.org")) {
                latestHemoglobin = (double) observation.value;
            }
        }
        staticFieldConfig.setValues(fieldValues, CARRIER.class, person);
        fieldValues.put(CARRIER.BENE_ID, (String) person.attributes.get(BB2_BENE_ID));
        // The REQUIRED fields
        fieldValues.put(CARRIER.CLM_ID, "" + claimId);
        fieldValues.put(CARRIER.CLM_GRP_ID, "" + claimGroupId);
        fieldValues.put(CARRIER.CARR_CLM_CNTL_NUM, "" + carrClmId);
        fieldValues.put(CARRIER.CLM_FROM_DT, bb2DateFromTimestamp(encounter.start));
        fieldValues.put(CARRIER.LINE_1ST_EXPNS_DT, bb2DateFromTimestamp(encounter.start));
        fieldValues.put(CARRIER.CLM_THRU_DT, bb2DateFromTimestamp(encounter.stop));
        fieldValues.put(CARRIER.LINE_LAST_EXPNS_DT, bb2DateFromTimestamp(encounter.stop));
        fieldValues.put(CARRIER.NCH_WKLY_PROC_DT, bb2DateFromTimestamp(ExportHelper.nextFriday(encounter.stop)));
        fieldValues.put(CARRIER.CARR_NUM, getCarrier(encounter.provider.state, CARRIER.CARR_NUM));
        fieldValues.put(CARRIER.CLM_PMT_AMT, String.format("%.2f", encounter.claim.getTotalClaimCost()));
        if (encounter.claim.payer == Payer.getGovernmentPayer(HealthInsuranceModule.MEDICARE)) {
            fieldValues.put(CARRIER.CARR_CLM_PRMRY_PYR_PD_AMT, "0");
        } else {
            fieldValues.put(CARRIER.CARR_CLM_PRMRY_PYR_PD_AMT, String.format("%.2f", encounter.claim.getCoveredCost()));
        }
        fieldValues.put(CARRIER.NCH_CLM_PRVDR_PMT_AMT, String.format("%.2f", encounter.claim.getTotalClaimCost()));
        fieldValues.put(CARRIER.NCH_CARR_CLM_SBMTD_CHRG_AMT, String.format("%.2f", encounter.claim.getTotalClaimCost()));
        fieldValues.put(CARRIER.NCH_CARR_CLM_ALOWD_AMT, String.format("%.2f", encounter.claim.getCoveredCost()));
        fieldValues.put(CARRIER.CARR_CLM_CASH_DDCTBL_APLD_AMT, String.format("%.2f", encounter.claim.getDeductiblePaid()));
        fieldValues.put(CARRIER.CARR_CLM_RFRNG_PIN_NUM, encounter.provider.id);
        fieldValues.put(CARRIER.CARR_PRFRNG_PIN_NUM, encounter.provider.id);
        fieldValues.put(CARRIER.ORG_NPI_NUM, encounter.provider.npi);
        fieldValues.put(CARRIER.PRF_PHYSN_NPI, encounter.clinician.npi);
        fieldValues.put(CARRIER.RFR_PHYSN_NPI, encounter.clinician.npi);
        fieldValues.put(CARRIER.PRVDR_SPCLTY, ClinicianSpecialty.getCMSProviderSpecialtyCode((String) encounter.clinician.attributes.get(Clinician.SPECIALTY)));
        fieldValues.put(CARRIER.TAX_NUM, bb2TaxId((String) encounter.clinician.attributes.get(Person.IDENTIFIER_SSN)));
        fieldValues.put(CARRIER.LINE_SRVC_CNT, "" + encounter.claim.items.size());
        fieldValues.put(CARRIER.CARR_LINE_PRCNG_LCLTY_CD, getCarrier(encounter.provider.state, CARRIER.CARR_LINE_PRCNG_LCLTY_CD));
        fieldValues.put(CARRIER.LINE_NCH_PMT_AMT, String.format("%.2f", encounter.claim.getCoveredCost()));
        // length of encounter in minutes
        fieldValues.put(CARRIER.CARR_LINE_MTUS_CNT, "" + ((encounter.stop - encounter.start) / (1000 * 60)));
        fieldValues.put(CARRIER.LINE_HCT_HGB_RSLT_NUM, "" + latestHemoglobin);
        // OPTIONAL
        String icdReasonCode = null;
        if (encounter.reason != null) {
            // values into the principle diagnoses code.
            if (conditionCodeMapper.canMap(encounter.reason.code)) {
                icdReasonCode = conditionCodeMapper.map(encounter.reason.code, person, true);
                fieldValues.put(CARRIER.PRNCPAL_DGNS_CD, icdReasonCode);
                fieldValues.put(CARRIER.LINE_ICD_DGNS_CD, icdReasonCode);
            }
        }
        // Use the active condition diagnoses to enter mapped values
        // into the diagnoses codes.
        List<String> mappedDiagnosisCodes = getDiagnosesCodes(person, encounter.stop);
        if (mappedDiagnosisCodes.isEmpty() && icdReasonCode == null) {
            // skip this encounter
            continue;
        }
        int smallest = Math.min(mappedDiagnosisCodes.size(), BB2RIFStructure.carrierDxFields.length);
        for (int i = 0; i < smallest; i++) {
            CARRIER[] dxField = BB2RIFStructure.carrierDxFields[i];
            fieldValues.put(dxField[0], mappedDiagnosisCodes.get(i));
            // 0=ICD10
            fieldValues.put(dxField[1], "0");
        }
        if (!fieldValues.containsKey(CARRIER.PRNCPAL_DGNS_CD)) {
            fieldValues.put(CARRIER.PRNCPAL_DGNS_CD, mappedDiagnosisCodes.get(0));
        }
        synchronized (rifWriters.getOrCreateWriter(CARRIER.class)) {
            int lineNum = 1;
            CLIA cliaLab = cliaLabNumbers[person.randInt(cliaLabNumbers.length)];
            for (ClaimEntry lineItem : encounter.claim.items) {
                String hcpcsCode = "";
                String ndcCode = "";
                if (lineItem.entry instanceof HealthRecord.Procedure) {
                    for (HealthRecord.Code code : lineItem.entry.codes) {
                        if (hcpcsCodeMapper.canMap(code.code)) {
                            hcpcsCode = hcpcsCodeMapper.map(code.code, person, true);
                            // take the first mappable code for each procedure
                            break;
                        }
                    }
                } else if (lineItem.entry instanceof HealthRecord.Medication) {
                    HealthRecord.Medication med = (HealthRecord.Medication) lineItem.entry;
                    if (med.administration) {
                        // Administration of medication
                        hcpcsCode = "T1502";
                        ndcCode = medicationCodeMapper.map(med.codes.get(0).code, person);
                    }
                }
                // TBD: decide whether line item skip logic is needed here and in other files
                // TBD: affects ~80% of carrier claim lines, so left out for now
                // if (hcpcsCode == null) {
                // continue; // skip this line item
                // }
                fieldValues.put(CARRIER.HCPCS_CD, hcpcsCode);
                if (betosCodeMapper.canMap(hcpcsCode)) {
                    fieldValues.put(CARRIER.BETOS_CD, betosCodeMapper.map(hcpcsCode, person));
                } else {
                    fieldValues.put(CARRIER.BETOS_CD, "");
                }
                fieldValues.put(CARRIER.LINE_NDC_CD, ndcCode);
                fieldValues.put(CARRIER.LINE_BENE_PTB_DDCTBL_AMT, String.format("%.2f", lineItem.deductible));
                fieldValues.put(CARRIER.LINE_COINSRNC_AMT, String.format("%.2f", lineItem.coinsurance));
                fieldValues.put(CARRIER.LINE_BENE_PMT_AMT, String.format("%.2f", lineItem.copay + lineItem.deductible + lineItem.pocket));
                fieldValues.put(CARRIER.LINE_PRVDR_PMT_AMT, String.format("%.2f", lineItem.coinsurance + lineItem.payer));
                fieldValues.put(CARRIER.LINE_SBMTD_CHRG_AMT, String.format("%.2f", lineItem.cost));
                fieldValues.put(CARRIER.LINE_ALOWD_CHRG_AMT, String.format("%.2f", lineItem.cost - lineItem.adjustment));
                // If this item is a lab report, add the number of the clinical lab...
                if (lineItem.entry instanceof HealthRecord.Report) {
                    fieldValues.put(CARRIER.CARR_LINE_CLIA_LAB_NUM, cliaLab.toString());
                }
                // set the line number and write out field values
                fieldValues.put(CARRIER.LINE_NUM, Integer.toString(lineNum++));
                rifWriters.writeValues(CARRIER.class, fieldValues);
            }
            if (lineNum == 1) {
                // If lineNum still equals 1, then no line items were successfully added.
                // Add a single top-level entry.
                fieldValues.put(CARRIER.LINE_NUM, Integer.toString(lineNum));
                fieldValues.put(CARRIER.LINE_BENE_PTB_DDCTBL_AMT, String.format("%.2f", encounter.claim.getDeductiblePaid()));
                fieldValues.put(CARRIER.LINE_COINSRNC_AMT, String.format("%.2f", encounter.claim.getCoinsurancePaid()));
                fieldValues.put(CARRIER.LINE_SBMTD_CHRG_AMT, String.format("%.2f", encounter.claim.getTotalClaimCost()));
                fieldValues.put(CARRIER.LINE_ALOWD_CHRG_AMT, String.format("%.2f", encounter.claim.getCoveredCost()));
                fieldValues.put(CARRIER.LINE_PRVDR_PMT_AMT, String.format("%.2f", encounter.claim.getCoveredCost()));
                fieldValues.put(CARRIER.LINE_BENE_PMT_AMT, String.format("%.2f", encounter.claim.getPatientCost()));
                // 99241: "Office consultation for a new or established patient"
                fieldValues.put(CARRIER.HCPCS_CD, "99241");
                rifWriters.writeValues(CARRIER.class, fieldValues);
            }
        }
    }
}
Also used : Medication(org.mitre.synthea.world.concepts.HealthRecord.Medication) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) CARRIER(org.mitre.synthea.export.BB2RIFStructure.CARRIER) ClaimEntry(org.mitre.synthea.world.concepts.Claim.ClaimEntry) HealthRecord(org.mitre.synthea.world.concepts.HealthRecord) Code(org.mitre.synthea.world.concepts.HealthRecord.Code) Medication(org.mitre.synthea.world.concepts.HealthRecord.Medication)

Aggregations

HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 CARRIER (org.mitre.synthea.export.BB2RIFStructure.CARRIER)2 Test (org.junit.Test)1 StaticFieldConfig (org.mitre.synthea.export.BB2RIFExporter.StaticFieldConfig)1 BENEFICIARY (org.mitre.synthea.export.BB2RIFStructure.BENEFICIARY)1 DME (org.mitre.synthea.export.BB2RIFStructure.DME)1 INPATIENT (org.mitre.synthea.export.BB2RIFStructure.INPATIENT)1 RandomNumberGenerator (org.mitre.synthea.helpers.RandomNumberGenerator)1 Person (org.mitre.synthea.world.agents.Person)1 ClaimEntry (org.mitre.synthea.world.concepts.Claim.ClaimEntry)1 HealthRecord (org.mitre.synthea.world.concepts.HealthRecord)1 Code (org.mitre.synthea.world.concepts.HealthRecord.Code)1 Medication (org.mitre.synthea.world.concepts.HealthRecord.Medication)1