Search in sources :

Example 1 with InvalidRifValueException

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

the class TransformerUtils method createExtensionDate.

/**
 * @param ccwVariable the {@link CcwCodebookInterface} being mapped
 * @param dateYear the value to use for {@link Coding#getCode()} for the resulting {@link Coding}
 * @return the output {@link Extension}, with {@link Extension#getValue()} set to represent the
 *     specified input values
 */
static Extension createExtensionDate(CcwCodebookInterface ccwVariable, Optional<BigDecimal> dateYear) {
    Extension extension = null;
    if (!dateYear.isPresent()) {
        throw new NoSuchElementException();
    }
    try {
        String stringDate = String.format("%04d", dateYear.get().intValue());
        DateType dateYearValue = new DateType(stringDate);
        String extensionUrl = CCWUtils.calculateVariableReferenceUrl(ccwVariable);
        extension = new Extension(extensionUrl, dateYearValue);
    } catch (DataFormatException e) {
        throw new InvalidRifValueException(String.format("Unable to create DateType with reference year: '%s'.", dateYear.get()), e);
    }
    return extension;
}
Also used : IBaseExtension(org.hl7.fhir.instance.model.api.IBaseExtension) Extension(org.hl7.fhir.dstu3.model.Extension) DataFormatException(ca.uhn.fhir.parser.DataFormatException) InvalidRifValueException(gov.cms.bfd.model.rif.parse.InvalidRifValueException) DateType(org.hl7.fhir.dstu3.model.DateType) NoSuchElementException(java.util.NoSuchElementException)

Example 2 with InvalidRifValueException

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

the class PartDEventTransformerV2 method transformClaim.

/**
 * @param claimGroup the CCW {@link PartDEvent} to transform
 * @return a FHIR {@link ExplanationOfBenefit} resource that represents the specified {@link
 *     PartDEvent}
 */
private static ExplanationOfBenefit transformClaim(PartDEvent claimGroup) {
    ExplanationOfBenefit eob = new ExplanationOfBenefit();
    eob.getMeta().addProfile(ProfileConstants.C4BB_EOB_PHARMACY_PROFILE_URL);
    // Common group level fields between all claim types
    // Claim Type + Claim ID
    // => ExplanationOfBenefit.id
    // PDE_ID           => ExplanationOfBenefit.identifier
    // CLM_GRP_ID       => ExplanationOfBenefit.identifier
    // BENE_ID + Coverage Type
    // => ExplanationOfBenefit.insurance.coverage (reference)
    // BENE_ID          => ExplanationOfBenefit.patient (reference)
    // FINAL_ACTION     => ExplanationOfBenefit.status
    // SRVC_DT          => ExplanationOfBenefit.billablePeriod.start
    // SRVC_DT          => ExplanationOfBenefit.billablePeriod.end
    TransformerUtilsV2.mapEobCommonClaimHeaderData(eob, claimGroup.getEventId(), claimGroup.getBeneficiaryId(), ClaimTypeV2.PDE, claimGroup.getClaimGroupId().toPlainString(), MedicareSegment.PART_D, Optional.of(claimGroup.getPrescriptionFillDate()), Optional.of(claimGroup.getPrescriptionFillDate()), Optional.empty(), claimGroup.getFinalAction());
    // RX_SRVC_RFRNC_NUM => ExplanationOfBenefit.identifier
    eob.addIdentifier(TransformerUtilsV2.createClaimIdentifier(CcwCodebookVariable.RX_SRVC_RFRNC_NUM, claimGroup.getPrescriptionReferenceNumber().toPlainString()));
    // map eob type codes into FHIR
    // EOB Type               => ExplanationOfBenefit.type.coding
    // Claim Type  (pharmacy) => ExplanationOfBenefit.type.coding
    TransformerUtilsV2.mapEobType(eob, ClaimTypeV2.PDE, Optional.empty(), Optional.empty());
    // Coverage object is not optional, and we want to add extensions to it. This is safe.
    // PLAN_CNTRCT_REC_ID => ExplanationOfBenefit.insurance.coverage.extension
    eob.getInsuranceFirstRep().getCoverage().addExtension(TransformerUtilsV2.createExtensionIdentifier(CcwCodebookVariable.PLAN_CNTRCT_REC_ID, claimGroup.getPlanContractId()));
    // PLAN_PBP_REC_NUM => ExplanationOfBenefit.insurance.coverage.extension
    eob.getInsuranceFirstRep().getCoverage().addExtension(TransformerUtilsV2.createExtensionIdentifier(CcwCodebookVariable.PLAN_PBP_REC_NUM, claimGroup.getPlanBenefitPackageId()));
    // PD_DT => ExplanationOfBenefit.payment.date
    if (claimGroup.getPaymentDate().isPresent()) {
        eob.getPayment().setDate(TransformerUtilsV2.convertToDate(claimGroup.getPaymentDate().get()));
    }
    ItemComponent rxItem = eob.addItem();
    // 1 => ExplanationOfBenefit.item.sequence
    rxItem.setSequence(1);
    // CMPND_CD => ExplanationOfBenefit.item.programCode
    switch(claimGroup.getCompoundCode()) {
        // COMPOUNDED
        case 2:
            /* Pharmacy dispense invoice for a compound */
            TransformerUtilsV2.addInformationSlice(eob, C4BBSupportingInfoType.COMPOUND_CODE).setCode(new CodeableConcept().addCoding(new Coding().setSystem(V3ActCode.RXCINV.getSystem()).setCode(V3ActCode.RXCINV.toCode()).setDisplay(V3ActCode.RXCINV.getDisplay())));
            break;
        // NOT_COMPOUNDED
        case 1:
            /*
         * Pharmacy dispense invoice not involving a compound
         */
            TransformerUtilsV2.addInformationSlice(eob, C4BBSupportingInfoType.COMPOUND_CODE).setCode(new CodeableConcept().addCoding(new Coding().setSystem(V3ActCode.RXDINV.getSystem()).setCode(V3ActCode.RXDINV.toCode()).setDisplay(V3ActCode.RXDINV.getDisplay())));
            break;
        // NOT_SPECIFIED
        case 0:
            /*
         * Pharmacy dispense invoice not specified - do not set a value
         */
            break;
        default:
            /*
         * Unexpected value encountered - compound code should be either
         * compounded or not compounded.
         */
            throw new InvalidRifValueException("Unexpected value encountered - compound code should be either compounded or not compounded: " + claimGroup.getCompoundCode());
    }
    // SRVC_DT => ExplanationOfBenefit.item.servicedDate
    rxItem.setServiced(new DateType().setValue(TransformerUtilsV2.convertToDate(claimGroup.getPrescriptionFillDate())));
    /*
     * Create an adjudication for either CVRD_D_PLAN_PD_AMT or NCVRD_PLAN_PD_AMT,
     * depending on the value of DRUG_CVRG_STUS_CD. Stick DRUG_CVRG_STUS_CD into the
     * adjudication.reason field. CARING Slicing and CARING Adjudication Value Sets.
     */
    if (claimGroup.getDrugCoverageStatusCode() == 'C') {
        // CVRD_D_PLAN_PD_AMT => ExplanationOfBenefit.item.adjudication.amount
        TransformerUtilsV2.addAdjudication(rxItem, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.CVRD_D_PLAN_PD_AMT, C4BBAdjudication.BENEFIT, claimGroup.getPartDPlanCoveredPaidAmount()));
    } else {
        // NCVRD_PLAN_PD_AMT => ExplanationOfBenefit.item.adjudication.amount
        TransformerUtilsV2.addAdjudication(rxItem, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.CVRD_D_PLAN_PD_AMT, C4BBAdjudication.NONCOVERED, claimGroup.getPartDPlanNonCoveredPaidAmount()));
    }
    // GDC_BLW_OOPT_AMT => ExplanationOfBenefit.item.adjudication.amount
    TransformerUtilsV2.addAdjudication(rxItem, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.GDC_BLW_OOPT_AMT, C4BBAdjudication.COINSURANCE, claimGroup.getGrossCostBelowOutOfPocketThreshold()));
    // GDC_ABV_OOPT_AMT => ExplanationOfBenefit.item.adjudication.amount
    TransformerUtilsV2.addAdjudication(rxItem, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.GDC_ABV_OOPT_AMT, C4BBAdjudication.COINSURANCE, claimGroup.getGrossCostAboveOutOfPocketThreshold()));
    // PTNT_PAY_AMT => ExplanationOfBenefit.item.adjudication.amount
    TransformerUtilsV2.addAdjudication(rxItem, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.PTNT_PAY_AMT, C4BBAdjudication.PAID_BY_PATIENT, claimGroup.getPatientPaidAmount()));
    // OTHR_TROOP_AMT => ExplanationOfBenefit.item.adjudication.amount
    TransformerUtilsV2.addAdjudication(rxItem, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.OTHR_TROOP_AMT, C4BBAdjudication.PRIOR_PAYER_PAID, claimGroup.getOtherTrueOutOfPocketPaidAmount()));
    // LICS_AMT => ExplanationOfBenefit.item.adjudication.amount
    TransformerUtilsV2.addAdjudication(rxItem, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.LICS_AMT, C4BBAdjudication.DISCOUNT, claimGroup.getLowIncomeSubsidyPaidAmount()));
    // PLRO_AMT => ExplanationOfBenefit.item.adjudication.amount
    TransformerUtilsV2.addAdjudication(rxItem, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.PLRO_AMT, C4BBAdjudication.PRIOR_PAYER_PAID, claimGroup.getPatientLiabilityReductionOtherPaidAmount()));
    // TOT_RX_CST_AMT => ExplanationOfBenefit.item.adjudication.amount
    TransformerUtilsV2.addAdjudication(rxItem, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.TOT_RX_CST_AMT, C4BBAdjudication.DRUG_COST, claimGroup.getTotalPrescriptionCost()));
    // RPTD_GAP_DSCNT_NUM => ExplanationOfBenefit.item.adjudication.amount
    TransformerUtilsV2.addAdjudication(rxItem, TransformerUtilsV2.createAdjudicationAmtSlice(CcwCodebookVariable.RPTD_GAP_DSCNT_NUM, C4BBAdjudication.DISCOUNT, claimGroup.getGapDiscountAmount()));
    // Validate PRESCRBR_ID
    if (claimGroup.getPrescriberIdQualifierCode() == null || !claimGroup.getPrescriberIdQualifierCode().equalsIgnoreCase("01")) {
        throw new InvalidRifValueException("Prescriber ID Qualifier Code is invalid: " + claimGroup.getPrescriberIdQualifierCode());
    }
    // PRSCRBR_ID => ExplanationOfBenefit.careTeam.provider
    TransformerUtilsV2.addCareTeamMember(eob, rxItem, C4BBPractitionerIdentifierType.NPI, C4BBClaimPharmacyTeamRole.PRESCRIBING, Optional.ofNullable(claimGroup.getPrescriberId()));
    // This can't use TransformerUtilsV2.addNationalDrugCode because it maps differently
    // PROD_SRVC_ID => ExplanationOfBenefit.item.productOrService
    rxItem.setProductOrService(TransformerUtilsV2.createCodeableConcept(TransformerConstants.CODING_NDC, null, TransformerUtilsV2.retrieveFDADrugCodeDisplay(claimGroup.getNationalDrugCode()), claimGroup.getNationalDrugCode()));
    // QTY_DSPNSD_NUM => ExplanationOfBenefit.item.quantity
    rxItem.setQuantity(new SimpleQuantity().setValue(claimGroup.getQuantityDispensed()));
    // FILL_NUM => ExplanationOfBenefit.item.quantity.extension
    TransformerUtilsV2.addInformationSlice(eob, C4BBSupportingInfoType.REFILL_NUM).setValue(new SimpleQuantity().setValue(claimGroup.getFillNumber()));
    // DAYS_SUPLY_NUM => ExplanationOfBenefit.item.quantity.extension
    TransformerUtilsV2.addInformationSlice(eob, C4BBSupportingInfoType.DAYS_SUPPLY).setValue(new SimpleQuantity().setValue(claimGroup.getDaysSupply()));
    /*
     * This chart is to display the different code values for the different service provider id qualifier
     * codes below
     *   Code	    Code value
     *   01        National Provider Identifier (NPI)
     *   06        Unique Physician Identification Number (UPIN)
     *   07        National Council for Prescription Drug Programs (NCPDP) provider identifier
     *   08        State license number
     *   11        Federal tax number
     *   99        Other
     */
    C4BBOrganizationIdentifierType identifierType;
    if (!claimGroup.getServiceProviderId().isEmpty()) {
        switch(claimGroup.getServiceProviderIdQualiferCode()) {
            case "01":
                identifierType = C4BBOrganizationIdentifierType.NPI;
                break;
            case "06":
                identifierType = C4BBOrganizationIdentifierType.UPIN;
                break;
            case "07":
                identifierType = C4BBOrganizationIdentifierType.NCPDP;
                break;
            case "08":
                identifierType = C4BBOrganizationIdentifierType.SL;
                break;
            case "11":
                identifierType = C4BBOrganizationIdentifierType.TAX;
                break;
            default:
                identifierType = null;
                break;
        }
        // SRVC_PRVDR_ID => ExplanationOfBenefit.facility
        if (identifierType != null) {
            eob.setFacility(TransformerUtilsV2.createIdentifierReference(identifierType, claimGroup.getServiceProviderId()));
        }
    }
    /*
     * Storing code values in EOB.information below
     */
    // DRUG_CVRG_STUS_CD => ExplanationOfBenefit.supportingInfo.code
    TransformerUtilsV2.addInformationWithCode(eob, CcwCodebookVariable.DRUG_CVRG_STUS_CD, CcwCodebookVariable.DRUG_CVRG_STUS_CD, claimGroup.getDrugCoverageStatusCode());
    // DAW_PROD_SLCTN_CD => ExplanationOfBenefit.supportingInfo.code
    TransformerUtilsV2.addInformationWithCode(eob, CcwCodebookVariable.DAW_PROD_SLCTN_CD, CcwCodebookVariable.DAW_PROD_SLCTN_CD, claimGroup.getDispenseAsWrittenProductSelectionCode());
    // DAW_PROD_SLCTN_CD => ExplanationOfBenefit.supportingInfo.code
    if (claimGroup.getDispensingStatusCode().isPresent()) {
        TransformerUtilsV2.addInformationWithCode(eob, CcwCodebookVariable.DSPNSNG_STUS_CD, CcwCodebookVariable.DSPNSNG_STUS_CD, claimGroup.getDispensingStatusCode());
    }
    // DRUG_CVRG_STUS_CD => ExplanationOfBenefit.supportingInfo.code
    TransformerUtilsV2.addInformationWithCode(eob, CcwCodebookVariable.DRUG_CVRG_STUS_CD, CcwCodebookVariable.DRUG_CVRG_STUS_CD, claimGroup.getDrugCoverageStatusCode());
    // ADJSTMT_DLTN_CD => => ExplanationOfBenefit.supportingInfo.code
    if (claimGroup.getAdjustmentDeletionCode().isPresent()) {
        TransformerUtilsV2.addInformationWithCode(eob, CcwCodebookVariable.ADJSTMT_DLTN_CD, CcwCodebookVariable.ADJSTMT_DLTN_CD, claimGroup.getAdjustmentDeletionCode());
    }
    // NSTD_FRMT_CD => ExplanationOfBenefit.supportingInfo.code
    if (claimGroup.getNonstandardFormatCode().isPresent()) {
        TransformerUtilsV2.addInformationWithCode(eob, CcwCodebookVariable.NSTD_FRMT_CD, CcwCodebookVariable.NSTD_FRMT_CD, claimGroup.getNonstandardFormatCode());
    }
    // PRCNG_EXCPTN_CD => ExplanationOfBenefit.supportingInfo.code
    if (claimGroup.getPricingExceptionCode().isPresent()) {
        TransformerUtilsV2.addInformationWithCode(eob, CcwCodebookVariable.PRCNG_EXCPTN_CD, CcwCodebookVariable.PRCNG_EXCPTN_CD, claimGroup.getPricingExceptionCode());
    }
    // CTSTRPHC_CVRG_CD => ExplanationOfBenefit.supportingInfo.code
    if (claimGroup.getCatastrophicCoverageCode().isPresent()) {
        TransformerUtilsV2.addInformationWithCode(eob, CcwCodebookVariable.CTSTRPHC_CVRG_CD, CcwCodebookVariable.CTSTRPHC_CVRG_CD, claimGroup.getCatastrophicCoverageCode());
    }
    // RX_ORGN_CD => ExplanationOfBenefit.supportingInfo:rxorigincode
    TransformerUtilsV2.addInformationSliceWithCode(eob, C4BBSupportingInfoType.RX_ORIGIN_CODE, CcwCodebookVariable.RX_ORGN_CD, CcwCodebookVariable.RX_ORGN_CD, claimGroup.getPrescriptionOriginationCode());
    // BRND_GNRC_CD => ExplanationOfBenefit.supportingInfo:brandgenericcode
    TransformerUtilsV2.addInformationSliceWithCode(eob, C4BBSupportingInfoType.BRAND_GENERIC_CODE, CcwCodebookVariable.BRND_GNRC_CD, CcwCodebookVariable.BRND_GNRC_CD, claimGroup.getBrandGenericCode());
    // PHRMCY_SRVC_TYPE_CD => ExplanationOfBenefit.facility.extension
    eob.getFacility().addExtension(TransformerUtilsV2.createExtensionCoding(eob, CcwCodebookVariable.PHRMCY_SRVC_TYPE_CD, claimGroup.getPharmacyTypeCode()));
    // PTNT_RSDNC_CD => ExplanationOfBenefit.supportingInfo.code
    TransformerUtilsV2.addInformationWithCode(eob, CcwCodebookVariable.PTNT_RSDNC_CD, CcwCodebookVariable.PTNT_RSDNC_CD, claimGroup.getPatientResidenceCode());
    // SUBMSN_CLR_CD => ExplanationOfBenefit.supportingInfo.code
    if (claimGroup.getSubmissionClarificationCode().isPresent()) {
        TransformerUtilsV2.addInformationWithCode(eob, CcwCodebookVariable.SUBMSN_CLR_CD, CcwCodebookVariable.SUBMSN_CLR_CD, claimGroup.getSubmissionClarificationCode());
    }
    // Last Updated => ExplanationOfBenefit.meta.lastUpdated
    TransformerUtilsV2.setLastUpdated(eob, claimGroup.getLastUpdated());
    return eob;
}
Also used : Coding(org.hl7.fhir.r4.model.Coding) InvalidRifValueException(gov.cms.bfd.model.rif.parse.InvalidRifValueException) C4BBOrganizationIdentifierType(gov.cms.bfd.server.war.commons.carin.C4BBOrganizationIdentifierType) ItemComponent(org.hl7.fhir.r4.model.ExplanationOfBenefit.ItemComponent) SimpleQuantity(org.hl7.fhir.r4.model.SimpleQuantity) ExplanationOfBenefit(org.hl7.fhir.r4.model.ExplanationOfBenefit) DateType(org.hl7.fhir.r4.model.DateType) CodeableConcept(org.hl7.fhir.r4.model.CodeableConcept)

Example 3 with InvalidRifValueException

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

the class RifFilesProcessor method produceRecords.

/**
 * @param rifFileEvent the {@link RifFileEvent} that is being processed
 * @return a {@link RifFileRecords} with the {@link RifRecordEvent}s produced from the specified
 *     {@link RifFileEvent}
 */
public RifFileRecords produceRecords(RifFileEvent rifFileEvent) {
    RifFile file = rifFileEvent.getFile();
    /*
     * Approach used here to parse CSV as a Java 8 Stream is courtesy of
     * https://rumianom.pl/rumianom/entry/apache-commons-csv-with-java.
     */
    CSVParser parser = RifParsingUtils.createCsvParser(file);
    boolean isGrouped;
    BiFunction<RifFileEvent, List<CSVRecord>, RifRecordEvent<?>> recordParser;
    if (file.getFileType() == RifFileType.BENEFICIARY) {
        isGrouped = false;
        recordParser = RifFilesProcessor::buildBeneficiaryEvent;
    } else if (file.getFileType() == RifFileType.BENEFICIARY_HISTORY) {
        isGrouped = false;
        recordParser = RifFilesProcessor::buildBeneficiaryHistoryEvent;
    } else if (file.getFileType() == RifFileType.MEDICARE_BENEFICIARY_ID_HISTORY) {
        isGrouped = false;
        recordParser = RifFilesProcessor::buildMedicareBeneficiaryIdHistoryEvent;
    } else if (file.getFileType() == RifFileType.PDE) {
        isGrouped = false;
        recordParser = RifFilesProcessor::buildPartDEvent;
    } else if (file.getFileType() == RifFileType.CARRIER) {
        isGrouped = true;
        recordParser = RifFilesProcessor::buildCarrierClaimEvent;
    } else if (file.getFileType() == RifFileType.INPATIENT) {
        isGrouped = true;
        recordParser = RifFilesProcessor::buildInpatientClaimEvent;
    } else if (file.getFileType() == RifFileType.OUTPATIENT) {
        isGrouped = true;
        recordParser = RifFilesProcessor::buildOutpatientClaimEvent;
    } else if (file.getFileType() == RifFileType.SNF) {
        isGrouped = true;
        recordParser = RifFilesProcessor::buildSNFClaimEvent;
    } else if (file.getFileType() == RifFileType.HOSPICE) {
        isGrouped = true;
        recordParser = RifFilesProcessor::buildHospiceClaimEvent;
    } else if (file.getFileType() == RifFileType.HHA) {
        isGrouped = true;
        recordParser = RifFilesProcessor::buildHHAClaimEvent;
    } else if (file.getFileType() == RifFileType.DME) {
        isGrouped = true;
        recordParser = RifFilesProcessor::buildDMEClaimEvent;
    } else {
        throw new UnsupportedRifFileTypeException("Unsupported file type:" + file.getFileType());
    }
    /*
     * Use the CSVParser to drive a Stream of grouped CSVRecords
     * (specifically, group by claim ID/lines).
     */
    CsvRecordGrouper grouper = new ColumnValueCsvRecordGrouper(isGrouped ? file.getFileType().getIdColumn() : null);
    Iterator<List<CSVRecord>> csvIterator = new CsvRecordGroupingIterator(parser, grouper);
    Spliterator<List<CSVRecord>> spliterator = Spliterators.spliteratorUnknownSize(csvIterator, Spliterator.ORDERED | Spliterator.NONNULL);
    Stream<List<CSVRecord>> csvRecordStream = StreamSupport.stream(spliterator, false).onClose(() -> {
        try {
            /*
                     * This will also close the Reader and InputStream that the
                     * CSVParser was consuming.
                     */
            parser.close();
        } catch (IOException e) {
            LOGGER.warn("Unable to close CSVParser", e);
        }
    });
    /* Map each record group to a single RifRecordEvent. */
    Stream<RifRecordEvent<?>> rifRecordStream = csvRecordStream.map(csvRecordGroup -> {
        try {
            Timer.Context parsingTimer = rifFileEvent.getEventMetrics().timer(MetricRegistry.name(getClass().getSimpleName(), "recordParsing")).time();
            RifRecordEvent<?> recordEvent = recordParser.apply(rifFileEvent, csvRecordGroup);
            parsingTimer.close();
            return recordEvent;
        } catch (InvalidRifValueException e) {
            LOGGER.warn("Parse error encountered near line number '{}'.", csvRecordGroup.get(0).getRecordNumber());
            throw new InvalidRifValueException(e);
        }
    });
    return new RifFileRecords(rifFileEvent, rifRecordStream);
}
Also used : CsvRecordGrouper(gov.cms.bfd.pipeline.ccw.rif.extract.CsvRecordGroupingIterator.CsvRecordGrouper) ColumnValueCsvRecordGrouper(gov.cms.bfd.pipeline.ccw.rif.extract.CsvRecordGroupingIterator.ColumnValueCsvRecordGrouper) RifFile(gov.cms.bfd.model.rif.RifFile) RifFileEvent(gov.cms.bfd.model.rif.RifFileEvent) RifRecordEvent(gov.cms.bfd.model.rif.RifRecordEvent) ColumnValueCsvRecordGrouper(gov.cms.bfd.pipeline.ccw.rif.extract.CsvRecordGroupingIterator.ColumnValueCsvRecordGrouper) IOException(java.io.IOException) Timer(com.codahale.metrics.Timer) InvalidRifValueException(gov.cms.bfd.model.rif.parse.InvalidRifValueException) CSVParser(org.apache.commons.csv.CSVParser) List(java.util.List) RifFileRecords(gov.cms.bfd.model.rif.RifFileRecords) UnsupportedRifFileTypeException(gov.cms.bfd.pipeline.ccw.rif.extract.exceptions.UnsupportedRifFileTypeException)

Example 4 with InvalidRifValueException

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

the class PartDEventTransformer method transformClaim.

/**
 * @param claimGroup the CCW {@link PartDEvent} to transform
 * @return a FHIR {@link ExplanationOfBenefit} resource that represents the specified {@link
 *     PartDEvent}
 */
private static ExplanationOfBenefit transformClaim(PartDEvent claimGroup) {
    ExplanationOfBenefit eob = new ExplanationOfBenefit();
    // Common group level fields between all claim types
    TransformerUtils.mapEobCommonClaimHeaderData(eob, claimGroup.getEventId(), claimGroup.getBeneficiaryId(), ClaimType.PDE, claimGroup.getClaimGroupId().toPlainString(), MedicareSegment.PART_D, Optional.of(claimGroup.getPrescriptionFillDate()), Optional.of(claimGroup.getPrescriptionFillDate()), Optional.empty(), claimGroup.getFinalAction());
    eob.addIdentifier(TransformerUtils.createIdentifier(CcwCodebookVariable.RX_SRVC_RFRNC_NUM, claimGroup.getPrescriptionReferenceNumber().toPlainString()));
    // map eob type codes into FHIR
    TransformerUtils.mapEobType(eob, ClaimType.PDE, Optional.empty(), Optional.empty());
    eob.getInsurance().getCoverage().addExtension(TransformerUtils.createExtensionIdentifier(CcwCodebookVariable.PLAN_CNTRCT_REC_ID, claimGroup.getPlanContractId()));
    eob.getInsurance().getCoverage().addExtension(TransformerUtils.createExtensionIdentifier(CcwCodebookVariable.PLAN_PBP_REC_NUM, claimGroup.getPlanBenefitPackageId()));
    if (claimGroup.getPaymentDate().isPresent()) {
        eob.getPayment().setDate(TransformerUtils.convertToDate(claimGroup.getPaymentDate().get()));
    }
    ItemComponent rxItem = eob.addItem();
    rxItem.setSequence(1);
    ExplanationOfBenefit.DetailComponent detail = new ExplanationOfBenefit.DetailComponent();
    switch(claimGroup.getCompoundCode()) {
        // COMPOUNDED
        case 2:
            /* Pharmacy dispense invoice for a compound */
            detail.getType().addCoding(new Coding().setSystem(V3ActCode.RXCINV.getSystem()).setCode(V3ActCode.RXCINV.toCode()).setDisplay(V3ActCode.RXCINV.getDisplay()));
            break;
        // NOT_COMPOUNDED
        case 1:
            /*
         * Pharmacy dispense invoice not involving a compound
         */
            detail.getType().addCoding(new Coding().setSystem(V3ActCode.RXCINV.getSystem()).setCode(V3ActCode.RXDINV.toCode()).setDisplay(V3ActCode.RXDINV.getDisplay()));
            break;
        // NOT_SPECIFIED
        case 0:
            /*
         * Pharmacy dispense invoice not specified - do not set a value
         */
            break;
        default:
            /*
         * Unexpected value encountered - compound code should be either
         * compounded or not compounded.
         */
            throw new InvalidRifValueException("Unexpected value encountered - compound code should be either compounded or not compounded: " + claimGroup.getCompoundCode());
    }
    rxItem.addDetail(detail);
    rxItem.setServiced(new DateType().setValue(TransformerUtils.convertToDate(claimGroup.getPrescriptionFillDate())));
    /*
     * Create an adjudication for either CVRD_D_PLAN_PD_AMT or NCVRD_PLAN_PD_AMT,
     * depending on the value of DRUG_CVRG_STUS_CD. Stick DRUG_CVRG_STUS_CD into the
     * adjudication.reason field.
     */
    CodeableConcept planPaidAmountAdjudicationCategory;
    BigDecimal planPaidAmountAdjudicationValue;
    if (claimGroup.getDrugCoverageStatusCode() == 'C') {
        planPaidAmountAdjudicationCategory = TransformerUtils.createAdjudicationCategory(CcwCodebookVariable.CVRD_D_PLAN_PD_AMT);
        planPaidAmountAdjudicationValue = claimGroup.getPartDPlanCoveredPaidAmount();
    } else {
        planPaidAmountAdjudicationCategory = TransformerUtils.createAdjudicationCategory(CcwCodebookVariable.NCVRD_PLAN_PD_AMT);
        planPaidAmountAdjudicationValue = claimGroup.getPartDPlanNonCoveredPaidAmount();
    }
    rxItem.addAdjudication().setCategory(planPaidAmountAdjudicationCategory).setReason(TransformerUtils.createCodeableConcept(eob, CcwCodebookVariable.DRUG_CVRG_STUS_CD, claimGroup.getDrugCoverageStatusCode())).setAmount(TransformerUtils.createMoney(planPaidAmountAdjudicationValue));
    rxItem.addAdjudication().setCategory(TransformerUtils.createAdjudicationCategory(CcwCodebookVariable.GDC_BLW_OOPT_AMT)).setAmount(TransformerUtils.createMoney(claimGroup.getGrossCostBelowOutOfPocketThreshold()));
    rxItem.addAdjudication().setCategory(TransformerUtils.createAdjudicationCategory(CcwCodebookVariable.GDC_ABV_OOPT_AMT)).setAmount(TransformerUtils.createMoney(claimGroup.getGrossCostAboveOutOfPocketThreshold()));
    rxItem.addAdjudication().setCategory(TransformerUtils.createAdjudicationCategory(CcwCodebookVariable.PTNT_PAY_AMT)).setAmount(TransformerUtils.createMoney(claimGroup.getPatientPaidAmount()));
    rxItem.addAdjudication().setCategory(TransformerUtils.createAdjudicationCategory(CcwCodebookVariable.OTHR_TROOP_AMT)).setAmount(TransformerUtils.createMoney(claimGroup.getOtherTrueOutOfPocketPaidAmount()));
    rxItem.addAdjudication().setCategory(TransformerUtils.createAdjudicationCategory(CcwCodebookVariable.LICS_AMT)).setAmount(TransformerUtils.createMoney(claimGroup.getLowIncomeSubsidyPaidAmount()));
    rxItem.addAdjudication().setCategory(TransformerUtils.createAdjudicationCategory(CcwCodebookVariable.PLRO_AMT)).setAmount(TransformerUtils.createMoney(claimGroup.getPatientLiabilityReductionOtherPaidAmount()));
    rxItem.addAdjudication().setCategory(TransformerUtils.createAdjudicationCategory(CcwCodebookVariable.TOT_RX_CST_AMT)).setAmount(TransformerUtils.createMoney(claimGroup.getTotalPrescriptionCost()));
    rxItem.addAdjudication().setCategory(TransformerUtils.createAdjudicationCategory(CcwCodebookVariable.RPTD_GAP_DSCNT_NUM)).setAmount(TransformerUtils.createMoney(claimGroup.getGapDiscountAmount()));
    if (claimGroup.getPrescriberIdQualifierCode() == null || !claimGroup.getPrescriberIdQualifierCode().equalsIgnoreCase("01"))
        throw new InvalidRifValueException("Prescriber ID Qualifier Code is invalid: " + claimGroup.getPrescriberIdQualifierCode());
    if (claimGroup.getPrescriberId() != null) {
        TransformerUtils.addCareTeamPractitioner(eob, rxItem, TransformerConstants.CODING_NPI_US, claimGroup.getPrescriberId(), ClaimCareteamrole.PRIMARY);
    }
    rxItem.setService(TransformerUtils.createCodeableConcept(TransformerConstants.CODING_NDC, null, TransformerUtils.retrieveFDADrugCodeDisplay(claimGroup.getNationalDrugCode()), claimGroup.getNationalDrugCode()));
    SimpleQuantity quantityDispensed = new SimpleQuantity();
    quantityDispensed.setValue(claimGroup.getQuantityDispensed());
    rxItem.setQuantity(quantityDispensed);
    rxItem.getQuantity().addExtension(TransformerUtils.createExtensionQuantity(CcwCodebookVariable.FILL_NUM, claimGroup.getFillNumber()));
    rxItem.getQuantity().addExtension(TransformerUtils.createExtensionQuantity(CcwCodebookVariable.DAYS_SUPLY_NUM, claimGroup.getDaysSupply()));
    /*
     * This chart is to dosplay the different code values for the different service provider id qualifer
     * codes below
     *   Code	    Code value
     *   01        National Provider Identifier (NPI)
     *   06        Unique Physician Identification Number (UPIN)
     *   07        National Council for Prescription Drug Programs (NCPDP) provider identifier
     *   08        State license number
     *   11        Federal tax number
     *   99        Other
     */
    IdentifierType identifierType;
    if (!claimGroup.getServiceProviderId().isEmpty()) {
        switch(claimGroup.getServiceProviderIdQualiferCode()) {
            case "01":
                identifierType = IdentifierType.NPI;
                break;
            case "06":
                identifierType = IdentifierType.UPIN;
                break;
            case "07":
                identifierType = IdentifierType.NCPDP;
                break;
            case "08":
                identifierType = IdentifierType.SL;
                break;
            case "11":
                identifierType = IdentifierType.TAX;
                break;
            default:
                identifierType = null;
                break;
        }
        if (identifierType != null) {
            eob.setOrganization(TransformerUtils.createIdentifierReference(identifierType, claimGroup.getServiceProviderId()));
            eob.setFacility(TransformerUtils.createIdentifierReference(identifierType, claimGroup.getServiceProviderId()));
        }
        eob.getFacility().addExtension(TransformerUtils.createExtensionCoding(eob, CcwCodebookVariable.PHRMCY_SRVC_TYPE_CD, claimGroup.getPharmacyTypeCode()));
    }
    /*
     * Storing code values in EOB.information below
     */
    TransformerUtils.addInformationWithCode(eob, CcwCodebookVariable.DAW_PROD_SLCTN_CD, CcwCodebookVariable.DAW_PROD_SLCTN_CD, claimGroup.getDispenseAsWrittenProductSelectionCode());
    if (claimGroup.getDispensingStatusCode().isPresent())
        TransformerUtils.addInformationWithCode(eob, CcwCodebookVariable.DSPNSNG_STUS_CD, CcwCodebookVariable.DSPNSNG_STUS_CD, claimGroup.getDispensingStatusCode());
    TransformerUtils.addInformationWithCode(eob, CcwCodebookVariable.DRUG_CVRG_STUS_CD, CcwCodebookVariable.DRUG_CVRG_STUS_CD, claimGroup.getDrugCoverageStatusCode());
    if (claimGroup.getAdjustmentDeletionCode().isPresent())
        TransformerUtils.addInformationWithCode(eob, CcwCodebookVariable.ADJSTMT_DLTN_CD, CcwCodebookVariable.ADJSTMT_DLTN_CD, claimGroup.getAdjustmentDeletionCode());
    if (claimGroup.getNonstandardFormatCode().isPresent())
        TransformerUtils.addInformationWithCode(eob, CcwCodebookVariable.NSTD_FRMT_CD, CcwCodebookVariable.NSTD_FRMT_CD, claimGroup.getNonstandardFormatCode());
    if (claimGroup.getPricingExceptionCode().isPresent())
        TransformerUtils.addInformationWithCode(eob, CcwCodebookVariable.PRCNG_EXCPTN_CD, CcwCodebookVariable.PRCNG_EXCPTN_CD, claimGroup.getPricingExceptionCode());
    if (claimGroup.getCatastrophicCoverageCode().isPresent())
        TransformerUtils.addInformationWithCode(eob, CcwCodebookVariable.CTSTRPHC_CVRG_CD, CcwCodebookVariable.CTSTRPHC_CVRG_CD, claimGroup.getCatastrophicCoverageCode());
    if (claimGroup.getPrescriptionOriginationCode().isPresent())
        TransformerUtils.addInformationWithCode(eob, CcwCodebookVariable.RX_ORGN_CD, CcwCodebookVariable.RX_ORGN_CD, claimGroup.getPrescriptionOriginationCode());
    if (claimGroup.getBrandGenericCode().isPresent())
        TransformerUtils.addInformationWithCode(eob, CcwCodebookVariable.BRND_GNRC_CD, CcwCodebookVariable.BRND_GNRC_CD, claimGroup.getBrandGenericCode());
    TransformerUtils.addInformationWithCode(eob, CcwCodebookVariable.PHRMCY_SRVC_TYPE_CD, CcwCodebookVariable.PHRMCY_SRVC_TYPE_CD, claimGroup.getPharmacyTypeCode());
    TransformerUtils.addInformationWithCode(eob, CcwCodebookVariable.PTNT_RSDNC_CD, CcwCodebookVariable.PTNT_RSDNC_CD, claimGroup.getPatientResidenceCode());
    if (claimGroup.getSubmissionClarificationCode().isPresent())
        TransformerUtils.addInformationWithCode(eob, CcwCodebookVariable.SUBMSN_CLR_CD, CcwCodebookVariable.SUBMSN_CLR_CD, claimGroup.getSubmissionClarificationCode());
    TransformerUtils.setLastUpdated(eob, claimGroup.getLastUpdated());
    return eob;
}
Also used : Coding(org.hl7.fhir.dstu3.model.Coding) InvalidRifValueException(gov.cms.bfd.model.rif.parse.InvalidRifValueException) ItemComponent(org.hl7.fhir.dstu3.model.ExplanationOfBenefit.ItemComponent) SimpleQuantity(org.hl7.fhir.dstu3.model.SimpleQuantity) ExplanationOfBenefit(org.hl7.fhir.dstu3.model.ExplanationOfBenefit) DateType(org.hl7.fhir.dstu3.model.DateType) IdentifierType(gov.cms.bfd.server.war.commons.IdentifierType) BigDecimal(java.math.BigDecimal) CodeableConcept(org.hl7.fhir.dstu3.model.CodeableConcept)

Example 5 with InvalidRifValueException

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

the class TransformerUtilsV2 method createExtensionDate.

/**
 * @param ccwVariable the {@link CcwCodebookInterface} being mapped
 * @param dateYear the value to use for {@link Coding#getCode()} for the resulting {@link Coding}
 * @return the output {@link Extension}, with {@link Extension#getValue()} set to represent the
 *     specified input values
 */
static Extension createExtensionDate(CcwCodebookInterface ccwVariable, Optional<BigDecimal> dateYear) {
    Extension extension = null;
    if (!dateYear.isPresent()) {
        throw new NoSuchElementException();
    }
    try {
        String stringDate = String.format("%04d", dateYear.get().intValue());
        DateType dateYearValue = new DateType(stringDate);
        String extensionUrl = CCWUtils.calculateVariableReferenceUrl(ccwVariable);
        extension = new Extension(extensionUrl, dateYearValue);
    } catch (DataFormatException e) {
        throw new InvalidRifValueException(String.format("Unable to create DateType with reference year: '%s'.", dateYear.get()), e);
    }
    return extension;
}
Also used : Extension(org.hl7.fhir.r4.model.Extension) DataFormatException(ca.uhn.fhir.parser.DataFormatException) InvalidRifValueException(gov.cms.bfd.model.rif.parse.InvalidRifValueException) DateType(org.hl7.fhir.r4.model.DateType) NoSuchElementException(java.util.NoSuchElementException)

Aggregations

InvalidRifValueException (gov.cms.bfd.model.rif.parse.InvalidRifValueException)5 DataFormatException (ca.uhn.fhir.parser.DataFormatException)2 NoSuchElementException (java.util.NoSuchElementException)2 DateType (org.hl7.fhir.dstu3.model.DateType)2 DateType (org.hl7.fhir.r4.model.DateType)2 Timer (com.codahale.metrics.Timer)1 RifFile (gov.cms.bfd.model.rif.RifFile)1 RifFileEvent (gov.cms.bfd.model.rif.RifFileEvent)1 RifFileRecords (gov.cms.bfd.model.rif.RifFileRecords)1 RifRecordEvent (gov.cms.bfd.model.rif.RifRecordEvent)1 ColumnValueCsvRecordGrouper (gov.cms.bfd.pipeline.ccw.rif.extract.CsvRecordGroupingIterator.ColumnValueCsvRecordGrouper)1 CsvRecordGrouper (gov.cms.bfd.pipeline.ccw.rif.extract.CsvRecordGroupingIterator.CsvRecordGrouper)1 UnsupportedRifFileTypeException (gov.cms.bfd.pipeline.ccw.rif.extract.exceptions.UnsupportedRifFileTypeException)1 IdentifierType (gov.cms.bfd.server.war.commons.IdentifierType)1 C4BBOrganizationIdentifierType (gov.cms.bfd.server.war.commons.carin.C4BBOrganizationIdentifierType)1 IOException (java.io.IOException)1 BigDecimal (java.math.BigDecimal)1 List (java.util.List)1 CSVParser (org.apache.commons.csv.CSVParser)1 CodeableConcept (org.hl7.fhir.dstu3.model.CodeableConcept)1