Search in sources :

Example 1 with BeneficiaryHistory

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

the class PatientResourceProvider method queryDatabaseByHash.

/**
 * @param hash the {@link Beneficiary} hash value to match
 * @param hashType a string to represent the hash type (used for logging purposes)
 * @param requestHeader the {@link #RequestHeaders} where resource request headers are
 *     encapsulated
 * @param beneficiaryHashField the JPA location of the beneficiary hash field
 * @param beneficiaryHistoryHashField the JPA location of the beneficiary history hash field
 * @return a FHIR {@link Patient} for the CCW {@link Beneficiary} that matches the specified
 *     {@link Beneficiary} hash value
 * @throws NoResultException A {@link NoResultException} will be thrown if no matching {@link
 *     Beneficiary} can be found
 */
@Trace
private Patient queryDatabaseByHash(String hash, String hashType, SingularAttribute<Beneficiary, String> beneficiaryHashField, SingularAttribute<BeneficiaryHistory, String> beneficiaryHistoryHashField, RequestHeaders requestHeader) {
    if (hash == null || hash.trim().isEmpty())
        throw new IllegalArgumentException();
    /*
     * Beneficiaries' HICN/MBIs can change over time and those past HICN/MBIs may land in
     * BeneficiaryHistory records. Accordingly, we need to search for matching HICN/MBIs in both the
     * Beneficiary and the BeneficiaryHistory records.
     *
     * There's no sane way to do this in a single query with JPA 2.1, it appears: JPA doesn't
     * support UNIONs and it doesn't support subqueries in FROM clauses. That said, the ideal query
     * would look like this:
     *
     * SELECT * FROM ( SELECT DISTINCT "beneficiaryId" FROM "Beneficiaries" WHERE "hicn" =
     * :'hicn_hash' UNION SELECT DISTINCT "beneficiaryId" FROM "BeneficiariesHistory" WHERE "hicn" =
     * :'hicn_hash') AS matching_benes INNER JOIN "Beneficiaries" ON matching_benes."beneficiaryId"
     * = "Beneficiaries"."beneficiaryId" LEFT JOIN "BeneficiariesHistory" ON
     * "Beneficiaries"."beneficiaryId" = "BeneficiariesHistory"."beneficiaryId" LEFT JOIN
     * "MedicareBeneficiaryIdHistory" ON "Beneficiaries"."beneficiaryId" =
     * "MedicareBeneficiaryIdHistory"."beneficiaryId";
     *
     * ... with the returned columns and JOINs being dynamic, depending on IncludeIdentifiers.
     *
     * In lieu of that, we run two queries: one to find HICN/MBI matches in BeneficiariesHistory,
     * and a second to find BENE_ID or HICN/MBI matches in Beneficiaries (with all of their data, so
     * we're ready to return the result). This is bad and dumb but I can't find a better working
     * alternative.
     *
     * (I'll just note that I did also try JPA/Hibernate native SQL queries but couldn't get the
     * joins or fetch groups to work with them.)
     *
     * If we want to fix this, we need to move identifiers out entirely to separate tables:
     * BeneficiaryHicns and BeneficiaryMbis. We could then safely query these tables and join them
     * back to Beneficiaries (and hopefully the optimizer will play nice, too).
     */
    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    // First, find all matching hashes from BeneficiariesHistory.
    CriteriaQuery<String> beneHistoryMatches = builder.createQuery(String.class);
    Root<BeneficiaryHistory> beneHistoryMatchesRoot = beneHistoryMatches.from(BeneficiaryHistory.class);
    beneHistoryMatches.select(beneHistoryMatchesRoot.get(BeneficiaryHistory_.beneficiaryId));
    beneHistoryMatches.where(builder.equal(beneHistoryMatchesRoot.get(beneficiaryHistoryHashField), hash));
    List<String> matchingIdsFromBeneHistory = null;
    Long hicnsFromHistoryQueryNanoSeconds = null;
    Timer.Context beneHistoryMatchesTimer = metricRegistry.timer(MetricRegistry.name(getClass().getSimpleName(), "query", "bene_by_" + hashType, hashType + "s_from_beneficiarieshistory")).time();
    try {
        matchingIdsFromBeneHistory = entityManager.createQuery(beneHistoryMatches).getResultList();
    } finally {
        hicnsFromHistoryQueryNanoSeconds = beneHistoryMatchesTimer.stop();
        TransformerUtils.recordQueryInMdc("bene_by_" + hashType + "." + hashType + "s_from_beneficiarieshistory", hicnsFromHistoryQueryNanoSeconds, matchingIdsFromBeneHistory == null ? 0 : matchingIdsFromBeneHistory.size());
    }
    // Then, find all Beneficiary records that match the hash or those BENE_IDs.
    CriteriaQuery<Beneficiary> beneMatches = builder.createQuery(Beneficiary.class);
    Root<Beneficiary> beneMatchesRoot = beneMatches.from(Beneficiary.class);
    beneMatchesRoot.fetch(Beneficiary_.skippedRifRecords, JoinType.LEFT);
    if (requestHeader.isHICNinIncludeIdentifiers())
        beneMatchesRoot.fetch(Beneficiary_.beneficiaryHistories, JoinType.LEFT);
    if (requestHeader.isMBIinIncludeIdentifiers())
        beneMatchesRoot.fetch(Beneficiary_.medicareBeneficiaryIdHistories, JoinType.LEFT);
    beneMatches.select(beneMatchesRoot);
    Predicate beneHashMatches = builder.equal(beneMatchesRoot.get(beneficiaryHashField), hash);
    if (matchingIdsFromBeneHistory != null && !matchingIdsFromBeneHistory.isEmpty()) {
        Predicate beneHistoryHashMatches = beneMatchesRoot.get(Beneficiary_.beneficiaryId).in(matchingIdsFromBeneHistory);
        beneMatches.where(builder.or(beneHashMatches, beneHistoryHashMatches));
    } else {
        beneMatches.where(beneHashMatches);
    }
    List<Beneficiary> matchingBenes = Collections.emptyList();
    Long benesByHashOrIdQueryNanoSeconds = null;
    Timer.Context timerHicnQuery = metricRegistry.timer(MetricRegistry.name(getClass().getSimpleName(), "query", "bene_by_" + hashType, "bene_by_" + hashType + "_or_id")).time();
    try {
        matchingBenes = entityManager.createQuery(beneMatches).getResultList();
    } finally {
        benesByHashOrIdQueryNanoSeconds = timerHicnQuery.stop();
        TransformerUtils.recordQueryInMdc(String.format("bene_by_" + hashType + ".bene_by_" + hashType + "_or_id.include_%s", String.join("_", (List<String>) requestHeader.getValue(HEADER_NAME_INCLUDE_IDENTIFIERS))), benesByHashOrIdQueryNanoSeconds, matchingBenes.size());
    }
    // Then, if we found more than one distinct BENE_ID, or none, throw an error.
    long distinctBeneIds = matchingBenes.stream().map(Beneficiary::getBeneficiaryId).filter(Objects::nonNull).distinct().count();
    Beneficiary beneficiary = null;
    if (distinctBeneIds <= 0) {
        throw new NoResultException();
    } else if (distinctBeneIds > 1) {
        MDC.put("database_query.by_hash.collision.distinct_bene_ids", Long.toString(distinctBeneIds));
        throw new ResourceNotFoundException("By hash query found more than one distinct BENE_ID: " + Long.toString(distinctBeneIds));
    } else if (distinctBeneIds == 1) {
        beneficiary = matchingBenes.get(0);
    }
    // Null out the unhashed HICNs if we're not supposed to be returning them
    if (!requestHeader.isHICNinIncludeIdentifiers()) {
        beneficiary.setHicnUnhashed(Optional.empty());
    }
    // Null out the unhashed MBIs if we're not supposed to be returning
    if (!requestHeader.isMBIinIncludeIdentifiers()) {
        beneficiary.setMedicareBeneficiaryId(Optional.empty());
    }
    Patient patient = BeneficiaryTransformer.transform(metricRegistry, beneficiary, requestHeader);
    return patient;
}
Also used : CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) BeneficiaryHistory(gov.cms.bfd.model.rif.BeneficiaryHistory) Patient(org.hl7.fhir.dstu3.model.Patient) NoResultException(javax.persistence.NoResultException) Predicate(javax.persistence.criteria.Predicate) Timer(com.codahale.metrics.Timer) Objects(java.util.Objects) ResourceNotFoundException(ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException) Beneficiary(gov.cms.bfd.model.rif.Beneficiary) Trace(com.newrelic.api.agent.Trace)

Example 2 with BeneficiaryHistory

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

the class BeneficiaryTransformer method transform.

/**
 * @param beneficiary the CCW {@link Beneficiary} to transform
 * @param requestHeader {@link RequestHeaders} the holder that contains all supported resource
 *     request headers
 * @return a FHIR {@link Patient} resource that represents the specified {@link Beneficiary}
 */
private static Patient transform(Beneficiary beneficiary, RequestHeaders requestHeader) {
    Objects.requireNonNull(beneficiary);
    Patient patient = new Patient();
    /*
     * Notify end users when they receive Patient records impacted by
     * https://jira.cms.gov/browse/BFD-1566. See the documentation on
     * LoadAppOptions.isFilteringNonNullAndNon2022Benes() for details.
     */
    if (!beneficiary.getSkippedRifRecords().isEmpty()) {
        patient.getMeta().addTag(TransformerConstants.CODING_SYSTEM_BFD_TAGS, TransformerConstants.CODING_BFD_TAGS_DELAYED_BACKDATED_ENROLLMENT, TransformerConstants.CODING_BFD_TAGS_DELAYED_BACKDATED_ENROLLMENT_DISPLAY);
    }
    patient.setId(beneficiary.getBeneficiaryId());
    patient.addIdentifier(TransformerUtils.createIdentifier(CcwCodebookVariable.BENE_ID, beneficiary.getBeneficiaryId()));
    // Add hicn-hash identifier ONLY if raw hicn is requested.
    if (requestHeader.isHICNinIncludeIdentifiers()) {
        patient.addIdentifier().setSystem(TransformerConstants.CODING_BBAPI_BENE_HICN_HASH).setValue(beneficiary.getHicn());
    }
    if (beneficiary.getMbiHash().isPresent()) {
        Period mbiPeriod = new Period();
        if (beneficiary.getMbiEffectiveDate().isPresent()) {
            TransformerUtils.setPeriodStart(mbiPeriod, beneficiary.getMbiEffectiveDate().get());
        }
        if (beneficiary.getMbiObsoleteDate().isPresent()) {
            TransformerUtils.setPeriodEnd(mbiPeriod, beneficiary.getMbiObsoleteDate().get());
        }
        if (mbiPeriod.hasStart() || mbiPeriod.hasEnd()) {
            patient.addIdentifier().setSystem(TransformerConstants.CODING_BBAPI_BENE_MBI_HASH).setValue(beneficiary.getMbiHash().get()).setPeriod(mbiPeriod);
        } else {
            patient.addIdentifier().setSystem(TransformerConstants.CODING_BBAPI_BENE_MBI_HASH).setValue(beneficiary.getMbiHash().get());
        }
    }
    Extension currentIdentifier = TransformerUtils.createIdentifierCurrencyExtension(CurrencyIdentifier.CURRENT);
    Extension historicalIdentifier = TransformerUtils.createIdentifierCurrencyExtension(CurrencyIdentifier.HISTORIC);
    // Add lastUpdated
    TransformerUtils.setLastUpdated(patient, beneficiary.getLastUpdated());
    if (requestHeader.isHICNinIncludeIdentifiers()) {
        Optional<String> hicnUnhashedCurrent = beneficiary.getHicnUnhashed();
        if (hicnUnhashedCurrent.isPresent())
            addUnhashedIdentifier(patient, hicnUnhashedCurrent.get(), TransformerConstants.CODING_BBAPI_BENE_HICN_UNHASHED, currentIdentifier);
        List<String> unhashedHicns = new ArrayList<String>();
        for (BeneficiaryHistory beneHistory : beneficiary.getBeneficiaryHistories()) {
            Optional<String> hicnUnhashedHistoric = beneHistory.getHicnUnhashed();
            if (hicnUnhashedHistoric.isPresent())
                unhashedHicns.add(hicnUnhashedHistoric.get());
            TransformerUtils.updateMaxLastUpdated(patient, beneHistory.getLastUpdated());
        }
        List<String> unhashedHicnsNoDupes = unhashedHicns.stream().distinct().collect(Collectors.toList());
        for (String hicn : unhashedHicnsNoDupes) {
            addUnhashedIdentifier(patient, hicn, TransformerConstants.CODING_BBAPI_BENE_HICN_UNHASHED, historicalIdentifier);
        }
    }
    if (requestHeader.isMBIinIncludeIdentifiers()) {
        Optional<String> mbiUnhashedCurrent = beneficiary.getMedicareBeneficiaryId();
        if (mbiUnhashedCurrent.isPresent())
            addUnhashedIdentifier(patient, mbiUnhashedCurrent.get(), TransformerConstants.CODING_BBAPI_MEDICARE_BENEFICIARY_ID_UNHASHED, currentIdentifier);
        List<String> unhashedMbis = new ArrayList<String>();
        for (MedicareBeneficiaryIdHistory mbiHistory : beneficiary.getMedicareBeneficiaryIdHistories()) {
            Optional<String> mbiUnhashedHistoric = mbiHistory.getMedicareBeneficiaryId();
            if (mbiUnhashedHistoric.isPresent())
                unhashedMbis.add(mbiUnhashedHistoric.get());
            TransformerUtils.updateMaxLastUpdated(patient, mbiHistory.getLastUpdated());
        }
        List<String> unhashedMbisNoDupes = unhashedMbis.stream().distinct().collect(Collectors.toList());
        for (String mbi : unhashedMbisNoDupes) {
            addUnhashedIdentifier(patient, mbi, TransformerConstants.CODING_BBAPI_MEDICARE_BENEFICIARY_ID_UNHASHED, historicalIdentifier);
        }
    }
    // support header includeAddressFields from downstream components e.g. BB2
    // per requirement of BFD-379, BB2 always send header includeAddressFields = False
    Boolean addrHdrVal = requestHeader.getValue(PatientResourceProvider.HEADER_NAME_INCLUDE_ADDRESS_FIELDS);
    if (addrHdrVal != null && addrHdrVal) {
        patient.addAddress().setState(beneficiary.getStateCode()).setPostalCode(beneficiary.getPostalCode()).setCity(beneficiary.getDerivedCityName().orElse(null)).addLine(beneficiary.getDerivedMailingAddress1().orElse(null)).addLine(beneficiary.getDerivedMailingAddress2().orElse(null)).addLine(beneficiary.getDerivedMailingAddress3().orElse(null)).addLine(beneficiary.getDerivedMailingAddress4().orElse(null)).addLine(beneficiary.getDerivedMailingAddress5().orElse(null)).addLine(beneficiary.getDerivedMailingAddress6().orElse(null));
    } else {
        patient.addAddress().setState(beneficiary.getStateCode()).setPostalCode(beneficiary.getPostalCode());
    }
    if (beneficiary.getBirthDate() != null) {
        patient.setBirthDate(TransformerUtils.convertToDate(beneficiary.getBirthDate()));
    }
    // Death Date
    if (beneficiary.getBeneficiaryDateOfDeath().isPresent()) {
        patient.setDeceased(new DateTimeType(TransformerUtils.convertToDate(beneficiary.getBeneficiaryDateOfDeath().get()), TemporalPrecisionEnum.DAY));
    }
    char sex = beneficiary.getSex();
    if (sex == Sex.MALE.getCode())
        patient.setGender((AdministrativeGender.MALE));
    else if (sex == Sex.FEMALE.getCode())
        patient.setGender((AdministrativeGender.FEMALE));
    else
        patient.setGender((AdministrativeGender.UNKNOWN));
    if (beneficiary.getRace().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionCoding(patient, CcwCodebookVariable.RACE, beneficiary.getRace().get()));
    }
    HumanName name = patient.addName().addGiven(beneficiary.getNameGiven()).setFamily(beneficiary.getNameSurname()).setUse(HumanName.NameUse.USUAL);
    if (beneficiary.getNameMiddleInitial().isPresent())
        name.addGiven(String.valueOf(beneficiary.getNameMiddleInitial().get()));
    // The reference year of the enrollment data
    if (beneficiary.getBeneEnrollmentReferenceYear().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionDate(CcwCodebookVariable.RFRNC_YR, beneficiary.getBeneEnrollmentReferenceYear()));
    }
    // Monthly Medicare-Medicaid dual eligibility codes
    if (beneficiary.getMedicaidDualEligibilityJanCode().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionCoding(patient, CcwCodebookVariable.DUAL_01, beneficiary.getMedicaidDualEligibilityJanCode()));
    }
    if (beneficiary.getMedicaidDualEligibilityFebCode().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionCoding(patient, CcwCodebookVariable.DUAL_02, beneficiary.getMedicaidDualEligibilityFebCode()));
    }
    if (beneficiary.getMedicaidDualEligibilityMarCode().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionCoding(patient, CcwCodebookVariable.DUAL_03, beneficiary.getMedicaidDualEligibilityMarCode()));
    }
    if (beneficiary.getMedicaidDualEligibilityAprCode().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionCoding(patient, CcwCodebookVariable.DUAL_04, beneficiary.getMedicaidDualEligibilityAprCode()));
    }
    if (beneficiary.getMedicaidDualEligibilityMayCode().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionCoding(patient, CcwCodebookVariable.DUAL_05, beneficiary.getMedicaidDualEligibilityMayCode()));
    }
    if (beneficiary.getMedicaidDualEligibilityJunCode().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionCoding(patient, CcwCodebookVariable.DUAL_06, beneficiary.getMedicaidDualEligibilityJunCode()));
    }
    if (beneficiary.getMedicaidDualEligibilityJulCode().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionCoding(patient, CcwCodebookVariable.DUAL_07, beneficiary.getMedicaidDualEligibilityJulCode()));
    }
    if (beneficiary.getMedicaidDualEligibilityAugCode().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionCoding(patient, CcwCodebookVariable.DUAL_08, beneficiary.getMedicaidDualEligibilityAugCode()));
    }
    if (beneficiary.getMedicaidDualEligibilitySeptCode().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionCoding(patient, CcwCodebookVariable.DUAL_09, beneficiary.getMedicaidDualEligibilitySeptCode()));
    }
    if (beneficiary.getMedicaidDualEligibilityOctCode().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionCoding(patient, CcwCodebookVariable.DUAL_10, beneficiary.getMedicaidDualEligibilityOctCode()));
    }
    if (beneficiary.getMedicaidDualEligibilityNovCode().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionCoding(patient, CcwCodebookVariable.DUAL_11, beneficiary.getMedicaidDualEligibilityNovCode()));
    }
    if (beneficiary.getMedicaidDualEligibilityDecCode().isPresent()) {
        patient.addExtension(TransformerUtils.createExtensionCoding(patient, CcwCodebookVariable.DUAL_12, beneficiary.getMedicaidDualEligibilityDecCode()));
    }
    return patient;
}
Also used : BeneficiaryHistory(gov.cms.bfd.model.rif.BeneficiaryHistory) ArrayList(java.util.ArrayList) Patient(org.hl7.fhir.dstu3.model.Patient) Period(org.hl7.fhir.dstu3.model.Period) MedicareBeneficiaryIdHistory(gov.cms.bfd.model.rif.MedicareBeneficiaryIdHistory) Extension(org.hl7.fhir.dstu3.model.Extension) HumanName(org.hl7.fhir.dstu3.model.HumanName) DateTimeType(org.hl7.fhir.dstu3.model.DateTimeType)

Example 3 with BeneficiaryHistory

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

the class BeneficiaryTransformerV2Test method setup.

@BeforeEach
public void setup() {
    List<Object> parsedRecords = ServerTestUtils.parseData(Arrays.asList(StaticRifResourceGroup.SAMPLE_A.getResources()));
    // Pull out the base Beneficiary record and fix its HICN and MBI-HASH fields.
    beneficiary = parsedRecords.stream().filter(r -> r instanceof Beneficiary).map(r -> (Beneficiary) r).findFirst().get();
    beneficiary.getSkippedRifRecords().add(new SkippedRifRecord());
    beneficiary.setLastUpdated(Instant.now());
    beneficiary.setMbiHash(Optional.of("someMBIhash"));
    // Add the history records to the Beneficiary, but nill out the HICN fields.
    Set<BeneficiaryHistory> beneficiaryHistories = parsedRecords.stream().filter(r -> r instanceof BeneficiaryHistory).map(r -> (BeneficiaryHistory) r).filter(r -> beneficiary.getBeneficiaryId().equals(r.getBeneficiaryId())).collect(Collectors.toSet());
    beneficiary.getBeneficiaryHistories().addAll(beneficiaryHistories);
    // Add the MBI history records to the Beneficiary.
    Set<MedicareBeneficiaryIdHistory> beneficiaryMbis = parsedRecords.stream().filter(r -> r instanceof MedicareBeneficiaryIdHistory).map(r -> (MedicareBeneficiaryIdHistory) r).filter(r -> beneficiary.getBeneficiaryId().equals(r.getBeneficiaryId().orElse(null))).collect(Collectors.toSet());
    beneficiary.getMedicareBeneficiaryIdHistories().addAll(beneficiaryMbis);
    assertThat(beneficiary, is(notNullValue()));
    createPatient(RequestHeaders.getHeaderWrapper());
}
Also used : CoreMatchers.is(org.hamcrest.CoreMatchers.is) BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) StaticRifResource(gov.cms.bfd.model.rif.samples.StaticRifResource) Date(java.util.Date) Identifier(org.hl7.fhir.r4.model.Identifier) IsEmptyCollection(org.hamcrest.collection.IsEmptyCollection) Disabled(org.junit.jupiter.api.Disabled) CoreMatchers.notNullValue(org.hamcrest.CoreMatchers.notNullValue) BigDecimal(java.math.BigDecimal) FhirContext(ca.uhn.fhir.context.FhirContext) HumanName(org.hl7.fhir.r4.model.HumanName) StringType(org.hl7.fhir.r4.model.StringType) BeneficiaryHistory(gov.cms.bfd.model.rif.BeneficiaryHistory) TemporalPrecisionEnum(ca.uhn.fhir.model.api.TemporalPrecisionEnum) Patient(org.hl7.fhir.r4.model.Patient) DateType(org.hl7.fhir.r4.model.DateType) Period(org.hl7.fhir.r4.model.Period) Set(java.util.Set) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) Beneficiary(gov.cms.bfd.model.rif.Beneficiary) List(java.util.List) BooleanType(org.hl7.fhir.r4.model.BooleanType) TransformerConstants(gov.cms.bfd.server.war.commons.TransformerConstants) Coding(org.hl7.fhir.r4.model.Coding) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Optional(java.util.Optional) Extension(org.hl7.fhir.r4.model.Extension) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) SkippedRifRecord(gov.cms.bfd.model.rif.SkippedRifRecord) DateTimeType(org.hl7.fhir.r4.model.DateTimeType) CoreMatchers.not(org.hamcrest.CoreMatchers.not) SimpleDateFormat(java.text.SimpleDateFormat) ProfileConstants(gov.cms.bfd.server.war.commons.ProfileConstants) RequestHeaders(gov.cms.bfd.server.war.commons.RequestHeaders) ArrayList(java.util.ArrayList) Address(org.hl7.fhir.r4.model.Address) CcwCodebookVariable(gov.cms.bfd.model.codebook.data.CcwCodebookVariable) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) StaticRifResourceGroup(gov.cms.bfd.model.rif.samples.StaticRifResourceGroup) ServerTestUtils(gov.cms.bfd.server.war.ServerTestUtils) IParser(ca.uhn.fhir.parser.IParser) IBaseDatatype(org.hl7.fhir.instance.model.api.IBaseDatatype) MetricRegistry(com.codahale.metrics.MetricRegistry) MedicareBeneficiaryIdHistory(gov.cms.bfd.model.rif.MedicareBeneficiaryIdHistory) AdministrativeGender(org.hl7.fhir.r4.model.Enumerations.AdministrativeGender) BeneficiaryHistory(gov.cms.bfd.model.rif.BeneficiaryHistory) SkippedRifRecord(gov.cms.bfd.model.rif.SkippedRifRecord) MedicareBeneficiaryIdHistory(gov.cms.bfd.model.rif.MedicareBeneficiaryIdHistory) Beneficiary(gov.cms.bfd.model.rif.Beneficiary) BeforeEach(org.junit.jupiter.api.BeforeEach)

Example 4 with BeneficiaryHistory

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

the class RifLoaderIT method loadSampleUUnchanged.

/**
 * Runs {@link RifLoader} against the {@link StaticRifResourceGroup#SAMPLE_U} data.
 */
@Test
public void loadSampleUUnchanged() {
    loadSample(Arrays.asList(StaticRifResourceGroup.SAMPLE_A.getResources()));
    // this should insert a new beneficiary history record
    /*
     * FIXME Why is this called "_UNCHANGED" if it will result in a new bene history record? Is the
     * name off, or are we still creating some unnecessary history records?
     */
    loadSample(Arrays.asList(StaticRifResource.SAMPLE_U_BENES_UNCHANGED));
    verifyRecordPrimaryKeysPresent(Arrays.asList(StaticRifResource.SAMPLE_U_BENES_UNCHANGED));
    long start = System.currentTimeMillis();
    // this should bypass inserting a new beneficiary history record because it already exists
    loadSample(Arrays.asList(StaticRifResource.SAMPLE_U_BENES_UNCHANGED));
    /*
     * Verify that the updates worked as expected by manually checking some fields.
     */
    EntityManagerFactory entityManagerFactory = PipelineTestUtils.get().getPipelineApplicationState().getEntityManagerFactory();
    EntityManager entityManager = null;
    try {
        entityManager = entityManagerFactory.createEntityManager();
        CriteriaQuery<BeneficiaryHistory> beneficiaryHistoryCriteria = entityManager.getCriteriaBuilder().createQuery(BeneficiaryHistory.class);
        List<BeneficiaryHistory> beneficiaryHistoryEntries = entityManager.createQuery(beneficiaryHistoryCriteria.select(beneficiaryHistoryCriteria.from(BeneficiaryHistory.class))).getResultList();
        for (BeneficiaryHistory beneHistory : beneficiaryHistoryEntries) {
            assertEquals("567834", beneHistory.getBeneficiaryId());
            // A recent lastUpdated timestamp
            assertTrue(beneHistory.getLastUpdated().isPresent(), "Expected a lastUpdated field");
            long end = System.currentTimeMillis();
            // finding the time difference and converting it into seconds
            long secs = (end - start) / 1000L;
            beneHistory.getLastUpdated().ifPresent(lastUpdated -> {
                assertFalse(lastUpdated.isAfter(Instant.now().minusSeconds(secs)), "Expected not a recent lastUpdated timestamp");
            });
        }
        // Make sure the size is the same and no records have been inserted if the same fields in the
        // beneficiary history table are the same.
        assertEquals(4, beneficiaryHistoryEntries.size());
    } finally {
        if (entityManager != null)
            entityManager.close();
    }
}
Also used : BeneficiaryHistory(gov.cms.bfd.model.rif.BeneficiaryHistory) EntityManager(javax.persistence.EntityManager) EntityManagerFactory(javax.persistence.EntityManagerFactory) Test(org.junit.jupiter.api.Test)

Example 5 with BeneficiaryHistory

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

the class RifFilesProcessor method buildBeneficiaryHistoryEvent.

/**
 * @param fileEvent the {@link RifFileEvent} being processed
 * @param csvRecords the {@link CSVRecord} to be mapped (in a single-element {@link List}), which
 *     must be from a {@link RifFileType#BENEFICIARY_HISTORY} {@link RifFile}
 * @return a {@link RifRecordEvent} built from the specified {@link CSVRecord}s
 */
private static RifRecordEvent<BeneficiaryHistory> buildBeneficiaryHistoryEvent(RifFileEvent fileEvent, List<CSVRecord> csvRecords) {
    if (csvRecords.size() != 1)
        throw new BadCodeMonkeyException();
    CSVRecord csvRecord = csvRecords.get(0);
    if (LOGGER.isTraceEnabled())
        LOGGER.trace(csvRecord.toString());
    RecordAction recordAction = RecordAction.match(csvRecord.get("DML_IND"));
    BeneficiaryHistory beneficiaryHistoryRow = BeneficiaryHistoryParser.parseRif(csvRecords);
    return new RifRecordEvent<BeneficiaryHistory>(fileEvent, csvRecords, recordAction, beneficiaryHistoryRow.getBeneficiaryId(), beneficiaryHistoryRow);
}
Also used : BeneficiaryHistory(gov.cms.bfd.model.rif.BeneficiaryHistory) BadCodeMonkeyException(gov.cms.bfd.sharedutils.exceptions.BadCodeMonkeyException) RifRecordEvent(gov.cms.bfd.model.rif.RifRecordEvent) CSVRecord(org.apache.commons.csv.CSVRecord) RecordAction(gov.cms.bfd.model.rif.RecordAction)

Aggregations

BeneficiaryHistory (gov.cms.bfd.model.rif.BeneficiaryHistory)38 Beneficiary (gov.cms.bfd.model.rif.Beneficiary)30 Test (org.junit.jupiter.api.Test)29 ResourceNotFoundException (ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException)27 MedicareBeneficiaryIdHistory (gov.cms.bfd.model.rif.MedicareBeneficiaryIdHistory)27 StaticRifResourceGroup (gov.cms.bfd.model.rif.samples.StaticRifResourceGroup)26 ServerTestUtils (gov.cms.bfd.server.war.ServerTestUtils)26 RequestHeaders (gov.cms.bfd.server.war.commons.RequestHeaders)26 TransformerConstants (gov.cms.bfd.server.war.commons.TransformerConstants)26 Instant (java.time.Instant)26 Arrays (java.util.Arrays)26 List (java.util.List)26 Collectors (java.util.stream.Collectors)26 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)26 Date (java.util.Date)25 Assertions.assertNotNull (org.junit.jupiter.api.Assertions.assertNotNull)25 Assertions.assertNull (org.junit.jupiter.api.Assertions.assertNull)25 Assertions.assertTrue (org.junit.jupiter.api.Assertions.assertTrue)25 DateTimeDt (ca.uhn.fhir.model.primitive.DateTimeDt)24 Constants (ca.uhn.fhir.rest.api.Constants)24