Search in sources :

Example 1 with Device

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

the class CPCDSExporter method claim.

/**
 * Method to write a single Claims file. Take an encounter in the parameters and
 * processes Diagnoses, Procedures, and Pharmacy claims for each one, in order.
 *
 * @param rand            Source of randomness to use when generating ids etc
 * @param encounter       The encounter object itself
 * @param personID        The Id of the involved patient
 * @param encounterID     The Id of the encounter
 * @param medRecordNumber The patients Medical Record Number
 * @param attributes      Calculated attributes for the entire encounter
 * @param payerId         The Id of the payer
 * @throws IOException Throws this exception
 */
private void claim(RandomNumberGenerator rand, Encounter encounter, String personID, String encounterID, UUID medRecordNumber, CPCDSAttributes attributes, String payerId, String coverageID) throws IOException {
    StringBuilder s = new StringBuilder();
    int i = 1;
    while (i <= attributes.getLength()) {
        // admin
        String billType = attributes.getBillTypeCode();
        String[] adminSection = { String.valueOf(dateFromTimestamp(encounter.start)), String.valueOf(dateFromTimestamp(encounter.stop)), String.valueOf(dateFromTimestamp(encounter.stop)), String.valueOf(dateFromTimestamp(encounter.start)), String.valueOf(dateFromTimestamp(encounter.start)), String.valueOf(dateFromTimestamp(encounter.stop)), personID.toString(), medRecordNumber.toString(), encounterID, "", "", "", attributes.getSourceAdminCode(), attributes.getAdmissionTypeCode(), Character.toString(billType.charAt(0)), Character.toString(billType.charAt(1)), Character.toString(billType.charAt(2)), attributes.getProcStatus(), attributes.getClaimType(), attributes.getDischarge(), attributes.getDenialCode(), coverageID, attributes.getPayeeType(), personID, attributes.getPaymentType(), coverageID };
        StringBuilder admin = new StringBuilder();
        for (String item : adminSection) {
            admin.append(item).append(',');
        }
        String adminString = admin.toString();
        // provider
        practitioner(encounter.clinician.attributes.get("specialty").toString(), attributes.getNpiProvider(), attributes.getServiceSiteNPI(), encounter.clinician.getFullname());
        String[] providerSection = { attributes.getNpiProvider(), attributes.getNetworkStatus(), attributes.getNpiProvider(), attributes.getNetworkStatus(), attributes.getServiceSiteNPI(), attributes.getNetworkStatus(), attributes.getNpiProvider(), attributes.getNetworkStatus(), attributes.getNpiProvider(), attributes.getNetworkStatus(), attributes.getNpiPrescribingProvider(), attributes.getNetworkStatus(), attributes.getNpiProvider() };
        StringBuilder provider = new StringBuilder();
        for (String item : providerSection) {
            provider.append(item).append(',');
        }
        String providerString = provider.toString();
        // totals
        // encounter.claim.getTotalClaimCost();
        BigDecimal totalCost = attributes.getTotalClaimCost();
        BigDecimal coveredCost = encounter.claim.getCoveredCost();
        BigDecimal disallowed = totalCost.subtract(coveredCost);
        BigDecimal patientPaid = Claim.ZERO_CENTS;
        BigDecimal memberReimbursement = Claim.ZERO_CENTS;
        BigDecimal paymentAmount = Claim.ZERO_CENTS;
        BigDecimal toProvider = Claim.ZERO_CENTS;
        BigDecimal deductible = encounter.claim.person.coverage.getTotalCoverage();
        BigDecimal liability = Claim.ZERO_CENTS;
        BigDecimal copay = Claim.ZERO_CENTS;
        if (disallowed.compareTo(Claim.ZERO_CENTS) > 0) {
            memberReimbursement = Claim.ZERO_CENTS;
            patientPaid = disallowed;
        } else {
            memberReimbursement = disallowed.negate();
            disallowed = Claim.ZERO_CENTS;
            patientPaid = Claim.ZERO_CENTS;
        }
        paymentAmount = coveredCost.add(patientPaid);
        toProvider = paymentAmount;
        liability = totalCost.subtract(paymentAmount);
        String[] claimTotalsSection = { String.valueOf(paymentAmount), String.valueOf(totalCost), String.valueOf(patientPaid), String.valueOf(toProvider), String.valueOf(memberReimbursement), String.valueOf(paymentAmount), String.valueOf(disallowed), String.valueOf(deductible), String.valueOf(""), String.valueOf(copay), String.valueOf(liability), String.valueOf(coveredCost), String.valueOf(0.00) };
        StringBuilder totals = new StringBuilder();
        for (String item : claimTotalsSection) {
            totals.append(item).append(',');
        }
        String totalsString = totals.toString();
        String pharmacyEMPTY = ",,,,,,," + attributes.getResidence() + ",";
        String procedureEMPTY = ",,,,,,,,";
        // diagnosis
        for (Entry condition : encounter.conditions) {
            StringBuilder cond = new StringBuilder();
            String presentOnAdmission;
            String[] poaCodes = { "Y", "N", "U", "W" };
            presentOnAdmission = poaCodes[(int) randomLongWithBounds(0, 3)];
            cond.append(adminString);
            cond.append(pharmacyEMPTY);
            cond.append(providerString);
            cond.append(totalsString);
            cond.append(dateFromTimestamp(condition.start)).append(',');
            cond.append(i).append(',');
            cond.append(dateFromTimestamp(condition.stop)).append(',');
            cond.append("").append(',');
            cond.append(attributes.getPlaceOfService()).append(',');
            cond.append(attributes.getRevenueCenterCode()).append(',');
            cond.append("").append(',');
            cond.append("").append(',');
            cond.append("").append(',');
            cond.append("").append(',');
            cond.append("").append(',');
            cond.append("").append(',');
            cond.append(attributes.getBenefitPaymentStatus()).append(',');
            cond.append(attributes.getDenialCode()).append(',');
            BigDecimal cost = condition.getCost();
            cond.append(0.00).append(',');
            cond.append(0.00).append(',');
            cond.append(0.00).append(',');
            cond.append("").append(',');
            cond.append(cost).append(',');
            cond.append(cost).append(',');
            cond.append(encounter.claim.person.coverage.getTotalCoverage()).append(',');
            cond.append(cost).append(',');
            cond.append(0.00).append(',');
            cond.append(cost).append(',');
            cond.append(cost).append(',');
            cond.append(0.00).append(',');
            cond.append(0.00).append(',');
            cond.append(0.00).append(',');
            Code coding = condition.codes.get(0);
            String diagnosisCode = "SNOMED";
            String diagnosisType = "principal";
            cond.append(coding.code).append(',');
            cond.append(clean(coding.display)).append(',');
            cond.append(presentOnAdmission).append(',');
            cond.append(diagnosisCode).append(',');
            cond.append(diagnosisType).append(',');
            cond.append("").append(',');
            cond.append(procedureEMPTY).append(NEWLINE);
            s.append(cond.toString());
            i++;
        }
        // procedures
        int k = 0;
        for (Procedure procedure : encounter.procedures) {
            String presentOnAdmission;
            String diagnosisCode = "SNOMED";
            String diagnosisType = "principal";
            String procedureType;
            if (k == 0) {
                procedureType = "primary";
            } else {
                procedureType = "secondary";
            }
            String[] poaCodes = { "Y", "N", "U", "W" };
            presentOnAdmission = poaCodes[(int) randomLongWithBounds(0, 3)];
            StringBuilder proc = new StringBuilder();
            proc.append(adminString);
            proc.append(",").append(",").append(",").append(",").append(",").append(",");
            proc.append("01,").append(attributes.getResidence()).append(',');
            proc.append(providerString);
            proc.append(totalsString);
            String typeOfService = "01";
            if (attributes.getNetworkStatus().equals("out")) {
                typeOfService = "11";
            }
            proc.append(dateFromTimestamp(procedure.start)).append(',');
            proc.append(i).append(',');
            proc.append(dateFromTimestamp(procedure.stop)).append(',');
            proc.append(typeOfService).append(',');
            proc.append(attributes.getPlaceOfService()).append(',');
            proc.append(attributes.getRevenueCenterCode()).append(',');
            proc.append("").append(',');
            proc.append("").append(',');
            proc.append("").append(',');
            proc.append("").append(',');
            proc.append("").append(',');
            proc.append("").append(',');
            proc.append(attributes.getBenefitPaymentStatus()).append(',');
            proc.append(attributes.getDenialCode()).append(',');
            BigDecimal cost = procedure.getCost();
            proc.append(0.00).append(',');
            proc.append(0.00).append(',');
            proc.append(0.00).append(',');
            proc.append("").append(',');
            proc.append(cost).append(',');
            proc.append(cost).append(',');
            proc.append(encounter.claim.person.coverage.getTotalCoverage()).append(',');
            proc.append(cost).append(',');
            proc.append(0.00).append(',');
            proc.append(cost).append(',');
            proc.append(cost).append(',');
            proc.append(0.00).append(',');
            proc.append(0.00).append(',');
            proc.append(0.00).append(',');
            if (procedure.reasons.size() != 0) {
                Code reasons = procedure.reasons.get(0);
                proc.append(reasons.code).append(',');
                proc.append(clean(reasons.display)).append(',');
                proc.append(presentOnAdmission).append(',');
                proc.append(diagnosisCode).append(',');
                proc.append(diagnosisType).append(',');
            } else {
                proc.append("").append(',');
                proc.append("").append(',');
                proc.append("").append(',');
                proc.append("").append(',');
                proc.append("").append(',');
            }
            proc.append("").append(',');
            Code procedureCode = procedure.codes.get(0);
            proc.append(procedureCode.code).append(',');
            proc.append(clean(procedureCode.display)).append(',');
            proc.append(dateFromTimestamp(procedure.start)).append(',');
            proc.append(diagnosisCode).append(',');
            proc.append(procedureType).append(',');
            proc.append("").append(',');
            proc.append("").append(',');
            proc.append("").append(',');
            proc.append("").append(NEWLINE);
            s.append(proc.toString());
            i++;
        }
        // pharmacy
        for (Medication medication : encounter.medications) {
            StringBuilder med = new StringBuilder();
            String presentOnAdmission;
            String diagnosisCode = "SNOMED";
            String diagnosisType = "principal";
            String[] poaCodes = { "Y", "N", "U", "W" };
            presentOnAdmission = poaCodes[(int) randomLongWithBounds(0, 3)];
            String[] brandGenericList = { "b", "g" };
            String brandGenericCode = brandGenericList[(int) randomLongWithBounds(0, 1)];
            String[] dawCodeList = { "1", "2", "3", "4", "7", "1", "3", "5", "8" };
            String dawCode;
            if (brandGenericCode.equals("b")) {
                dawCode = dawCodeList[(int) randomLongWithBounds(0, 4)];
            } else {
                if (brandGenericCode.equals("g")) {
                    dawCode = dawCodeList[(int) randomLongWithBounds(5, 8)];
                } else {
                    dawCode = "0";
                }
            }
            /*
         * {"dosage": {"amount":1,"frequency":2,"period":1,"unit":"days"},
         * "duration":{"quantity":2,"unit":"weeks"}, "instructions":[ {
         * "system":"SNOMED-CT", "code":"code", "display":"display string"} ] }
         */
            JsonObject medicationDetails = medication.prescriptionDetails;
            Dictionary<String, Integer> dayMultiplier = new Hashtable<String, Integer>();
            dayMultiplier.put("hours", 1);
            dayMultiplier.put("days", 1);
            dayMultiplier.put("weeks", 2);
            dayMultiplier.put("months", 30);
            dayMultiplier.put("years", 365);
            int dailyDosage;
            int daysSupply;
            JsonObject dosage;
            JsonObject duration;
            if (medicationDetails == null || medicationDetails.has("as_needed")) {
                dailyDosage = 0;
                daysSupply = 0;
            } else {
                if (medicationDetails != null && medicationDetails.has("dosage")) {
                    dosage = medicationDetails.get("dosage").getAsJsonObject();
                    if (dosage.has("amount") == false) {
                        dosage.addProperty("amount", 0);
                    }
                    if (dosage.has("frequency") == false) {
                        dosage.addProperty("frequency", 0);
                    }
                    if (dosage.has("period") == false) {
                        dosage.addProperty("period", 0);
                    }
                    if (dosage.has("unit") == false) {
                        dosage.addProperty("unit", "days");
                    }
                } else {
                    dosage = new JsonObject();
                    dosage.addProperty("amount", 0);
                    dosage.addProperty("frequency", 0);
                    dosage.addProperty("period", 0);
                    dosage.addProperty("unit", "days");
                }
                if (medicationDetails != null && medicationDetails.has("duration")) {
                    duration = medicationDetails.get("duration").getAsJsonObject();
                    if (duration.has("quantity") == false) {
                        duration.addProperty("quantity", 0);
                    }
                    if (duration.has("unit") == false) {
                        duration.addProperty("unit", "days");
                    }
                } else {
                    duration = new JsonObject();
                    duration.addProperty("quantity", 0);
                    duration.addProperty("unit", "days");
                }
                dailyDosage = dosage.get("amount").getAsInt() * dosage.get("frequency").getAsInt() * dosage.get("period").getAsInt() * (int) dayMultiplier.get(dosage.get("unit").getAsString());
                daysSupply = duration.get("quantity").getAsInt() * dayMultiplier.get(duration.get("unit").getAsString());
            }
            UUID rxRef = rand.randUUID();
            String[] serviceTypeList = { "01", "04", "06" };
            String serviceType = serviceTypeList[(int) randomLongWithBounds(0, 2)];
            med.append(adminString);
            med.append(daysSupply).append(',');
            med.append(rxRef).append(',');
            med.append(dawCode).append(',');
            med.append("0").append(',');
            med.append("0").append(',');
            med.append(brandGenericCode).append(',');
            med.append(serviceType).append(',');
            med.append(attributes.getResidence()).append(',');
            med.append(providerString);
            med.append(totalsString);
            Code coding = medication.codes.get(0);
            med.append(dateFromTimestamp(medication.start)).append(',');
            med.append(i).append(',');
            med.append(dateFromTimestamp(medication.stop)).append(',');
            med.append("16").append(',');
            med.append("01").append(',');
            med.append(attributes.getRevenueCenterCode()).append(',');
            med.append(dailyDosage * daysSupply).append(',');
            med.append(dailyDosage * daysSupply).append(',');
            med.append(coding.code).append(',');
            med.append(randomLongWithBounds(0, 2)).append(',');
            med.append(dailyDosage * daysSupply).append(',');
            med.append("UN").append(',');
            med.append(attributes.getBenefitPaymentStatus()).append(',');
            med.append(attributes.getDenialCode()).append(',');
            BigDecimal cost = medication.getCost();
            med.append(0.00).append(',');
            med.append(0.00).append(',');
            med.append(0.00).append(',');
            med.append((dailyDosage == 0 || daysSupply == 0 ? 0 : cost.longValue() / (dailyDosage * daysSupply))).append(',');
            med.append(cost).append(',');
            med.append(cost).append(',');
            med.append(encounter.claim.person.coverage.getTotalCoverage()).append(',');
            med.append(cost).append(',');
            med.append(0.00).append(',');
            med.append(cost).append(',');
            med.append(cost).append(',');
            med.append(0.00).append(',');
            med.append(0.00).append(',');
            med.append(0.00).append(',');
            if (medication.reasons.size() != 0) {
                Code reasons = medication.reasons.get(0);
                med.append(reasons.code).append(',');
                med.append(clean(reasons.display)).append(',');
                med.append(presentOnAdmission).append(',');
                med.append(diagnosisCode).append(',');
                med.append(diagnosisType).append(',');
            } else {
                med.append("").append(',');
                med.append("").append(',');
                med.append("").append(',');
                med.append("").append(',');
                med.append("").append(',');
            }
            med.append("").append(',');
            med.append(procedureEMPTY).append(NEWLINE);
            s.append(med.toString());
            i++;
        }
        // Devices
        for (Device device : encounter.devices) {
            StringBuilder dev = new StringBuilder();
            dev.append(adminString);
            dev.append(",").append(",").append(",").append(",").append(",").append(",");
            dev.append("01,").append(attributes.getResidence()).append(',');
            dev.append(providerString);
            dev.append(totalsString);
            String typeOfService = "01";
            if (attributes.getNetworkStatus().equals("out")) {
                typeOfService = "11";
            }
            dev.append(dateFromTimestamp(device.start)).append(',');
            dev.append(i).append(',');
            dev.append(dateFromTimestamp(device.stop)).append(',');
            dev.append(typeOfService).append(',');
            dev.append(attributes.getPlaceOfService()).append(',');
            dev.append(attributes.getRevenueCenterCode()).append(',');
            dev.append("").append(',');
            dev.append("").append(',');
            dev.append("").append(',');
            dev.append("").append(',');
            dev.append("").append(',');
            dev.append("").append(',');
            dev.append(attributes.getBenefitPaymentStatus()).append(',');
            dev.append(attributes.getDenialCode()).append(',');
            BigDecimal cost = device.getCost();
            dev.append(0.00).append(',');
            dev.append(0.00).append(',');
            dev.append(0.00).append(',');
            dev.append("").append(',');
            dev.append(cost).append(',');
            dev.append(cost).append(',');
            dev.append(encounter.claim.person.coverage.getTotalCoverage()).append(',');
            dev.append(cost).append(',');
            dev.append(0.00).append(',');
            dev.append(cost).append(',');
            dev.append(cost).append(',');
            dev.append(0.00).append(',');
            dev.append(0.00).append(',');
            dev.append(0.00).append(',');
            dev.append("").append(',');
            dev.append("").append(',');
            dev.append("").append(',');
            dev.append("").append(',');
            dev.append("").append(',');
            dev.append("").append(',');
            String diagnosisCode = "SNOMED";
            String deviceType = "";
            Code deviceCode = device.codes.get(0);
            dev.append(deviceCode.code).append(',');
            dev.append(clean(deviceCode.display)).append(',');
            dev.append(dateFromTimestamp(device.start)).append(',');
            dev.append(diagnosisCode).append(',');
            dev.append(deviceType).append(',');
            dev.append("").append(',');
            dev.append("").append(',');
            dev.append("").append(',');
            dev.append("").append(NEWLINE);
            s.append(dev.toString());
            i++;
        }
    }
    write(s.toString(), claims);
}
Also used : Hashtable(java.util.Hashtable) Device(org.mitre.synthea.world.concepts.HealthRecord.Device) JsonObject(com.google.gson.JsonObject) Code(org.mitre.synthea.world.concepts.HealthRecord.Code) BigDecimal(java.math.BigDecimal) Entry(org.mitre.synthea.world.concepts.HealthRecord.Entry) Medication(org.mitre.synthea.world.concepts.HealthRecord.Medication) Procedure(org.mitre.synthea.world.concepts.HealthRecord.Procedure) UUID(java.util.UUID)

Example 2 with Device

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

the class CSVExporter method export.

/**
 * Add a single Person's health record info to the CSV records.
 *
 * @param person Person to write record data for
 * @param time   Time the simulation ended
 * @throws IOException if any IO error occurs
 */
public void export(Person person, long time) throws IOException {
    String personID = patient(person, time);
    for (Encounter encounter : person.record.encounters) {
        String encounterID = encounter(person, personID, encounter);
        String payerID = encounter.claim.payer.uuid;
        claim(person, encounter.claim, encounter, encounterID, time);
        for (HealthRecord.Entry condition : encounter.conditions) {
            /* condition to ignore codes other then retrieved from terminology url */
            if (!StringUtils.isEmpty(Config.get("generate.terminology_service_url")) && !RandomCodeGenerator.selectedCodes.isEmpty()) {
                if (RandomCodeGenerator.selectedCodes.stream().filter(code -> code.code.equals(condition.codes.get(0).code)).findFirst().isPresent()) {
                    condition(personID, encounterID, condition);
                }
            } else {
                condition(personID, encounterID, condition);
            }
        }
        for (HealthRecord.Allergy allergy : encounter.allergies) {
            allergy(personID, encounterID, allergy);
        }
        for (Observation observation : encounter.observations) {
            observation(personID, encounterID, observation);
        }
        for (Procedure procedure : encounter.procedures) {
            procedure(personID, encounterID, procedure);
        }
        for (Medication medication : encounter.medications) {
            medication(personID, encounterID, payerID, medication, time);
            claim(person, medication.claim, encounter, encounterID, time);
        }
        for (HealthRecord.Entry immunization : encounter.immunizations) {
            immunization(personID, encounterID, immunization);
        }
        for (CarePlan careplan : encounter.careplans) {
            careplan(person, personID, encounterID, careplan);
        }
        for (ImagingStudy imagingStudy : encounter.imagingStudies) {
            imagingStudy(person, personID, encounterID, imagingStudy);
        }
        for (Device device : encounter.devices) {
            device(personID, encounterID, device);
        }
        for (Supply supply : encounter.supplies) {
            supply(personID, encounterID, encounter, supply);
        }
    }
    CSVExporter.getInstance().exportPayerTransitions(person, time);
    int yearsOfHistory = Integer.parseInt(Config.get("exporter.years_of_history"));
    Calendar cutOff = new GregorianCalendar(1900, 0, 1);
    if (yearsOfHistory > 0) {
        cutOff = Calendar.getInstance();
        cutOff.set(cutOff.get(Calendar.YEAR) - yearsOfHistory, 0, 1);
    }
    Calendar now = Calendar.getInstance();
    Calendar birthDay = Calendar.getInstance();
    birthDay.setTimeInMillis((long) person.attributes.get(Person.BIRTHDATE));
    String[] gbdMetrics = { QualityOfLifeModule.QALY, QualityOfLifeModule.DALY, QualityOfLifeModule.QOLS };
    String unit = null;
    for (String score : gbdMetrics) {
        if (score.equals(QualityOfLifeModule.QOLS)) {
            unit = "{score}";
        } else {
            // years in UCUM is "a" for Latin "Annus"
            unit = "a";
        }
        @SuppressWarnings("unchecked") Map<Integer, Double> scores = (Map<Integer, Double>) person.attributes.get(score);
        for (Integer year : scores.keySet()) {
            birthDay.set(Calendar.YEAR, year);
            if (birthDay.after(cutOff) && birthDay.before(now)) {
                Observation obs = person.record.new Observation(birthDay.getTimeInMillis(), score, scores.get(year));
                obs.unit = unit;
                Code code = new Code("GBD", score, score);
                obs.codes.add(code);
                observation(personID, "", obs);
            }
        }
    }
    patients.flush();
    encounters.flush();
    conditions.flush();
    allergies.flush();
    medications.flush();
    careplans.flush();
    observations.flush();
    procedures.flush();
    immunizations.flush();
    imagingStudies.flush();
    devices.flush();
    supplies.flush();
    claims.flush();
    claimsTransactions.flush();
}
Also used : Device(org.mitre.synthea.world.concepts.HealthRecord.Device) GregorianCalendar(java.util.GregorianCalendar) Calendar(java.util.Calendar) Supply(org.mitre.synthea.world.concepts.HealthRecord.Supply) GregorianCalendar(java.util.GregorianCalendar) ImagingStudy(org.mitre.synthea.world.concepts.HealthRecord.ImagingStudy) Code(org.mitre.synthea.world.concepts.HealthRecord.Code) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) HealthRecord(org.mitre.synthea.world.concepts.HealthRecord) CarePlan(org.mitre.synthea.world.concepts.HealthRecord.CarePlan) Entry(org.mitre.synthea.world.concepts.HealthRecord.Entry) Observation(org.mitre.synthea.world.concepts.HealthRecord.Observation) Medication(org.mitre.synthea.world.concepts.HealthRecord.Medication) Encounter(org.mitre.synthea.world.concepts.HealthRecord.Encounter) Procedure(org.mitre.synthea.world.concepts.HealthRecord.Procedure) Map(java.util.Map)

Example 3 with Device

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

the class BB2RIFExporter method exportDME.

/**
 * Export DME 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 exportDME(Person person, long startTime, long stopTime) throws IOException {
    HashMap<DME, String> fieldValues = new HashMap<>();
    for (HealthRecord.Encounter encounter : person.record.encounters) {
        if (encounter.stop < startTime || encounter.stop < claimCutoff) {
            continue;
        }
        boolean isVA = (ProviderType.VETERAN == encounter.provider.type);
        // IHS facilities have valid 6 digit id, IHS centers don't
        boolean isIHSCenter = (ProviderType.IHS == encounter.provider.type) && encounter.provider.id.length() != 6;
        if (isVA || isIHSCenter) {
            continue;
        }
        long claimId = BB2RIFExporter.claimId.getAndDecrement();
        int claimGroupId = BB2RIFExporter.claimGroupId.getAndDecrement();
        long carrClmId = BB2RIFExporter.carrClmCntlNum.getAndDecrement();
        double latestHemoglobin = 0;
        for (HealthRecord.Observation observation : encounter.observations) {
            if (observation.containsCode("718-7", "http://loinc.org")) {
                latestHemoglobin = (double) observation.value;
            }
        }
        fieldValues.clear();
        staticFieldConfig.setValues(fieldValues, DME.class, person);
        // complex fields that could not easily be set using cms_field_values.tsv
        fieldValues.put(DME.CLM_ID, "" + claimId);
        fieldValues.put(DME.CLM_GRP_ID, "" + claimGroupId);
        fieldValues.put(DME.CARR_CLM_CNTL_NUM, "" + carrClmId);
        fieldValues.put(DME.BENE_ID, (String) person.attributes.get(BB2_BENE_ID));
        fieldValues.put(DME.LINE_HCT_HGB_RSLT_NUM, "" + latestHemoglobin);
        fieldValues.put(DME.CARR_NUM, getCarrier(encounter.provider.state, CARRIER.CARR_NUM));
        fieldValues.put(DME.NCH_WKLY_PROC_DT, bb2DateFromTimestamp(ExportHelper.nextFriday(encounter.stop)));
        fieldValues.put(DME.PRVDR_NUM, encounter.provider.id);
        fieldValues.put(DME.PRVDR_NPI, encounter.provider.npi);
        fieldValues.put(DME.RFR_PHYSN_NPI, encounter.clinician.npi);
        fieldValues.put(DME.PRVDR_SPCLTY, ClinicianSpecialty.getCMSProviderSpecialtyCode((String) encounter.clinician.attributes.get(Clinician.SPECIALTY)));
        fieldValues.put(DME.PRVDR_STATE_CD, locationMapper.getStateCode(encounter.provider.state));
        fieldValues.put(DME.TAX_NUM, bb2TaxId((String) encounter.clinician.attributes.get(Person.IDENTIFIER_SSN)));
        fieldValues.put(DME.DMERC_LINE_PRCNG_STATE_CD, locationMapper.getStateCode((String) person.attributes.get(Person.STATE)));
        fieldValues.put(DME.LINE_1ST_EXPNS_DT, bb2DateFromTimestamp(encounter.start));
        fieldValues.put(DME.LINE_LAST_EXPNS_DT, bb2DateFromTimestamp(encounter.stop));
        fieldValues.put(DME.LINE_SRVC_CNT, "" + encounter.claim.items.size());
        fieldValues.put(DME.LINE_PLACE_OF_SRVC_CD, getPlaceOfService(encounter));
        // OPTIONAL
        if (encounter.reason != null) {
            // values into the principle diagnoses code.
            if (conditionCodeMapper.canMap(encounter.reason.code)) {
                String icdCode = conditionCodeMapper.map(encounter.reason.code, person, true);
                fieldValues.put(DME.PRNCPAL_DGNS_CD, icdCode);
                fieldValues.put(DME.LINE_ICD_DGNS_CD, icdCode);
            }
        }
        // Use the active condition diagnoses to enter mapped values
        // into the diagnoses codes.
        List<String> mappedDiagnosisCodes = getDiagnosesCodes(person, encounter.stop);
        if (mappedDiagnosisCodes.isEmpty()) {
            // skip this encounter
            continue;
        }
        int smallest = Math.min(mappedDiagnosisCodes.size(), BB2RIFStructure.dmeDxFields.length);
        for (int i = 0; i < smallest; i++) {
            DME[] dxField = BB2RIFStructure.dmeDxFields[i];
            fieldValues.put(dxField[0], mappedDiagnosisCodes.get(i));
            // 0=ICD10
            fieldValues.put(dxField[1], "0");
        }
        if (!fieldValues.containsKey(DME.PRNCPAL_DGNS_CD)) {
            fieldValues.put(DME.PRNCPAL_DGNS_CD, mappedDiagnosisCodes.get(0));
            fieldValues.put(DME.LINE_ICD_DGNS_CD, mappedDiagnosisCodes.get(0));
        }
        // preprocess some subtotals...
        ClaimEntry subTotals = (encounter.claim).new ClaimEntry(null);
        for (ClaimEntry lineItem : encounter.claim.items) {
            if (lineItem.entry instanceof Device || lineItem.entry instanceof Supply) {
                subTotals.addCosts(lineItem);
            }
        }
        fieldValues.put(DME.CARR_CLM_CASH_DDCTBL_APLD_AMT, String.format("%.2f", subTotals.deductible));
        fieldValues.put(DME.CARR_CLM_PRMRY_PYR_PD_AMT, String.format("%.2f", subTotals.coinsurance.add(subTotals.payer)));
        fieldValues.put(DME.NCH_CARR_CLM_ALOWD_AMT, String.format("%.2f", subTotals.cost.subtract(subTotals.adjustment)));
        fieldValues.put(DME.NCH_CARR_CLM_SBMTD_CHRG_AMT, String.format("%.2f", subTotals.cost));
        fieldValues.put(DME.NCH_CLM_PRVDR_PMT_AMT, String.format("%.2f", subTotals.coinsurance.add(subTotals.payer)));
        fieldValues.put(DME.CLM_PMT_AMT, String.format("%.2f", subTotals.coinsurance.add(subTotals.payer)));
        synchronized (rifWriters.getOrCreateWriter(DME.class)) {
            int lineNum = 1;
            // Now generate the line items...
            for (ClaimEntry lineItem : encounter.claim.items) {
                if (!(lineItem.entry instanceof Device || lineItem.entry instanceof Supply)) {
                    continue;
                }
                if (lineItem.entry instanceof Supply) {
                    Supply supply = (Supply) lineItem.entry;
                    fieldValues.put(DME.DMERC_LINE_MTUS_CNT, "" + supply.quantity);
                } else {
                    fieldValues.put(DME.DMERC_LINE_MTUS_CNT, "");
                }
                if (!dmeCodeMapper.canMap(lineItem.entry.codes.get(0).code)) {
                    System.err.println(" *** Possibly Missing DME Code: " + lineItem.entry.codes.get(0).code + " " + lineItem.entry.codes.get(0).display);
                    continue;
                }
                fieldValues.put(DME.CLM_FROM_DT, bb2DateFromTimestamp(lineItem.entry.start));
                fieldValues.put(DME.CLM_THRU_DT, bb2DateFromTimestamp(lineItem.entry.start));
                String hcpcsCode = dmeCodeMapper.map(lineItem.entry.codes.get(0).code, person);
                fieldValues.put(DME.HCPCS_CD, hcpcsCode);
                if (betosCodeMapper.canMap(hcpcsCode)) {
                    fieldValues.put(DME.BETOS_CD, betosCodeMapper.map(hcpcsCode, person));
                } else {
                    fieldValues.put(DME.BETOS_CD, "");
                }
                fieldValues.put(DME.LINE_CMS_TYPE_SRVC_CD, dmeCodeMapper.map(lineItem.entry.codes.get(0).code, DME.LINE_CMS_TYPE_SRVC_CD.toString().toLowerCase(), person));
                fieldValues.put(DME.LINE_BENE_PTB_DDCTBL_AMT, String.format("%.2f", lineItem.deductible));
                fieldValues.put(DME.LINE_COINSRNC_AMT, String.format("%.2f", lineItem.getCoinsurancePaid()));
                fieldValues.put(DME.LINE_BENE_PMT_AMT, String.format("%.2f", lineItem.copay.add(lineItem.deductible).add(lineItem.pocket)));
                fieldValues.put(DME.LINE_PRVDR_PMT_AMT, String.format("%.2f", lineItem.coinsurance.add(lineItem.payer)));
                fieldValues.put(DME.LINE_SBMTD_CHRG_AMT, String.format("%.2f", lineItem.cost));
                fieldValues.put(DME.LINE_ALOWD_CHRG_AMT, String.format("%.2f", lineItem.cost.subtract(lineItem.adjustment)));
                fieldValues.put(DME.LINE_PRMRY_ALOWD_CHRG_AMT, String.format("%.2f", lineItem.cost.subtract(lineItem.adjustment)));
                fieldValues.put(DME.LINE_NCH_PMT_AMT, String.format("%.2f", lineItem.coinsurance.add(lineItem.payer)));
                // set the line number and write out field values
                fieldValues.put(DME.LINE_NUM, Integer.toString(lineNum++));
                rifWriters.writeValues(DME.class, fieldValues);
            }
        }
    }
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Device(org.mitre.synthea.world.concepts.HealthRecord.Device) Supply(org.mitre.synthea.world.concepts.HealthRecord.Supply) ClaimEntry(org.mitre.synthea.world.concepts.Claim.ClaimEntry) HealthRecord(org.mitre.synthea.world.concepts.HealthRecord) DME(org.mitre.synthea.export.BB2RIFStructure.DME)

Aggregations

Device (org.mitre.synthea.world.concepts.HealthRecord.Device)3 HealthRecord (org.mitre.synthea.world.concepts.HealthRecord)2 Code (org.mitre.synthea.world.concepts.HealthRecord.Code)2 Entry (org.mitre.synthea.world.concepts.HealthRecord.Entry)2 Medication (org.mitre.synthea.world.concepts.HealthRecord.Medication)2 Procedure (org.mitre.synthea.world.concepts.HealthRecord.Procedure)2 Supply (org.mitre.synthea.world.concepts.HealthRecord.Supply)2 JsonObject (com.google.gson.JsonObject)1 BigDecimal (java.math.BigDecimal)1 Calendar (java.util.Calendar)1 GregorianCalendar (java.util.GregorianCalendar)1 HashMap (java.util.HashMap)1 Hashtable (java.util.Hashtable)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 UUID (java.util.UUID)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 DME (org.mitre.synthea.export.BB2RIFStructure.DME)1 ClaimEntry (org.mitre.synthea.world.concepts.Claim.ClaimEntry)1 CarePlan (org.mitre.synthea.world.concepts.HealthRecord.CarePlan)1