Search in sources :

Example 1 with DMEClaimLine

use of gov.cms.bfd.model.rif.DMEClaimLine in project beneficiary-fhir-data by CMSgov.

the class DMEClaimTransformerV2 method handleClaimLines.

private static void handleClaimLines(DMEClaim claimGroup, ExplanationOfBenefit eob, Optional<Boolean> includeTaxNumbers) {
    for (DMEClaimLine line : claimGroup.getLines()) {
        ItemComponent item = TransformerUtilsV2.addItem(eob);
        // Override the default sequence
        // CLM_LINE_NUM => item.sequence
        item.setSequence(line.getLineNumber().intValue());
        // add an extension for the provider billing number as there is not a good place
        // to map this in the existing FHIR specification
        // PRVDR_NUM => ExplanationOfBenefit.provider.value
        line.getProviderBillingNumber().ifPresent(c -> item.addExtension(TransformerUtilsV2.createExtensionIdentifier(CcwCodebookVariable.SUPLRNUM, line.getProviderBillingNumber())));
        // PRVDR_NPI => ExplanationOfBenefit.careTeam.provider
        Optional<CareTeamComponent> performing = TransformerUtilsV2.addCareTeamMember(eob, item, C4BBPractitionerIdentifierType.NPI, C4BBClaimProfessionalAndNonClinicianCareTeamRole.PERFORMING, line.getProviderNPI());
        // Update the responsible flag
        performing.ifPresent(p -> {
            p.setResponsible(true);
            // PRVDR_SPCLTY => ExplanationOfBenefit.careTeam.qualification
            p.setQualification(TransformerUtilsV2.createCodeableConcept(eob, CcwCodebookVariable.PRVDR_SPCLTY, line.getProviderSpecialityCode()));
            // PRTCPTNG_IND_CD => ExplanationOfBenefit.careTeam.extension
            p.addExtension(TransformerUtilsV2.createExtensionCoding(eob, CcwCodebookVariable.PRTCPTNG_IND_CD, line.getProviderParticipatingIndCode()));
        });
        // PRVDR_STATE_CD => ExplanationOfBenefit.item.location.extension
        if (item.getLocation() != null) {
            item.getLocation().addExtension(TransformerUtilsV2.createExtensionCoding(eob, CcwCodebookVariable.PRVDR_STATE_CD, line.getProviderStateCode()));
        }
        // HCPCS_CD            => ExplanationOfBenefit.item.productOrService
        // HCPCS_1ST_MDFR_CD   => ExplanationOfBenefit.item.modifier
        // HCPCS_2ND_MDFR_CD   => ExplanationOfBenefit.item.modifier
        // HCPCS_3RD_MDFR_CD   => ExplanationOfBenefit.item.modifier
        // HCPCS_4Th_MDFR_CD   => ExplanationOfBenefit.item.modifier
        TransformerUtilsV2.mapHcpcs(eob, item, line.getHcpcsCode(), claimGroup.getHcpcsYearCode(), Arrays.asList(line.getHcpcsInitialModifierCode(), line.getHcpcsSecondModifierCode(), line.getHcpcsThirdModifierCode(), line.getHcpcsFourthModifierCode()));
        if (includeTaxNumbers.orElse(false)) {
            item.addExtension(TransformerUtilsV2.createExtensionCoding(eob, CcwCodebookVariable.TAX_NUM, line.getProviderTaxNumber()));
        }
        // REV_CNTR_PRVDR_PMT_AMT => ExplanationOfBenefit.item.adjudication
        TransformerUtilsV2.addAdjudication(item, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.REV_CNTR_PRVDR_PMT_AMT, C4BBAdjudication.PAID_TO_PROVIDER, line.getProviderPaymentAmount()));
        // TODO - check w/jack if this is right ELIGIBLE
        // LINE_PRMRY_ALOWD_CHRG_AMT => ExplanationOfBenefit.item.adjudication.value
        TransformerUtilsV2.addAdjudication(item, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.LINE_PRMRY_ALOWD_CHRG_AMT, C4BBAdjudication.ELIGIBLE, line.getPrimaryPayerAllowedChargeAmount()));
        // LINE_DME_PRCHS_PRICE_AMT => ExplanationOfBenefit.item.adjudication.value
        TransformerUtilsV2.addAdjudication(item, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.LINE_DME_PRCHS_PRICE_AMT, C4BBAdjudication.SUBMITTED, line.getPurchasePriceAmount()));
        // DMERC_LINE_SCRN_SVGS_AMT => ExplanationOfBenefit.item.extension
        line.getScreenSavingsAmount().ifPresent(c -> item.addExtension(// TODO should this be an adjudication?
        TransformerUtilsV2.createExtensionQuantity(CcwCodebookVariable.DMERC_LINE_SCRN_SVGS_AMT, line.getScreenSavingsAmount())));
        // DMERC_LINE_MTUS_CNT => ExplanationOfBenefit.item.extension
        Extension mtusQuantityExtension = TransformerUtilsV2.createExtensionQuantity(CcwCodebookVariable.DMERC_LINE_MTUS_CNT, line.getMtusCount());
        item.addExtension(mtusQuantityExtension);
        // DMERC_LINE_MTUS_CD => ExplanationOfBenefit.item.extension
        if (line.getMtusCode().isPresent()) {
            Quantity mtusQuantity = (Quantity) mtusQuantityExtension.getValue();
            TransformerUtilsV2.setQuantityUnitInfo(CcwCodebookVariable.DMERC_LINE_MTUS_CD, line.getMtusCode(), eob, mtusQuantity);
        }
        // DMERC_LINE_PRCNG_STATE_CD => ExplanationOfBenefit.item.extension
        line.getPricingStateCode().ifPresent(c -> item.addExtension(TransformerUtilsV2.createExtensionCoding(eob, CcwCodebookVariable.DMERC_LINE_PRCNG_STATE_CD, line.getPricingStateCode())));
        // DMERC_LINE_SUPPLR_TYPE_CD => ExplanationOfBenefit.item.extension
        line.getSupplierTypeCode().ifPresent(c -> item.addExtension(TransformerUtilsV2.createExtensionCoding(eob, CcwCodebookVariable.DMERC_LINE_SUPPLR_TYPE_CD, line.getSupplierTypeCode())));
        // Common item level fields between Carrier and DME
        // LINE_NUM                 => ExplanationOfBenefit.item.sequence
        // LINE_SRVC_CNT            => ExplanationOfBenefit.item.quantity
        // LINE_CMS_TYPE_SRVC_CD    => ExplanationOfBenefit.item.category
        // LINE_PLACE_OF_SRVC_CD    => ExplanationOfBenefit.item.location
        // LINE_1ST_EXPNS_DT        => ExplanationOfBenefit.item.servicedPeriod
        // LINE_LAST_EXPNS_DT       => ExplanationOfBenefit.item.servicedPeriod
        // LINE_NCH_PMT_AMT         => ExplanationOfBenefit.item.adjudication
        // LINE_PMT_80_100_CD       => ExplanationOfBenefit.item.adjudication.extension
        // PAID_TO_PATIENT          => ExplanationOfBenefit.item.adjudication
        // LINE_PRVDR_PMT_AMT       => ExplanationOfBenefit.item.adjudication
        // LINE_BENE_PTB_DDCTBL_AMT => ExplanationOfBenefit.item.adjudication
        // LINE_BENE_PRMRY_PYR_CD   => ExplanationOfBenefit.item.extension
        // LINE_BENE_PRMRY_PYR_PD_AMT => ExplanationOfBenefit.item.adjudication
        // BETOS_CD                 => ExplanationOfBenefit.item.extension
        // LINE_COINSRNC_AMT        => ExplanationOfBenefit.item.adjudication
        // LINE_SBMTD_CHRG_AMT      => ExplanationOfBenefit.item.adjudication
        // LINE_ALOWD_CHRG_AMT      => ExplanationOfBenefit.item.adjudication
        // LINE_BENE_PRMRY_PYR_CD   => ExplanationOfBenefit.item.extension
        // LINE_SERVICE_DEDUCTIBLE  => ExplanationOfBenefit.item.extension
        // LINE_HCT_HGB_TYPE_CD     => Observation.code
        // LINE_HCT_HGB_RSLT_NUM    => Observation.value
        // LINE_NDC_CD              => ExplanationOfBenefit.item.productOrService
        // LINE_BENE_PMT_AMT        => ExplanationOfBenefit.item.adjudication.value
        // LINE_PRCSG_IND_CD        => ExplanationOfBenefit.item.extension
        // LINE_DME_PRCHS_PRICE_AMT => ExplanationOfBenefit.item.adjudication.value
        TransformerUtilsV2.mapEobCommonItemCarrierDME(item, eob, claimGroup.getClaimId(), item.getSequence(), line.getServiceCount(), line.getPlaceOfServiceCode(), line.getFirstExpenseDate(), line.getLastExpenseDate(), line.getBeneficiaryPaymentAmount(), line.getProviderPaymentAmount(), line.getBeneficiaryPartBDeductAmount(), line.getPrimaryPayerCode(), line.getPrimaryPayerPaidAmount(), line.getBetosCode(), line.getPaymentAmount(), line.getPaymentCode(), line.getCoinsuranceAmount(), line.getSubmittedChargeAmount(), line.getAllowedChargeAmount(), line.getProcessingIndicatorCode(), line.getServiceDeductibleCode(), line.getHctHgbTestTypeCode(), line.getHctHgbTestResult(), line.getCmsServiceTypeCode(), line.getNationalDrugCode());
        // LINE_ICD_DGNS_CD      => ExplanationOfBenefit.item.diagnosisSequence
        // LINE_ICD_DGNS_VRSN_CD => ExplanationOfBenefit.item.diagnosisSequence
        DiagnosisUtilV2.addDiagnosisLink(eob, item, Diagnosis.from(line.getDiagnosisCode(), line.getDiagnosisCodeVersion(), DiagnosisLabel.OTHER), ClaimTypeV2.CARRIER);
        // PRVDR_STATE_CD => ExplanationOfBenefit.item.location.extension
        if (line.getProviderStateCode() != null) {
            item.getLocation().addExtension(TransformerUtilsV2.createExtensionCoding(eob, CcwCodebookVariable.PRVDR_STATE_CD, line.getProviderStateCode()));
        }
        // LINE_BENE_PRMRY_PYR_CD
        // claimLine.getPrimaryPayerCode()) => ExplanationOfBenefit.item.extension
        line.getPrimaryPayerCode().ifPresent(c -> item.addExtension(TransformerUtilsV2.createExtensionCoding(eob, CcwCodebookVariable.LINE_BENE_PRMRY_PYR_CD, line.getPrimaryPayerCode())));
        // LINE_BENE_PMT_AMT
        // claimLine.getBeneficiaryPaymentAmount() => ExplanationOfBenefit.item.adjudication.value
        TransformerUtilsV2.addAdjudication(item, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.LINE_BENE_PMT_AMT, C4BBAdjudication.PAID_TO_PROVIDER, line.getPurchasePriceAmount()));
        // LINE_DME_PRCHS_PRICE_AMT
        // claimLine.getPurchasePriceAmount() => ExplanationOfBenefit.item.adjudication.value
        TransformerUtilsV2.addAdjudication(item, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.LINE_DME_PRCHS_PRICE_AMT, C4BBAdjudication.SUBMITTED, line.getPurchasePriceAmount()));
    }
}
Also used : Extension(org.hl7.fhir.r4.model.Extension) ItemComponent(org.hl7.fhir.r4.model.ExplanationOfBenefit.ItemComponent) Quantity(org.hl7.fhir.r4.model.Quantity) CareTeamComponent(org.hl7.fhir.r4.model.ExplanationOfBenefit.CareTeamComponent) DMEClaimLine(gov.cms.bfd.model.rif.DMEClaimLine)

Example 2 with DMEClaimLine

use of gov.cms.bfd.model.rif.DMEClaimLine in project beneficiary-fhir-data by CMSgov.

the class RifFilesProcessorTest method process1DMEClaimRecord.

/**
 * Ensures that {@link RifFilesProcessor} can correctly handle {@link
 * StaticRifResource#SAMPLE_A_DME}.
 */
@Test
public void process1DMEClaimRecord() {
    RifFilesEvent filesEvent = new RifFilesEvent(Instant.now(), StaticRifResource.SAMPLE_A_DME.toRifFile());
    RifFilesProcessor processor = new RifFilesProcessor();
    RifFileRecords rifFileRecords = processor.produceRecords(filesEvent.getFileEvents().get(0));
    List<RifRecordEvent<?>> rifEventsList = rifFileRecords.getRecords().collect(Collectors.toList());
    assertEquals(StaticRifResource.SAMPLE_A_DME.getRecordCount(), rifEventsList.size());
    RifRecordEvent<?> rifRecordEvent = rifEventsList.get(0);
    assertEquals(StaticRifResource.SAMPLE_A_DME.getRifFileType(), rifRecordEvent.getFileEvent().getFile().getFileType());
    assertNotNull(rifRecordEvent.getRecord());
    assertTrue(rifRecordEvent.getRecord() instanceof DMEClaim);
    // Verify the claim header.
    DMEClaim claimGroup = (DMEClaim) rifRecordEvent.getRecord();
    assertEquals(RecordAction.INSERT, rifRecordEvent.getRecordAction());
    assertEquals(claimGroup.getBeneficiaryId(), rifRecordEvent.getBeneficiaryId());
    assertEquals("567834", claimGroup.getBeneficiaryId());
    assertEquals("2188888888", claimGroup.getClaimId());
    assertEquals(new BigDecimal(900), claimGroup.getClaimGroupId());
    assertEquals('M', claimGroup.getNearLineRecordIdCode());
    assertEquals("82", claimGroup.getClaimTypeCode());
    assertEquals(LocalDate.of(2014, 02, 03), claimGroup.getDateFrom());
    assertEquals(LocalDate.of(2014, 02, 03), claimGroup.getDateThrough());
    assertEquals(LocalDate.of(2014, 02, 14), claimGroup.getWeeklyProcessDate());
    assertEquals('1', claimGroup.getClaimEntryCode());
    assertEquals("01", claimGroup.getClaimDispositionCode());
    assertEquals("99999", claimGroup.getCarrierNumber());
    assertEquals("1", claimGroup.getPaymentDenialCode());
    assertEquals(new BigDecimal("777.75"), claimGroup.getPaymentAmount());
    assertEquals(new BigDecimal("0"), claimGroup.getPrimaryPayerPaidAmount());
    assertEquals('A', claimGroup.getProviderAssignmentIndicator());
    assertEquals(new BigDecimal("666.75"), claimGroup.getProviderPaymentAmount());
    assertEquals(new BigDecimal("666.66"), claimGroup.getBeneficiaryPaymentAmount());
    assertEquals(new BigDecimal("1752.75"), claimGroup.getSubmittedChargeAmount());
    assertEquals(new BigDecimal("754.79"), claimGroup.getAllowedChargeAmount());
    assertEquals(new BigDecimal("777.00"), claimGroup.getBeneficiaryPartBDeductAmount());
    assertEquals('3', claimGroup.getHcpcsYearCode().get().charValue());
    assertEquals("R5555", claimGroup.getDiagnosis1Code().get());
    assertEquals('0', claimGroup.getDiagnosis1CodeVersion().get().charValue());
    assertEquals("1306849450", claimGroup.getReferringPhysicianNpi().get());
    assertEquals("0", claimGroup.getClinicalTrialNumber().get());
    assertEquals(1, claimGroup.getLines().size());
    assertEquals("74655592568216", claimGroup.getClaimCarrierControlNumber().get());
    // Verify one of the claim lines.
    DMEClaimLine claimLine = claimGroup.getLines().get(0);
    assertEquals(new BigDecimal(1), claimLine.getLineNumber());
    assertEquals("9994931888", claimLine.getProviderTaxNumber());
    assertEquals("A5", claimLine.getProviderSpecialityCode().get());
    assertEquals('1', claimLine.getProviderParticipatingIndCode().get().charValue());
    assertEquals(new BigDecimal("60"), claimLine.getServiceCount());
    assertEquals('P', claimLine.getCmsServiceTypeCode());
    assertEquals("12", claimLine.getPlaceOfServiceCode());
    assertEquals(LocalDate.of(2014, 02, 03), claimLine.getFirstExpenseDate().get());
    assertEquals(LocalDate.of(2014, 02, 03), claimLine.getLastExpenseDate().get());
    assertEquals("345", claimLine.getHcpcsCode().get());
    assertFalse(claimLine.getHcpcsSecondModifierCode().isPresent());
    assertFalse(claimLine.getHcpcsThirdModifierCode().isPresent());
    assertFalse(claimLine.getHcpcsFourthModifierCode().isPresent());
    assertEquals("D9Z", claimLine.getBetosCode().get());
    assertEquals(new BigDecimal("123.45"), claimLine.getPaymentAmount());
    assertEquals(new BigDecimal("11.00"), claimLine.getBeneficiaryPaymentAmount());
    assertEquals(new BigDecimal("120.00"), claimLine.getProviderPaymentAmount());
    assertEquals(new BigDecimal("18.00"), claimLine.getBeneficiaryPartBDeductAmount());
    assertTrue(claimLine.getPrimaryPayerCode().isPresent());
    assertEquals(new BigDecimal("11.00"), claimLine.getPrimaryPayerPaidAmount());
    assertEquals(new BigDecimal("20.20"), claimLine.getCoinsuranceAmount());
    assertEquals(new BigDecimal("20.29"), claimLine.getPrimaryPayerAllowedChargeAmount());
    assertEquals(new BigDecimal("130.45"), claimLine.getSubmittedChargeAmount());
    assertEquals(new BigDecimal("129.45"), claimLine.getAllowedChargeAmount());
    assertEquals("A", claimLine.getProcessingIndicatorCode().get());
    assertEquals('0', claimLine.getPaymentCode().get().charValue());
    assertEquals('0', claimLine.getServiceDeductibleCode().get().charValue());
    assertEquals(new BigDecimal("82.29"), claimLine.getPurchasePriceAmount());
    assertEquals("1244444444", claimLine.getProviderNPI().get());
    assertEquals("AL", claimLine.getPricingStateCode().get());
    assertEquals("MO", claimLine.getProviderStateCode());
    assertEquals(new Character('3'), claimLine.getSupplierTypeCode().get());
    assertEquals(new BigDecimal("0.00"), claimLine.getScreenSavingsAmount().get());
    assertEquals(new BigDecimal("60"), claimLine.getMtusCount());
    assertEquals('3', claimLine.getMtusCode().get().charValue());
    assertEquals(new BigDecimal("44.4"), claimLine.getHctHgbTestResult());
    assertEquals("R2", claimLine.getHctHgbTestTypeCode().get());
    assertEquals("500904610", claimLine.getNationalDrugCode().get());
}
Also used : DMEClaim(gov.cms.bfd.model.rif.DMEClaim) RifRecordEvent(gov.cms.bfd.model.rif.RifRecordEvent) RifFileRecords(gov.cms.bfd.model.rif.RifFileRecords) RifFilesEvent(gov.cms.bfd.model.rif.RifFilesEvent) BigDecimal(java.math.BigDecimal) DMEClaimLine(gov.cms.bfd.model.rif.DMEClaimLine) Test(org.junit.jupiter.api.Test)

Example 3 with DMEClaimLine

use of gov.cms.bfd.model.rif.DMEClaimLine in project beneficiary-fhir-data by CMSgov.

the class DMEClaimTransformerTest method assertMatches.

/**
 * Verifies that the {@link ExplanationOfBenefit} "looks like" it should, if it were produced from
 * the specified {@link DMEClaim}.
 *
 * @param claim the {@link DMEClaim} that the {@link ExplanationOfBenefit} was generated from
 * @param eob the {@link ExplanationOfBenefit} that was generated from the specified {@link
 *     DMEClaim}@param includedTaxNumbers whether or not to include tax numbers are expected to be
 *     included in the result (see {@link
 *     ExplanationOfBenefitResourceProvider#HEADER_NAME_INCLUDE_TAX_NUMBERS}, defaults to <code>
 *     false</code>)
 * @throws FHIRException (indicates test failure)
 */
static void assertMatches(DMEClaim claim, ExplanationOfBenefit eob, Optional<Boolean> includedTaxNumbers) throws FHIRException {
    // Test to ensure group level fields between all claim types match
    TransformerTestUtils.assertEobCommonClaimHeaderData(eob, claim.getClaimId(), claim.getBeneficiaryId(), ClaimType.DME, claim.getClaimGroupId().toPlainString(), MedicareSegment.PART_B, Optional.of(claim.getDateFrom()), Optional.of(claim.getDateThrough()), Optional.of(claim.getPaymentAmount()), claim.getFinalAction());
    // Test to ensure common group fields between Carrier and DME match
    TransformerTestUtils.assertEobCommonGroupCarrierDMEEquals(eob, claim.getBeneficiaryId(), claim.getCarrierNumber(), claim.getClinicalTrialNumber(), claim.getBeneficiaryPartBDeductAmount(), claim.getPaymentDenialCode(), claim.getReferringPhysicianNpi(), Optional.of(claim.getProviderAssignmentIndicator()), claim.getProviderPaymentAmount(), claim.getBeneficiaryPaymentAmount(), claim.getSubmittedChargeAmount(), claim.getAllowedChargeAmount());
    TransformerTestUtils.assertAdjudicationTotalAmountEquals(CcwCodebookVariable.PRPAYAMT, claim.getPrimaryPayerPaidAmount(), eob);
    assertEquals(3, eob.getDiagnosis().size());
    assertEquals(1, eob.getItem().size());
    ItemComponent eobItem0 = eob.getItem().get(0);
    DMEClaimLine claimLine1 = claim.getLines().get(0);
    assertEquals(claimLine1.getLineNumber(), new BigDecimal(eobItem0.getSequence()));
    TransformerTestUtils.assertExtensionIdentifierEquals(CcwCodebookVariable.SUPLRNUM, claimLine1.getProviderBillingNumber(), eobItem0);
    TransformerTestUtils.assertCareTeamEquals(claimLine1.getProviderNPI().get(), ClaimCareteamrole.PRIMARY, eob);
    CareTeamComponent performingCareTeamEntry = TransformerTestUtils.findCareTeamEntryForProviderNpi(claimLine1.getProviderNPI().get(), eob.getCareTeam());
    TransformerTestUtils.assertHasCoding(CcwCodebookVariable.PRVDR_SPCLTY, claimLine1.getProviderSpecialityCode(), performingCareTeamEntry.getQualification());
    TransformerTestUtils.assertExtensionCodingEquals(CcwCodebookVariable.PRTCPTNG_IND_CD, claimLine1.getProviderParticipatingIndCode(), performingCareTeamEntry);
    TransformerTestUtils.assertExtensionCodingEquals(CcwCodebookVariable.PRVDR_STATE_CD, claimLine1.getProviderStateCode(), eobItem0.getLocation());
    CareTeamComponent taxNumberCareTeamEntry = TransformerTestUtils.findCareTeamEntryForProviderTaxNumber(claimLine1.getProviderTaxNumber(), eob.getCareTeam());
    if (includedTaxNumbers.orElse(false)) {
        assertNotNull(taxNumberCareTeamEntry);
    } else {
        assertNull(taxNumberCareTeamEntry);
    }
    TransformerTestUtils.assertHcpcsCodes(eobItem0, claimLine1.getHcpcsCode(), claimLine1.getHcpcsInitialModifierCode(), claimLine1.getHcpcsSecondModifierCode(), claim.getHcpcsYearCode(), 0);
    TransformerTestUtils.assertHasCoding(TransformerConstants.CODING_SYSTEM_HCPCS, "" + claim.getHcpcsYearCode().get(), null, claimLine1.getHcpcsCode().get(), eobItem0.getService().getCoding());
    TransformerTestUtils.assertAdjudicationAmountEquals(CcwCodebookVariable.LINE_PRMRY_ALOWD_CHRG_AMT, claimLine1.getPrimaryPayerAllowedChargeAmount(), eobItem0.getAdjudication());
    TransformerTestUtils.assertAdjudicationAmountEquals(CcwCodebookVariable.LINE_DME_PRCHS_PRICE_AMT, claimLine1.getPurchasePriceAmount(), eobItem0.getAdjudication());
    TransformerTestUtils.assertExtensionCodingEquals(CcwCodebookVariable.DMERC_LINE_PRCNG_STATE_CD, claimLine1.getPricingStateCode(), eobItem0.getLocation());
    TransformerTestUtils.assertExtensionCodingEquals(CcwCodebookVariable.DMERC_LINE_SUPPLR_TYPE_CD, claimLine1.getSupplierTypeCode(), eobItem0.getLocation());
    TransformerTestUtils.assertExtensionQuantityEquals(CcwCodebookVariable.DMERC_LINE_SCRN_SVGS_AMT, claimLine1.getScreenSavingsAmount(), eobItem0);
    TransformerTestUtils.assertQuantityUnitInfoEquals(CcwCodebookVariable.DMERC_LINE_MTUS_CNT, CcwCodebookVariable.DMERC_LINE_MTUS_CD, claimLine1.getMtusCode(), eobItem0);
    TransformerTestUtils.assertExtensionQuantityEquals(CcwCodebookVariable.DMERC_LINE_MTUS_CNT, claimLine1.getMtusCount(), eobItem0);
    TransformerTestUtils.assertExtensionCodingEquals(eobItem0, TransformerConstants.CODING_NDC, TransformerConstants.CODING_NDC, claimLine1.getNationalDrugCode().get());
    // verify {@link
    // TransformerUtils#mapEobType(CodeableConcept,ClaimType,Optional,Optional)}
    // method worked as expected for this claim type
    TransformerTestUtils.assertMapEobType(eob.getType(), ClaimType.DME, // be updated to match expected result.
    Optional.empty(), Optional.of(claim.getNearLineRecordIdCode()), Optional.of(claim.getClaimTypeCode()));
    // Test to ensure common item fields between Carrier and DME match
    TransformerTestUtils.assertEobCommonItemCarrierDMEEquals(eobItem0, eob, claimLine1.getServiceCount(), claimLine1.getPlaceOfServiceCode(), claimLine1.getFirstExpenseDate(), claimLine1.getLastExpenseDate(), claimLine1.getBeneficiaryPaymentAmount(), claimLine1.getProviderPaymentAmount(), claimLine1.getBeneficiaryPartBDeductAmount(), claimLine1.getPrimaryPayerCode(), claimLine1.getPrimaryPayerPaidAmount(), claimLine1.getBetosCode(), claimLine1.getPaymentAmount(), claimLine1.getPaymentCode(), claimLine1.getCoinsuranceAmount(), claimLine1.getSubmittedChargeAmount(), claimLine1.getAllowedChargeAmount(), claimLine1.getProcessingIndicatorCode(), claimLine1.getServiceDeductibleCode(), claimLine1.getDiagnosisCode(), claimLine1.getDiagnosisCodeVersion(), claimLine1.getHctHgbTestTypeCode(), claimLine1.getHctHgbTestResult(), claimLine1.getCmsServiceTypeCode(), claimLine1.getNationalDrugCode());
    // Test lastUpdated
    TransformerTestUtils.assertLastUpdatedEquals(claim.getLastUpdated(), eob);
}
Also used : ItemComponent(org.hl7.fhir.dstu3.model.ExplanationOfBenefit.ItemComponent) CareTeamComponent(org.hl7.fhir.dstu3.model.ExplanationOfBenefit.CareTeamComponent) DMEClaimLine(gov.cms.bfd.model.rif.DMEClaimLine) BigDecimal(java.math.BigDecimal)

Example 4 with DMEClaimLine

use of gov.cms.bfd.model.rif.DMEClaimLine in project beneficiary-fhir-data by CMSgov.

the class DMEClaimTransformer method transformClaim.

/**
 * @param includeTaxNumbers whether or not to include tax numbers in the result (see {@link
 *     ExplanationOfBenefitResourceProvider#HEADER_NAME_INCLUDE_TAX_NUMBERS}, defaults to <code>
 *     false</code>)
 * @return a FHIR {@link ExplanationOfBenefit} resource that represents the specified {@link
 *     DMEClaim}
 */
private static ExplanationOfBenefit transformClaim(DMEClaim claimGroup, Optional<Boolean> includeTaxNumbers) {
    ExplanationOfBenefit eob = new ExplanationOfBenefit();
    // Common group level fields between all claim types
    TransformerUtils.mapEobCommonClaimHeaderData(eob, claimGroup.getClaimId(), claimGroup.getBeneficiaryId(), ClaimType.DME, claimGroup.getClaimGroupId().toPlainString(), MedicareSegment.PART_B, Optional.of(claimGroup.getDateFrom()), Optional.of(claimGroup.getDateThrough()), Optional.of(claimGroup.getPaymentAmount()), claimGroup.getFinalAction());
    TransformerUtils.mapEobWeeklyProcessDate(eob, claimGroup.getWeeklyProcessDate());
    // map eob type codes into FHIR
    TransformerUtils.mapEobType(eob, ClaimType.DME, Optional.of(claimGroup.getNearLineRecordIdCode()), Optional.of(claimGroup.getClaimTypeCode()));
    // TODO is this column nullable? If so, why isn't it Optional?
    if (claimGroup.getPrimaryPayerPaidAmount() != null) {
        TransformerUtils.addAdjudicationTotal(eob, CcwCodebookVariable.PRPAYAMT, claimGroup.getPrimaryPayerPaidAmount());
    }
    // Common group level fields between Carrier and DME
    TransformerUtils.mapEobCommonGroupCarrierDME(eob, claimGroup.getBeneficiaryId(), claimGroup.getCarrierNumber(), claimGroup.getClinicalTrialNumber(), claimGroup.getBeneficiaryPartBDeductAmount(), claimGroup.getPaymentDenialCode(), claimGroup.getReferringPhysicianNpi(), Optional.of(claimGroup.getProviderAssignmentIndicator()), claimGroup.getProviderPaymentAmount(), claimGroup.getBeneficiaryPaymentAmount(), claimGroup.getSubmittedChargeAmount(), claimGroup.getAllowedChargeAmount(), claimGroup.getClaimDispositionCode(), claimGroup.getClaimCarrierControlNumber());
    for (Diagnosis diagnosis : TransformerUtils.extractDiagnoses1Thru12(claimGroup.getDiagnosisPrincipalCode(), claimGroup.getDiagnosisPrincipalCodeVersion(), claimGroup.getDiagnosis1Code(), claimGroup.getDiagnosis1CodeVersion(), claimGroup.getDiagnosis2Code(), claimGroup.getDiagnosis2CodeVersion(), claimGroup.getDiagnosis3Code(), claimGroup.getDiagnosis3CodeVersion(), claimGroup.getDiagnosis4Code(), claimGroup.getDiagnosis4CodeVersion(), claimGroup.getDiagnosis5Code(), claimGroup.getDiagnosis5CodeVersion(), claimGroup.getDiagnosis6Code(), claimGroup.getDiagnosis6CodeVersion(), claimGroup.getDiagnosis7Code(), claimGroup.getDiagnosis7CodeVersion(), claimGroup.getDiagnosis8Code(), claimGroup.getDiagnosis8CodeVersion(), claimGroup.getDiagnosis9Code(), claimGroup.getDiagnosis9CodeVersion(), claimGroup.getDiagnosis10Code(), claimGroup.getDiagnosis10CodeVersion(), claimGroup.getDiagnosis11Code(), claimGroup.getDiagnosis11CodeVersion(), claimGroup.getDiagnosis12Code(), claimGroup.getDiagnosis12CodeVersion())) TransformerUtils.addDiagnosisCode(eob, diagnosis);
    for (DMEClaimLine claimLine : claimGroup.getLines()) {
        ItemComponent item = eob.addItem();
        item.setSequence(claimLine.getLineNumber().intValue());
        /*
       * add an extension for the provider billing number as there is not a good place
       * to map this in the existing FHIR specification
       */
        if (claimLine.getProviderBillingNumber().isPresent()) {
            item.addExtension(TransformerUtils.createExtensionIdentifier(CcwCodebookVariable.SUPLRNUM, claimLine.getProviderBillingNumber()));
        }
        /*
       * Per Michelle at GDIT, and also Tony Dean at OEDA, the performing provider
       * _should_ always be present. However, we've found some examples in production
       * where it's not for some claim lines. (This is annoying, as it's present on
       * other lines in the same claim, and the data indicates that the same NPI
       * probably applies to the lines where it's not specified. Still, it's not safe
       * to guess at this, so we'll leave it blank.)
       */
        if (claimLine.getProviderNPI().isPresent()) {
            ExplanationOfBenefit.CareTeamComponent performingCareTeamMember = TransformerUtils.addCareTeamPractitioner(eob, item, TransformerConstants.CODING_NPI_US, claimLine.getProviderNPI().get(), ClaimCareteamrole.PRIMARY);
            performingCareTeamMember.setResponsible(true);
            /*
         * The provider's "specialty" and "type" code are equivalent.
         * However, the "specialty" codes are more granular, and seem to
         * better match the example FHIR
         * `http://hl7.org/fhir/ex-providerqualification` code set.
         * Accordingly, we map the "specialty" codes to the
         * `qualification` field here, and stick the "type" code into an
         * extension. TODO: suggest that the spec allows more than one
         * `qualification` entry.
         */
            performingCareTeamMember.setQualification(TransformerUtils.createCodeableConcept(eob, CcwCodebookVariable.PRVDR_SPCLTY, claimLine.getProviderSpecialityCode()));
            performingCareTeamMember.addExtension(TransformerUtils.createExtensionCoding(eob, CcwCodebookVariable.PRTCPTNG_IND_CD, claimLine.getProviderParticipatingIndCode()));
        }
        TransformerUtils.mapHcpcs(eob, item, claimGroup.getHcpcsYearCode(), claimLine.getHcpcsCode(), Arrays.asList(claimLine.getHcpcsInitialModifierCode(), claimLine.getHcpcsSecondModifierCode(), claimLine.getHcpcsThirdModifierCode(), claimLine.getHcpcsFourthModifierCode()));
        /*
       * FIXME This value seems to be just a "synonym" for the performing physician NPI and should
       * probably be mapped as an extra identifier with it (if/when that lands in a contained
       * Practitioner resource).
       */
        if (includeTaxNumbers.orElse(false)) {
            ExplanationOfBenefit.CareTeamComponent providerTaxNumber = TransformerUtils.addCareTeamPractitioner(eob, item, IdentifierType.TAX.getSystem(), claimLine.getProviderTaxNumber(), ClaimCareteamrole.OTHER);
            providerTaxNumber.setResponsible(true);
        }
        item.addAdjudication().setCategory(TransformerUtils.createAdjudicationCategory(CcwCodebookVariable.LINE_PRMRY_ALOWD_CHRG_AMT)).setAmount(TransformerUtils.createMoney(claimLine.getPrimaryPayerAllowedChargeAmount()));
        item.addAdjudication().setCategory(TransformerUtils.createAdjudicationCategory(CcwCodebookVariable.LINE_DME_PRCHS_PRICE_AMT)).setAmount(TransformerUtils.createMoney(claimLine.getPurchasePriceAmount()));
        if (claimLine.getScreenSavingsAmount().isPresent()) {
            // TODO should this be an adjudication?
            item.addExtension(TransformerUtils.createExtensionQuantity(CcwCodebookVariable.DMERC_LINE_SCRN_SVGS_AMT, claimLine.getScreenSavingsAmount()));
        }
        Extension mtusQuantityExtension = TransformerUtils.createExtensionQuantity(CcwCodebookVariable.DMERC_LINE_MTUS_CNT, claimLine.getMtusCount());
        item.addExtension(mtusQuantityExtension);
        if (claimLine.getMtusCode().isPresent()) {
            Quantity mtusQuantity = (Quantity) mtusQuantityExtension.getValue();
            TransformerUtils.setQuantityUnitInfo(CcwCodebookVariable.DMERC_LINE_MTUS_CD, claimLine.getMtusCode(), eob, mtusQuantity);
        }
        // Common item level fields between Carrier and DME
        TransformerUtils.mapEobCommonItemCarrierDME(item, eob, claimGroup.getClaimId(), claimLine.getServiceCount(), claimLine.getPlaceOfServiceCode(), claimLine.getFirstExpenseDate(), claimLine.getLastExpenseDate(), claimLine.getBeneficiaryPaymentAmount(), claimLine.getProviderPaymentAmount(), claimLine.getBeneficiaryPartBDeductAmount(), claimLine.getPrimaryPayerCode(), claimLine.getPrimaryPayerPaidAmount(), claimLine.getBetosCode(), claimLine.getPaymentAmount(), claimLine.getPaymentCode(), claimLine.getCoinsuranceAmount(), claimLine.getSubmittedChargeAmount(), claimLine.getAllowedChargeAmount(), claimLine.getProcessingIndicatorCode(), claimLine.getServiceDeductibleCode(), claimLine.getDiagnosisCode(), claimLine.getDiagnosisCodeVersion(), claimLine.getHctHgbTestTypeCode(), claimLine.getHctHgbTestResult(), claimLine.getCmsServiceTypeCode(), claimLine.getNationalDrugCode());
        if (!claimLine.getProviderStateCode().isEmpty()) {
            // FIXME Should this be pulled to a common mapping method?
            item.getLocation().addExtension(TransformerUtils.createExtensionCoding(eob, CcwCodebookVariable.PRVDR_STATE_CD, claimLine.getProviderStateCode()));
        }
        if (claimLine.getPricingStateCode().isPresent()) {
            item.getLocation().addExtension(TransformerUtils.createExtensionCoding(eob, CcwCodebookVariable.DMERC_LINE_PRCNG_STATE_CD, claimLine.getPricingStateCode()));
        }
        if (claimLine.getSupplierTypeCode().isPresent()) {
            // TODO should this be elsewhere; does it item.location make sense?
            item.getLocation().addExtension(TransformerUtils.createExtensionCoding(eob, CcwCodebookVariable.DMERC_LINE_SUPPLR_TYPE_CD, claimLine.getSupplierTypeCode()));
        }
    }
    TransformerUtils.setLastUpdated(eob, claimGroup.getLastUpdated());
    return eob;
}
Also used : Extension(org.hl7.fhir.dstu3.model.Extension) ItemComponent(org.hl7.fhir.dstu3.model.ExplanationOfBenefit.ItemComponent) Quantity(org.hl7.fhir.dstu3.model.Quantity) Diagnosis(gov.cms.bfd.server.war.commons.Diagnosis) ExplanationOfBenefit(org.hl7.fhir.dstu3.model.ExplanationOfBenefit) DMEClaimLine(gov.cms.bfd.model.rif.DMEClaimLine)

Aggregations

DMEClaimLine (gov.cms.bfd.model.rif.DMEClaimLine)4 BigDecimal (java.math.BigDecimal)2 ItemComponent (org.hl7.fhir.dstu3.model.ExplanationOfBenefit.ItemComponent)2 DMEClaim (gov.cms.bfd.model.rif.DMEClaim)1 RifFileRecords (gov.cms.bfd.model.rif.RifFileRecords)1 RifFilesEvent (gov.cms.bfd.model.rif.RifFilesEvent)1 RifRecordEvent (gov.cms.bfd.model.rif.RifRecordEvent)1 Diagnosis (gov.cms.bfd.server.war.commons.Diagnosis)1 ExplanationOfBenefit (org.hl7.fhir.dstu3.model.ExplanationOfBenefit)1 CareTeamComponent (org.hl7.fhir.dstu3.model.ExplanationOfBenefit.CareTeamComponent)1 Extension (org.hl7.fhir.dstu3.model.Extension)1 Quantity (org.hl7.fhir.dstu3.model.Quantity)1 CareTeamComponent (org.hl7.fhir.r4.model.ExplanationOfBenefit.CareTeamComponent)1 ItemComponent (org.hl7.fhir.r4.model.ExplanationOfBenefit.ItemComponent)1 Extension (org.hl7.fhir.r4.model.Extension)1 Quantity (org.hl7.fhir.r4.model.Quantity)1 Test (org.junit.jupiter.api.Test)1