Search in sources :

Example 16 with Identifier

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

the class CarrierClaimTransformerV2Test method shouldHaveExtensionsWithClaimClinicalTrailNumber.

@Test
public void shouldHaveExtensionsWithClaimClinicalTrailNumber() {
    Extension ex = TransformerTestUtilsV2.findExtensionByUrl("https://bluebutton.cms.gov/resources/variables/clm_clncl_tril_num", eob.getExtension());
    Identifier identifier = new Identifier().setSystem("https://bluebutton.cms.gov/resources/variables/clm_clncl_tril_num").setValue("0");
    Extension compare = new Extension("https://bluebutton.cms.gov/resources/variables/clm_clncl_tril_num", identifier);
    assertTrue(compare.equalsDeep(ex));
}
Also used : Extension(org.hl7.fhir.r4.model.Extension) Identifier(org.hl7.fhir.r4.model.Identifier) Test(org.junit.jupiter.api.Test)

Example 17 with Identifier

use of org.hl7.fhir.r4b.model.Identifier 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 18 with Identifier

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

the class R4CoverageResourceProvider method searchByBeneficiary.

/**
 * Adds support for the FHIR "search" operation for {@link Coverage}s, allowing users to search by
 * {@link Coverage#getBeneficiary()}.
 *
 * <p>The {@link Search} annotation indicates that this method supports the search operation.
 * There may be many different methods annotated with this {@link Search} annotation, to support
 * many different search criteria.
 *
 * @param beneficiary a {@link ReferenceParam} for the {@link Coverage#getBeneficiary()} to try
 *     and find matches for
 * @param startIndex an {@link OptionalParam} for the startIndex (or offset) used to determine
 *     pagination
 * @param lastUpdated an {@link OptionalParam} to filter the results based on the passed date
 *     range
 * @param requestDetails a {@link RequestDetails} containing the details of the request URL, used
 *     to parse out pagination values
 * @return Returns a {@link List} of {@link Coverage}s, which may contain multiple matching
 *     resources, or may also be empty.
 */
@Search
@Trace
public Bundle searchByBeneficiary(@RequiredParam(name = Coverage.SP_BENEFICIARY) @Description(shortDefinition = "The patient identifier to search for") ReferenceParam beneficiary, @OptionalParam(name = "startIndex") @Description(shortDefinition = "The offset used for result pagination") String startIndex, @OptionalParam(name = "_lastUpdated") @Description(shortDefinition = "Include resources last updated in the given range") DateRangeParam lastUpdated, RequestDetails requestDetails) {
    List<IBaseResource> coverages;
    try {
        Beneficiary beneficiaryEntity = findBeneficiaryById(beneficiary.getIdPart(), lastUpdated);
        if (!beneficiaryEntity.getBeneEnrollmentReferenceYear().isPresent()) {
            throw new ResourceNotFoundException("Cannot find coverage for non present enrollment year");
        }
        coverages = CoverageTransformerV2.transform(metricRegistry, beneficiaryEntity);
    } catch (NoResultException e) {
        coverages = new LinkedList<IBaseResource>();
    }
    OffsetLinkBuilder paging = new OffsetLinkBuilder(requestDetails, "/Coverage?");
    Operation operation = new Operation(Operation.Endpoint.V2_COVERAGE);
    operation.setOption("by", "beneficiary");
    operation.setOption("pageSize", paging.isPagingRequested() ? "" + paging.getPageSize() : "*");
    operation.setOption("_lastUpdated", Boolean.toString(lastUpdated != null && !lastUpdated.isEmpty()));
    operation.publishOperationName();
    // Add bene_id to MDC logs
    TransformerUtilsV2.logBeneIdToMdc(Arrays.asList(beneficiary.getIdPart()));
    return TransformerUtilsV2.createBundle(paging, coverages, loadedFilterManager.getTransactionTime());
}
Also used : OffsetLinkBuilder(gov.cms.bfd.server.war.commons.OffsetLinkBuilder) NoResultException(javax.persistence.NoResultException) Operation(gov.cms.bfd.server.war.Operation) IBaseResource(org.hl7.fhir.instance.model.api.IBaseResource) ResourceNotFoundException(ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException) LinkedList(java.util.LinkedList) Beneficiary(gov.cms.bfd.model.rif.Beneficiary) Trace(com.newrelic.api.agent.Trace) Search(ca.uhn.fhir.rest.annotation.Search)

Example 19 with Identifier

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

the class R4PatientResourceProvider method searchByIdentifier.

/**
 * Adds support for the FHIR "search" operation for {@link Patient}s, allowing users to search by
 * {@link Patient#getIdentifier()}. Specifically, the following criteria are supported:
 *
 * <p>Searches that don't match one of the above forms are not supported.
 *
 * <p>The {@link Search} annotation indicates that this method supports the search operation.
 * There may be many different methods annotated with this {@link Search} annotation, to support
 * many different search criteria.
 *
 * @param identifier an {@link Identifier} {@link TokenParam} for the {@link
 *     Patient#getIdentifier()} to try and find a matching {@link Patient} for
 * @param startIndex an {@link OptionalParam} for the startIndex (or offset) used to determine
 *     pagination
 * @param lastUpdated an {@link OptionalParam} to filter the results based on the passed date
 *     range
 * @param requestDetails a {@link RequestDetails} containing the details of the request URL, used
 *     to parse out pagination values
 * @return Returns a {@link List} of {@link Patient}s, which may contain multiple matching
 *     resources, or may also be empty.
 */
@Search
@Trace
public Bundle searchByIdentifier(@RequiredParam(name = Patient.SP_IDENTIFIER) @Description(shortDefinition = "The patient identifier to search for") TokenParam identifier, @OptionalParam(name = "startIndex") @Description(shortDefinition = "The offset used for result pagination") String startIndex, @OptionalParam(name = "_lastUpdated") @Description(shortDefinition = "Include resources last updated in the given range") DateRangeParam lastUpdated, RequestDetails requestDetails) {
    if (identifier.getQueryParameterQualifier() != null) {
        throw new InvalidRequestException("Unsupported query parameter qualifier: " + identifier.getQueryParameterQualifier());
    }
    if (!SUPPORTED_HASH_IDENTIFIER_SYSTEMS.contains(identifier.getSystem()))
        throw new InvalidRequestException("Unsupported identifier system: " + identifier.getSystem());
    RequestHeaders requestHeader = RequestHeaders.getHeaderWrapper(requestDetails);
    Operation operation = new Operation(Operation.Endpoint.V2_PATIENT);
    operation.setOption("by", "identifier");
    requestHeader.getNVPairs().forEach((n, v) -> operation.setOption(n, v.toString()));
    operation.setOption("_lastUpdated", Boolean.toString(lastUpdated != null && !lastUpdated.isEmpty()));
    operation.publishOperationName();
    List<IBaseResource> patients;
    try {
        Patient patient;
        switch(identifier.getSystem()) {
            case TransformerConstants.CODING_BBAPI_BENE_MBI_HASH:
                patient = queryDatabaseByMbiHash(identifier.getValue(), requestHeader);
                break;
            case TransformerConstants.CODING_BBAPI_BENE_HICN_HASH:
            case TransformerConstants.CODING_BBAPI_BENE_HICN_HASH_OLD:
                patient = queryDatabaseByHicnHash(identifier.getValue(), requestHeader);
                break;
            default:
                throw new InvalidRequestException("Unsupported identifier system: " + identifier.getSystem());
        }
        patients = QueryUtils.isInRange(patient.getMeta().getLastUpdated().toInstant(), lastUpdated) ? Collections.singletonList(patient) : Collections.emptyList();
    } catch (NoResultException e) {
        patients = new LinkedList<>();
    }
    OffsetLinkBuilder paging = new OffsetLinkBuilder(requestDetails, "/Patient?");
    return TransformerUtilsV2.createBundle(paging, patients, loadedFilterManager.getTransactionTime());
}
Also used : OffsetLinkBuilder(gov.cms.bfd.server.war.commons.OffsetLinkBuilder) Patient(org.hl7.fhir.r4.model.Patient) InvalidRequestException(ca.uhn.fhir.rest.server.exceptions.InvalidRequestException) Operation(gov.cms.bfd.server.war.Operation) NoResultException(javax.persistence.NoResultException) RequestHeaders(gov.cms.bfd.server.war.commons.RequestHeaders) IBaseResource(org.hl7.fhir.instance.model.api.IBaseResource) LinkedList(java.util.LinkedList) Trace(com.newrelic.api.agent.Trace) Search(ca.uhn.fhir.rest.annotation.Search)

Example 20 with Identifier

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

the class R4PatientResourceProvider method searchByLogicalId.

/**
 * Adds support for the FHIR "search" operation for {@link Patient}s, allowing users to search by
 * {@link Patient#getId()}.
 *
 * <p>The {@link Search} annotation indicates that this method supports the search operation.
 * There may be many different methods annotated with this {@link Search} annotation, to support
 * many different search criteria.
 *
 * @param logicalId a {@link TokenParam} (with no system, per the spec) for the {@link
 *     Patient#getId()} to try and find a matching {@link Patient} for
 * @param startIndex an {@link OptionalParam} for the startIndex (or offset) used to determine
 *     pagination
 * @param lastUpdated an {@link OptionalParam} to filter the results based on the passed date
 *     range
 * @param requestDetails a {@link RequestDetails} containing the details of the request URL, used
 *     to parse out pagination values
 * @return Returns a {@link List} of {@link Patient}s, which may contain multiple matching
 *     resources, or may also be empty.
 */
@Search
@Trace
public Bundle searchByLogicalId(@RequiredParam(name = Patient.SP_RES_ID) @Description(shortDefinition = "The patient identifier to search for") TokenParam logicalId, @OptionalParam(name = "startIndex") @Description(shortDefinition = "The offset used for result pagination") String startIndex, @OptionalParam(name = "_lastUpdated") @Description(shortDefinition = "Include resources last updated in the given range") DateRangeParam lastUpdated, RequestDetails requestDetails) {
    if (logicalId.getQueryParameterQualifier() != null)
        throw new InvalidRequestException("Unsupported query parameter qualifier: " + logicalId.getQueryParameterQualifier());
    if (logicalId.getSystem() != null && !logicalId.getSystem().isEmpty())
        throw new InvalidRequestException("Unsupported query parameter system: " + logicalId.getSystem());
    if (logicalId.getValueNotNull().isEmpty())
        throw new InvalidRequestException("Unsupported query parameter value: " + logicalId.getValue());
    List<IBaseResource> patients;
    if (loadedFilterManager.isResultSetEmpty(logicalId.getValue(), lastUpdated)) {
        patients = Collections.emptyList();
    } else {
        try {
            patients = Optional.of(read(new IdType(logicalId.getValue()), requestDetails)).filter(p -> QueryUtils.isInRange(p.getMeta().getLastUpdated().toInstant(), lastUpdated)).map(p -> Collections.singletonList((IBaseResource) p)).orElse(Collections.emptyList());
        } catch (ResourceNotFoundException e) {
            patients = Collections.emptyList();
        }
    }
    /*
     * Publish the operation name. Note: This is a bit later than we'd normally do this, as we need
     * to override the operation name that was published by the possible call to read(...), above.
     */
    RequestHeaders requestHeader = RequestHeaders.getHeaderWrapper(requestDetails);
    Operation operation = new Operation(Operation.Endpoint.V2_PATIENT);
    operation.setOption("by", "id");
    // track all api hdrs
    requestHeader.getNVPairs().forEach((n, v) -> operation.setOption(n, v.toString()));
    operation.setOption("_lastUpdated", Boolean.toString(lastUpdated != null && !lastUpdated.isEmpty()));
    operation.publishOperationName();
    OffsetLinkBuilder paging = new OffsetLinkBuilder(requestDetails, "/Patient?");
    Bundle bundle = TransformerUtilsV2.createBundle(paging, patients, loadedFilterManager.getTransactionTime());
    return bundle;
}
Also used : IdParam(ca.uhn.fhir.rest.annotation.IdParam) Arrays(java.util.Arrays) PatientLinkBuilder(gov.cms.bfd.server.war.commons.PatientLinkBuilder) Description(ca.uhn.fhir.model.api.annotation.Description) Identifier(org.hl7.fhir.r4.model.Identifier) NoResultException(javax.persistence.NoResultException) StringUtils(org.apache.commons.lang3.StringUtils) BigDecimal(java.math.BigDecimal) DateRangeParam(ca.uhn.fhir.rest.param.DateRangeParam) Predicate(javax.persistence.criteria.Predicate) IResourceProvider(ca.uhn.fhir.rest.server.IResourceProvider) IBaseResource(org.hl7.fhir.instance.model.api.IBaseResource) Map(java.util.Map) CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) JoinType(javax.persistence.criteria.JoinType) BeneficiaryHistory(gov.cms.bfd.model.rif.BeneficiaryHistory) LoadedFilterManager(gov.cms.bfd.server.war.commons.LoadedFilterManager) Patient(org.hl7.fhir.r4.model.Patient) SingularAttribute(javax.persistence.metamodel.SingularAttribute) CriteriaQuery(javax.persistence.criteria.CriteriaQuery) IdDt(ca.uhn.fhir.model.primitive.IdDt) InvalidRequestException(ca.uhn.fhir.rest.server.exceptions.InvalidRequestException) BeneficiaryMonthly_(gov.cms.bfd.model.rif.BeneficiaryMonthly_) QueryHints(org.hibernate.jpa.QueryHints) Collectors(java.util.stream.Collectors) BeneficiaryMonthly(gov.cms.bfd.model.rif.BeneficiaryMonthly) Objects(java.util.Objects) Beneficiary(gov.cms.bfd.model.rif.Beneficiary) List(java.util.List) BeneficiaryHistory_(gov.cms.bfd.model.rif.BeneficiaryHistory_) TransformerConstants(gov.cms.bfd.server.war.commons.TransformerConstants) Year(java.time.Year) LocalDate(java.time.LocalDate) Timer(com.codahale.metrics.Timer) Optional(java.util.Optional) OptionalParam(ca.uhn.fhir.rest.annotation.OptionalParam) QueryUtils(gov.cms.bfd.server.war.commons.QueryUtils) Trace(com.newrelic.api.agent.Trace) HashMap(java.util.HashMap) RequestHeaders(gov.cms.bfd.server.war.commons.RequestHeaders) TypedQuery(javax.persistence.TypedQuery) Beneficiary_(gov.cms.bfd.model.rif.Beneficiary_) ArrayList(java.util.ArrayList) RequiredParam(ca.uhn.fhir.rest.annotation.RequiredParam) Inject(javax.inject.Inject) Strings(com.google.common.base.Strings) RequestDetails(ca.uhn.fhir.rest.api.server.RequestDetails) Search(ca.uhn.fhir.rest.annotation.Search) CcwCodebookVariable(gov.cms.bfd.model.codebook.data.CcwCodebookVariable) ResourceNotFoundException(ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException) CommonHeaders(gov.cms.bfd.server.war.commons.CommonHeaders) LinkedList(java.util.LinkedList) Root(javax.persistence.criteria.Root) Read(ca.uhn.fhir.rest.annotation.Read) OffsetLinkBuilder(gov.cms.bfd.server.war.commons.OffsetLinkBuilder) MetricRegistry(com.codahale.metrics.MetricRegistry) Operation(gov.cms.bfd.server.war.Operation) EntityManager(javax.persistence.EntityManager) PersistenceContext(javax.persistence.PersistenceContext) IdType(org.hl7.fhir.r4.model.IdType) TokenParam(ca.uhn.fhir.rest.param.TokenParam) Component(org.springframework.stereotype.Component) MDC(org.slf4j.MDC) YearMonth(java.time.YearMonth) Bundle(org.hl7.fhir.r4.model.Bundle) Collections(java.util.Collections) OffsetLinkBuilder(gov.cms.bfd.server.war.commons.OffsetLinkBuilder) Bundle(org.hl7.fhir.r4.model.Bundle) InvalidRequestException(ca.uhn.fhir.rest.server.exceptions.InvalidRequestException) Operation(gov.cms.bfd.server.war.Operation) IBaseResource(org.hl7.fhir.instance.model.api.IBaseResource) ResourceNotFoundException(ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException) RequestHeaders(gov.cms.bfd.server.war.commons.RequestHeaders) IdType(org.hl7.fhir.r4.model.IdType) Trace(com.newrelic.api.agent.Trace) Search(ca.uhn.fhir.rest.annotation.Search)

Aggregations

Identifier (org.hl7.fhir.r4.model.Identifier)212 Complex (org.hl7.fhir.r4.utils.formats.Turtle.Complex)143 Complex (org.hl7.fhir.dstu3.utils.formats.Turtle.Complex)125 Complex (org.hl7.fhir.dstu2016may.formats.RdfGenerator.Complex)116 Test (org.junit.Test)90 Test (org.junit.jupiter.api.Test)84 CodeableConcept (org.hl7.fhir.r4.model.CodeableConcept)66 ArrayList (java.util.ArrayList)62 Reference (org.hl7.fhir.r4.model.Reference)57 Identifier (org.hl7.fhir.dstu3.model.Identifier)55 Patient (org.hl7.fhir.r4.model.Patient)55 Coding (org.hl7.fhir.r4.model.Coding)49 IBaseResource (org.hl7.fhir.instance.model.api.IBaseResource)41 Practitioner (org.hl7.fhir.r4.model.Practitioner)41 Date (java.util.Date)40 List (java.util.List)40 Resource (org.hl7.fhir.r4.model.Resource)37 BundleEntryComponent (org.hl7.fhir.r4.model.Bundle.BundleEntryComponent)36 InvalidRequestException (ca.uhn.fhir.rest.server.exceptions.InvalidRequestException)34 Collectors (java.util.stream.Collectors)31