Search in sources :

Example 6 with Quantity

use of org.hl7.fhir.r4b.model.Quantity in project beneficiary-fhir-data by CMSgov.

the class HHAClaimTransformerV2 method transformClaim.

/**
 * @param claimGroup the CCW {@link HHAClaim} to transform
 * @return a FHIR {@link ExplanationOfBenefit} resource that represents the specified {@link
 *     HHAClaim}
 */
private static ExplanationOfBenefit transformClaim(HHAClaim claimGroup) {
    ExplanationOfBenefit eob = new ExplanationOfBenefit();
    // Required values not directly mapped
    eob.getMeta().addProfile(ProfileConstants.C4BB_EOB_NONCLINICIAN_PROFILE_URL);
    // Common group level fields between all claim types
    // Claim Type + Claim ID    => ExplanationOfBenefit.id
    // CLM_ID                   => ExplanationOfBenefit.identifier
    // CLM_GRP_ID               => ExplanationOfBenefit.identifier
    // BENE_ID + Coverage Type  => ExplanationOfBenefit.insurance.coverage
    // BENE_ID                  => ExplanationOfBenefit.patient (reference)
    // FINAL_ACTION             => ExplanationOfBenefit.status
    // CLM_FROM_DT              => ExplanationOfBenefit.billablePeriod.start
    // CLM_THRU_DT              => ExplanationOfBenefit.billablePeriod.end
    // CLM_PMT_AMT              => ExplanationOfBenefit.payment.amount
    TransformerUtilsV2.mapEobCommonClaimHeaderData(eob, claimGroup.getClaimId(), claimGroup.getBeneficiaryId(), ClaimTypeV2.HHA, claimGroup.getClaimGroupId().toPlainString(), MedicareSegment.PART_B, Optional.of(claimGroup.getDateFrom()), Optional.of(claimGroup.getDateThrough()), Optional.of(claimGroup.getPaymentAmount()), claimGroup.getFinalAction());
    // NCH_WKLY_PROC_DT => ExplanationOfBenefit.supportinginfo.timingDate
    TransformerUtilsV2.addInformation(eob, TransformerUtilsV2.createInformationRecievedDateSlice(eob, CcwCodebookVariable.NCH_WKLY_PROC_DT, Optional.of(claimGroup.getWeeklyProcessDate())));
    // map eob type codes into FHIR
    // NCH_CLM_TYPE_CD            => ExplanationOfBenefit.type.coding
    // EOB Type                   => ExplanationOfBenefit.type.coding
    // Claim Type                 => ExplanationOfBenefit.type.coding
    // NCH_NEAR_LINE_REC_IDENT_CD => ExplanationOfBenefit.extension
    TransformerUtilsV2.mapEobType(eob, ClaimTypeV2.HHA, Optional.of(claimGroup.getNearLineRecordIdCode()), Optional.of(claimGroup.getClaimTypeCode()));
    // PRVDR_NUM => ExplanationOfBenefit.provider.identifier
    TransformerUtilsV2.addProviderSlice(eob, C4BBOrganizationIdentifierType.PRN, claimGroup.getProviderNumber(), claimGroup.getLastUpdated());
    // Common group level fields between Inpatient, Outpatient Hospice, HHA and SNF
    // ORG_NPI_NUM              => ExplanationOfBenefit.provider
    // CLM_FAC_TYPE_CD          => ExplanationOfBenefit.facility.extension
    // CLM_FREQ_CD              => ExplanationOfBenefit.supportingInfo
    // CLM_MDCR_NON_PMT_RSN_CD  => ExplanationOfBenefit.extension
    // PTNT_DSCHRG_STUS_CD      => ExplanationOfBenefit.supportingInfo
    // CLM_SRVC_CLSFCTN_TYPE_CD => ExplanationOfBenefit.extension
    // NCH_PRMRY_PYR_CD         => ExplanationOfBenefit.supportingInfo
    // CLM_TOT_CHRG_AMT         => ExplanationOfBenefit.total.amount
    // NCH_PRMRY_PYR_CLM_PD_AMT => ExplanationOfBenefit.benefitBalance.financial
    TransformerUtilsV2.mapEobCommonGroupInpOutHHAHospiceSNF(eob, claimGroup.getOrganizationNpi(), claimGroup.getClaimFacilityTypeCode(), claimGroup.getClaimFrequencyCode(), claimGroup.getClaimNonPaymentReasonCode(), claimGroup.getPatientDischargeStatusCode(), claimGroup.getClaimServiceClassificationTypeCode(), claimGroup.getClaimPrimaryPayerCode(), claimGroup.getTotalChargeAmount(), claimGroup.getPrimaryPayerPaidAmount(), claimGroup.getFiscalIntermediaryNumber(), claimGroup.getLastUpdated());
    // CLM_PPS_IND_CODE => ExplanationOfBenefit.supportingInfo
    TransformerUtilsV2.addInformationWithCode(eob, CcwCodebookVariable.CLM_PPS_IND_CD, CcwCodebookVariable.CLM_PPS_IND_CD, claimGroup.getProspectivePaymentCode());
    // ICD_DGNS_E_VRSN_CD(1-12) => diagnosis.diagnosisCodeableConcept
    for (Diagnosis diagnosis : DiagnosisUtilV2.extractDiagnoses(claimGroup)) {
        DiagnosisUtilV2.addDiagnosisCode(eob, diagnosis, ClaimTypeV2.HHA);
    }
    // Map care team
    // AT_PHYSN_NPI     => ExplanationOfBenefit.careTeam.provider
    // AT_PHYSN_UPIN    => ExplanationOfBenefit.careTeam.provider
    TransformerUtilsV2.mapCareTeam(eob, claimGroup.getAttendingPhysicianNpi(), Optional.empty(), Optional.empty(), claimGroup.getAttendingPhysicianUpin(), Optional.empty(), Optional.empty());
    // CLM_HHA_LUPA_IND_CD => ExplanationOfBenefit.supportinginfo.code
    claimGroup.getClaimLUPACode().ifPresent(c -> TransformerUtilsV2.addInformationWithCode(eob, CcwCodebookVariable.CLM_HHA_LUPA_IND_CD, CcwCodebookVariable.CLM_HHA_LUPA_IND_CD, c));
    // CLM_HHA_RFRL_CD => ExplanationOfBenefit.supportinginfo.code
    claimGroup.getClaimReferralCode().ifPresent(c -> TransformerUtilsV2.addInformationWithCode(eob, CcwCodebookVariable.CLM_HHA_RFRL_CD, CcwCodebookVariable.CLM_HHA_RFRL_CD, c));
    // CLM_HHA_TOT_VISIT_CNT => ExplanationOfBenefit.supportinginfo.value[x]
    TransformerUtilsV2.addInformation(eob, CcwCodebookVariable.CLM_HHA_TOT_VISIT_CNT).setValue(new Quantity(claimGroup.getTotalVisitCount().intValue()));
    // CLM_ADMSN_DT => ExplanationOfBenefit.supportingInfo:admissionperiod
    TransformerUtilsV2.addInformation(eob, TransformerUtilsV2.createInformationAdmPeriodSlice(eob, claimGroup.getCareStartDate(), Optional.empty()));
    for (HHAClaimLine line : claimGroup.getLines()) {
        ItemComponent item = eob.addItem();
        // Override the default sequence
        // CLM_LINE_NUM => item.sequence
        item.setSequence(line.getLineNumber().intValue());
        // PRVDR_STATE_CD => item.location
        TransformerUtilsV2.addLocationState(item, claimGroup.getProviderStateCode());
        // HCPCS_CD           => ExplanationOfBenefit.item.productOrService
        // HCPCS_1ST_MDFR_CD  => ExplanationOfBenefit.item.modifier
        // HCPCS_2ND_MDFR_CD  => ExplanationOfBenefit.item.modifier
        TransformerUtilsV2.mapHcpcs(eob, item, line.getHcpcsCode(), Optional.empty(), Arrays.asList(line.getHcpcsInitialModifierCode(), line.getHcpcsSecondModifierCode()));
        // REV_CNTR_1ST_ANSI_CD => ExplanationOfBenefit.item.adjudication
        TransformerUtilsV2.addAdjudication(item, TransformerUtilsV2.createAdjudicationDenialReasonSlice(eob, CcwCodebookVariable.REV_CNTR_1ST_ANSI_CD, line.getRevCntr1stAnsiCd()));
        // REV_CNTR                   => ExplanationOfBenefit.item.revenue
        // REV_CNTR_RATE_AMT          => ExplanationOfBenefit.item.adjudication
        // REV_CNTR_TOT_CHRG_AMT      => ExplanationOfBenefit.item.adjudication
        // REV_CNTR_NCVRD_CHRG_AMT    => ExplanationOfBenefit.item.adjudication
        // REV_CNTR_NDC_QTY           => ExplanationOfBenefit.item.quantity
        // REV_CNTR_NDC_QTY_QLFR_CD   => ExplanationOfBenefit.modifier
        TransformerUtilsV2.mapEobCommonItemRevenue(item, eob, line.getRevenueCenterCode(), line.getRateAmount(), line.getTotalChargeAmount(), Optional.of(line.getNonCoveredChargeAmount()), line.getNationalDrugCodeQuantity(), line.getNationalDrugCodeQualifierCode());
        // Common item level fields between Outpatient, HHA and Hospice
        // REV_CNTR_DT              => ExplanationOfBenefit.item.servicedDate
        // REV_CNTR_PMT_AMT_AMT     => ExplanationOfBenefit.item.adjudication
        TransformerUtilsV2.mapEobCommonItemRevenueOutHHAHospice(item, line.getRevenueCenterDate(), line.getPaymentAmount());
        // REV_CNTR_DDCTBL_COINSRNC_CD => item.revenue
        TransformerUtilsV2.addItemRevenue(item, eob, CcwCodebookVariable.REV_CNTR_DDCTBL_COINSRNC_CD, line.getDeductibleCoinsuranceCd());
        // RNDRNG_PHYSN_UPIN => ExplanationOfBenefit.careTeam.provider
        TransformerUtilsV2.addCareTeamMember(eob, item, C4BBPractitionerIdentifierType.UPIN, C4BBClaimProfessionalAndNonClinicianCareTeamRole.PERFORMING, line.getRevenueCenterRenderingPhysicianUPIN());
        // RNDRNG_PHYSN_NPI => ExplanationOfBenefit.careTeam.provider
        TransformerUtilsV2.addCareTeamMember(eob, item, C4BBPractitionerIdentifierType.NPI, C4BBClaimProfessionalAndNonClinicianCareTeamRole.PERFORMING, line.getRevenueCenterRenderingPhysicianNPI());
        // REV_CNTR_STUS_IND_CD => ExplanationOfBenefit.item.revenue.extension
        TransformerUtilsV2.mapEobCommonItemRevenueStatusCode(item, eob, line.getStatusCode());
    }
    TransformerUtilsV2.setLastUpdated(eob, claimGroup.getLastUpdated());
    return eob;
}
Also used : ItemComponent(org.hl7.fhir.r4.model.ExplanationOfBenefit.ItemComponent) Quantity(org.hl7.fhir.r4.model.Quantity) Diagnosis(gov.cms.bfd.server.war.commons.Diagnosis) ExplanationOfBenefit(org.hl7.fhir.r4.model.ExplanationOfBenefit) HHAClaimLine(gov.cms.bfd.model.rif.HHAClaimLine)

Example 7 with Quantity

use of org.hl7.fhir.r4b.model.Quantity in project beneficiary-fhir-data by CMSgov.

the class R4ExplanationOfBenefitResourceProviderIT method assertEobEquals.

/**
 * Compares two ExplanationOfBenefit objects in detail while working around serialization issues
 * like comparing "0" and "0.0" or creation differences like using "Quantity" vs "SimpleQuantity"
 *
 * @param expected the expected
 * @param actual the actual
 */
private static void assertEobEquals(ExplanationOfBenefit expected, ExplanationOfBenefit actual) {
    // ID in the bundle will have `ExplanationOfBenefit/` in front, so make sure the last bit
    // matches up
    assertTrue(actual.getId().endsWith(expected.getId()));
    // Clean them out so we can do a deep compare later
    actual.setId("");
    expected.setId("");
    // If there are any contained resources, they might have lastupdate times in them too
    assertEquals(expected.getContained().size(), actual.getContained().size());
    for (int i = 0; i < expected.getContained().size(); i++) {
        Resource expectedContained = expected.getContained().get(i);
        Resource actualContained = actual.getContained().get(i);
        expectedContained.getMeta().setLastUpdated(null);
        actualContained.getMeta().setLastUpdated(null);
        // TODO: HAPI seems to be inserting the `#` in the ID of the contained element.
        // This is incorrect according to the FHIR spec:
        // https://build.fhir.org/references.html#contained
        // This works around that problem
        assertEquals("#" + expectedContained.getId(), actualContained.getId());
        expectedContained.setId("");
        actualContained.setId("");
    }
    // Dates are not easy to compare so just make sure they are there
    assertNotNull(actual.getMeta().getLastUpdated());
    // We compared all of meta that we care about so get it out of the way
    expected.getMeta().setLastUpdated(null);
    actual.getMeta().setLastUpdated(null);
    // Created is required, but can't be compared
    assertNotNull(actual.getCreated());
    expected.setCreated(null);
    actual.setCreated(null);
    // Extensions may have `valueMoney` elements
    assertEquals(expected.getExtension().size(), actual.getExtension().size());
    for (int i = 0; i < expected.getExtension().size(); i++) {
        Extension expectedEx = expected.getExtension().get(i);
        Extension actualEx = actual.getExtension().get(i);
        // We have to deal with Money objects separately
        if (expectedEx.hasValue() && expectedEx.getValue() instanceof Money) {
            assertTrue(actualEx.getValue() instanceof Money);
            assertCurrencyEquals((Money) expectedEx.getValue(), (Money) actualEx.getValue());
            // Now remove since we validated so we can compare the rest directly
            expectedEx.setValue(null);
            actualEx.setValue(null);
        }
    }
    // SupportingInfo can have `valueQuantity` that has the 0 vs 0.0 issue
    assertEquals(expected.getSupportingInfo().size(), actual.getSupportingInfo().size());
    for (int i = 0; i < expected.getSupportingInfo().size(); i++) {
        SupportingInformationComponent expectedSup = expected.getSupportingInfo().get(i);
        SupportingInformationComponent actualSup = actual.getSupportingInfo().get(i);
        // We have to deal with Money objects separately
        if (expectedSup.hasValueQuantity()) {
            assertTrue(actualSup.hasValueQuantity());
            assertEquals(expectedSup.getValueQuantity().getValue().floatValue(), actualSup.getValueQuantity().getValue().floatValue(), 0.0);
            // Now remove since we validated so we can compare the rest directly
            expectedSup.setValue(null);
            actualSup.setValue(null);
        }
    }
    // line items
    assertEquals(expected.getItem().size(), actual.getItem().size());
    for (int i = 0; i < expected.getItem().size(); i++) {
        ItemComponent expectedItem = expected.getItem().get(i);
        ItemComponent actualItem = actual.getItem().get(i);
        // Compare value directly because SimpleQuantity vs Quantity can't be compared
        assertEquals(expectedItem.getQuantity().getValue().floatValue(), actualItem.getQuantity().getValue().floatValue(), 0.0);
        expectedItem.setQuantity(null);
        actualItem.setQuantity(null);
        assertEquals(expectedItem.getAdjudication().size(), actualItem.getAdjudication().size());
        for (int j = 0; j < expectedItem.getAdjudication().size(); j++) {
            AdjudicationComponent expectedAdj = expectedItem.getAdjudication().get(j);
            AdjudicationComponent actualAdj = actualItem.getAdjudication().get(j);
            // Here is where we start getting into trouble with "0" vs "0.0", so we do this manually
            if (expectedAdj.hasAmount()) {
                assertNotNull(actualAdj.getAmount());
                assertCurrencyEquals(expectedAdj.getAmount(), actualAdj.getAmount());
            } else {
                // If expected doesn't have an amount, actual shouldn't
                assertFalse(actualAdj.hasAmount());
            }
            // We just checked manually, so null them out and check the rest of the fields
            expectedAdj.setAmount(null);
            actualAdj.setAmount(null);
        }
    }
    // Total has the same problem with values
    assertEquals(expected.getTotal().size(), actual.getTotal().size());
    for (int i = 0; i < expected.getTotal().size(); i++) {
        TotalComponent expectedTot = expected.getTotal().get(i);
        TotalComponent actualTot = actual.getTotal().get(i);
        if (expectedTot.hasAmount()) {
            assertNotNull(actualTot.getAmount());
            assertCurrencyEquals(expectedTot.getAmount(), actualTot.getAmount());
        } else {
            // If expected doesn't have an amount, actual shouldn't
            assertFalse(actualTot.hasAmount());
        }
        expectedTot.setAmount(null);
        actualTot.setAmount(null);
    }
    // Benefit Balance Financial components
    assertEquals(expected.getBenefitBalance().size(), actual.getBenefitBalance().size());
    for (int i = 0; i < expected.getBenefitBalance().size(); i++) {
        BenefitBalanceComponent expectedBen = expected.getBenefitBalance().get(i);
        BenefitBalanceComponent actualBen = actual.getBenefitBalance().get(i);
        assertEquals(expectedBen.getFinancial().size(), actualBen.getFinancial().size());
        for (int j = 0; j < expectedBen.getFinancial().size(); j++) {
            BenefitComponent expectedFinancial = expectedBen.getFinancial().get(j);
            BenefitComponent actualFinancial = actualBen.getFinancial().get(j);
            // Are we dealing with Money?
            if (expectedFinancial.hasUsedMoney()) {
                assertNotNull(actualFinancial.getUsedMoney());
                assertCurrencyEquals(expectedFinancial.getUsedMoney(), actualFinancial.getUsedMoney());
                // Clean up
                expectedFinancial.setUsed(null);
                actualFinancial.setUsed(null);
            }
        }
    }
    // As does payment
    if (expected.hasPayment()) {
        assertTrue(actual.hasPayment());
        assertCurrencyEquals(expected.getPayment().getAmount(), actual.getPayment().getAmount());
    } else {
        // If expected doesn't have an amount, actual shouldn't
        assertFalse(actual.hasPayment());
    }
    expected.getPayment().setAmount(null);
    actual.getPayment().setAmount(null);
    // Now for the grand finale, we can do an `equalsDeep` on the rest
    assertTrue(expected.equalsDeep(actual));
}
Also used : Extension(org.hl7.fhir.r4.model.Extension) TotalComponent(org.hl7.fhir.r4.model.ExplanationOfBenefit.TotalComponent) Money(org.hl7.fhir.r4.model.Money) SupportingInformationComponent(org.hl7.fhir.r4.model.ExplanationOfBenefit.SupportingInformationComponent) ItemComponent(org.hl7.fhir.r4.model.ExplanationOfBenefit.ItemComponent) AdjudicationComponent(org.hl7.fhir.r4.model.ExplanationOfBenefit.AdjudicationComponent) IBaseResource(org.hl7.fhir.instance.model.api.IBaseResource) Resource(org.hl7.fhir.r4.model.Resource) BenefitBalanceComponent(org.hl7.fhir.r4.model.ExplanationOfBenefit.BenefitBalanceComponent) BenefitComponent(org.hl7.fhir.r4.model.ExplanationOfBenefit.BenefitComponent)

Example 8 with Quantity

use of org.hl7.fhir.r4b.model.Quantity in project beneficiary-fhir-data by CMSgov.

the class SNFClaimTransformerV2Test method shouldHaveLineItemQuantity.

@Test
public void shouldHaveLineItemQuantity() {
    Quantity quantity = eob.getItemFirstRep().getQuantity();
    Quantity compare = new Quantity(0);
    assertTrue(compare.equalsDeep(quantity));
}
Also used : Quantity(org.hl7.fhir.r4.model.Quantity) Test(org.junit.jupiter.api.Test)

Example 9 with Quantity

use of org.hl7.fhir.r4b.model.Quantity in project beneficiary-fhir-data by CMSgov.

the class SNFClaimTransformerV2Test method shouldHaveNchBloodPntsFrnshdQtySupInfo.

@Test
public void shouldHaveNchBloodPntsFrnshdQtySupInfo() {
    SupportingInformationComponent sic = TransformerTestUtilsV2.findSupportingInfoByCode("https://bluebutton.cms.gov/resources/variables/nch_blood_pnts_frnshd_qty", eob.getSupportingInfo());
    SupportingInformationComponent compare = TransformerTestUtilsV2.createSupportingInfo(// We don't care what the sequence number is here
    sic.getSequence(), // Category
    Arrays.asList(new Coding("http://terminology.hl7.org/CodeSystem/claiminformationcategory", "info", "Information"), new Coding("https://bluebutton.cms.gov/resources/codesystem/information", "https://bluebutton.cms.gov/resources/variables/nch_blood_pnts_frnshd_qty", "NCH Blood Pints Furnished Quantity"))).setValue(new Quantity().setValue(19).setUnit("pint").setSystem("http://unitsofmeasure.org").setCode("[pt_us]"));
    assertTrue(compare.equalsDeep(sic));
}
Also used : SupportingInformationComponent(org.hl7.fhir.r4.model.ExplanationOfBenefit.SupportingInformationComponent) Coding(org.hl7.fhir.r4.model.Coding) Quantity(org.hl7.fhir.r4.model.Quantity) Test(org.junit.jupiter.api.Test)

Example 10 with Quantity

use of org.hl7.fhir.r4b.model.Quantity in project beneficiary-fhir-data by CMSgov.

the class PartDEventTransformerV2Test method shouldHaveLineItemQuantity.

@Test
public void shouldHaveLineItemQuantity() {
    Quantity quantity = eob.getItemFirstRep().getQuantity();
    Quantity compare = new Quantity(60);
    assertTrue(compare.equalsDeep(quantity));
}
Also used : SimpleQuantity(org.hl7.fhir.r4.model.SimpleQuantity) Quantity(org.hl7.fhir.r4.model.Quantity) Test(org.junit.jupiter.api.Test)

Aggregations

Quantity (org.hl7.fhir.r4.model.Quantity)58 ArrayList (java.util.ArrayList)47 Test (org.junit.jupiter.api.Test)40 BigDecimal (java.math.BigDecimal)39 Quantity (org.hl7.fhir.dstu3.model.Quantity)39 Complex (org.hl7.fhir.r4.utils.formats.Turtle.Complex)37 Test (org.junit.Test)25 List (java.util.List)24 Complex (org.hl7.fhir.dstu2016may.formats.RdfGenerator.Complex)23 Complex (org.hl7.fhir.dstu3.utils.formats.Turtle.Complex)23 NotImplementedException (org.apache.commons.lang3.NotImplementedException)19 FHIRException (org.hl7.fhir.exceptions.FHIRException)18 PathEngineException (org.hl7.fhir.exceptions.PathEngineException)18 Observation (org.hl7.fhir.r4.model.Observation)18 UcumException (org.fhir.ucum.UcumException)16 BundleEntryComponent (org.hl7.fhir.r4.model.Bundle.BundleEntryComponent)16 Resource (org.hl7.fhir.r4.model.Resource)16 Quantity (org.hl7.fhir.r5.model.Quantity)16 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)15 Coding (org.hl7.fhir.r4.model.Coding)13