use of org.hl7.fhir.r4b.model.Range in project beneficiary-fhir-data by CMSgov.
the class TransformerUtilsV2 method createInformationAdmPeriodSlice.
/**
* Optionally creates an `admissionperiod` {@link SupportingInformationComponent} slice.
*
* @param periodStart Period start
* @param periodEnd Period end
* @return The created {@link SupportingInformationComponent}
*/
static Optional<SupportingInformationComponent> createInformationAdmPeriodSlice(ExplanationOfBenefit eob, Optional<LocalDate> periodStart, Optional<LocalDate> periodEnd) {
// Create a range if we can
if (periodStart.isPresent() || periodEnd.isPresent()) {
validatePeriodDates(periodStart, periodEnd);
// Create the period
Period period = new Period();
periodStart.ifPresent(start -> period.setStart(convertToDate(start), TemporalPrecisionEnum.DAY));
periodEnd.ifPresent(end -> period.setEnd(convertToDate(end), TemporalPrecisionEnum.DAY));
int maxSequence = eob.getSupportingInfo().stream().mapToInt(i -> i.getSequence()).max().orElse(0);
// Create the SupportingInfo element
return Optional.of(new SupportingInformationComponent().setSequence(maxSequence + 1).setCategory(new CodeableConcept().addCoding(createC4BBSupportingInfoCoding(C4BBSupportingInfoType.ADMISSION_PERIOD))).setTiming(period));
} else {
return Optional.empty();
}
}
use of org.hl7.fhir.r4b.model.Range in project beneficiary-fhir-data by CMSgov.
the class R4ExplanationOfBenefitResourceProvider method findByPatient.
/**
* Adds support for the FHIR "search" operation for {@link ExplanationOfBenefit}s, allowing users
* to search by {@link ExplanationOfBenefit#getPatient()}.
*
* <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 patient a {@link ReferenceParam} for the {@link ExplanationOfBenefit#getPatient()} to
* try and find matches for {@link ExplanationOfBenefit}s
* @param type a list of {@link ClaimTypeV2} to include in the result. Defaults to all types.
* @param startIndex an {@link OptionalParam} for the startIndex (or offset) used to determine
* pagination
* @param excludeSamhsa an {@link OptionalParam} that, if <code>"true"</code>, will use {@link
* R4EobSamhsaMatcher} to filter out all SAMHSA-related claims from the results
* @param lastUpdated an {@link OptionalParam} that specifies a date range for the lastUpdated
* field.
* @param serviceDate an {@link OptionalParam} that specifies a date range for {@link
* ExplanationOfBenefit}s that completed
* @param requestDetails a {@link RequestDetails} containing the details of the request URL, used
* to parse out pagination values
* @return Returns a {@link Bundle} of {@link ExplanationOfBenefit}s, which may contain multiple
* matching resources, or may also be empty.
*/
@Search
@Trace
public Bundle findByPatient(@RequiredParam(name = ExplanationOfBenefit.SP_PATIENT) @Description(shortDefinition = "The patient identifier to search for") ReferenceParam patient, @OptionalParam(name = "type") @Description(shortDefinition = "A list of claim types to include") TokenAndListParam type, @OptionalParam(name = "startIndex") @Description(shortDefinition = "The offset used for result pagination") String startIndex, @OptionalParam(name = "excludeSAMHSA") @Description(shortDefinition = "If true, exclude all SAMHSA-related resources") String excludeSamhsa, @OptionalParam(name = "_lastUpdated") @Description(shortDefinition = "Include resources last updated in the given range") DateRangeParam lastUpdated, @OptionalParam(name = "service-date") @Description(shortDefinition = "Include resources that completed in the given range") DateRangeParam serviceDate, RequestDetails requestDetails) {
/*
* startIndex is an optional parameter here because it must be declared in the
* event it is passed in. However, it is not being used here because it is also
* contained within requestDetails and parsed out along with other parameters
* later.
*/
String beneficiaryId = patient.getIdPart();
Set<ClaimTypeV2> claimTypes = parseTypeParam(type);
OffsetLinkBuilder paging = new OffsetLinkBuilder(requestDetails, "/ExplanationOfBenefit?");
boolean includeTaxNumbers = returnIncludeTaxNumbers(requestDetails);
Operation operation = new Operation(Operation.Endpoint.V2_EOB);
operation.setOption("by", "patient");
operation.setOption("IncludeTaxNumbers", "" + includeTaxNumbers);
operation.setOption("types", (claimTypes.size() == ClaimTypeV2.values().length) ? "*" : claimTypes.stream().sorted(Comparator.comparing(ClaimTypeV2::name)).collect(Collectors.toList()).toString());
operation.setOption("pageSize", paging.isPagingRequested() ? "" + paging.getPageSize() : "*");
operation.setOption("_lastUpdated", Boolean.toString(lastUpdated != null && !lastUpdated.isEmpty()));
operation.setOption("service-date", Boolean.toString(serviceDate != null && !serviceDate.isEmpty()));
operation.publishOperationName();
List<IBaseResource> eobs = new ArrayList<IBaseResource>();
// Optimize when the lastUpdated parameter is specified and result set is empty
if (loadedFilterManager.isResultSetEmpty(beneficiaryId, lastUpdated)) {
return TransformerUtilsV2.createBundle(paging, eobs, loadedFilterManager.getTransactionTime());
}
/*
* The way our JPA/SQL schema is setup, we have to run a separate search for
* each claim type, then combine the results. It's not super efficient, but it's
* also not so inefficient that it's worth fixing.
*/
if (claimTypes.contains(ClaimTypeV2.CARRIER)) {
eobs.addAll(transformToEobs(ClaimTypeV2.CARRIER, findClaimTypeByPatient(ClaimTypeV2.CARRIER, beneficiaryId, lastUpdated, serviceDate), Optional.of(includeTaxNumbers)));
}
if (claimTypes.contains(ClaimTypeV2.DME)) {
eobs.addAll(transformToEobs(ClaimTypeV2.DME, findClaimTypeByPatient(ClaimTypeV2.DME, beneficiaryId, lastUpdated, serviceDate), Optional.of(includeTaxNumbers)));
}
if (claimTypes.contains(ClaimTypeV2.HHA)) {
eobs.addAll(transformToEobs(ClaimTypeV2.HHA, findClaimTypeByPatient(ClaimTypeV2.HHA, beneficiaryId, lastUpdated, serviceDate), Optional.of(includeTaxNumbers)));
}
if (claimTypes.contains(ClaimTypeV2.HOSPICE)) {
eobs.addAll(transformToEobs(ClaimTypeV2.HOSPICE, findClaimTypeByPatient(ClaimTypeV2.HOSPICE, beneficiaryId, lastUpdated, serviceDate), Optional.of(includeTaxNumbers)));
}
if (claimTypes.contains(ClaimTypeV2.INPATIENT)) {
eobs.addAll(transformToEobs(ClaimTypeV2.INPATIENT, findClaimTypeByPatient(ClaimTypeV2.INPATIENT, beneficiaryId, lastUpdated, serviceDate), Optional.of(includeTaxNumbers)));
}
if (claimTypes.contains(ClaimTypeV2.OUTPATIENT)) {
eobs.addAll(transformToEobs(ClaimTypeV2.OUTPATIENT, findClaimTypeByPatient(ClaimTypeV2.OUTPATIENT, beneficiaryId, lastUpdated, serviceDate), Optional.of(includeTaxNumbers)));
}
if (claimTypes.contains(ClaimTypeV2.PDE)) {
eobs.addAll(transformToEobs(ClaimTypeV2.PDE, findClaimTypeByPatient(ClaimTypeV2.PDE, beneficiaryId, lastUpdated, serviceDate), Optional.of(includeTaxNumbers)));
}
if (claimTypes.contains(ClaimTypeV2.SNF)) {
eobs.addAll(transformToEobs(ClaimTypeV2.SNF, findClaimTypeByPatient(ClaimTypeV2.SNF, beneficiaryId, lastUpdated, serviceDate), Optional.of(includeTaxNumbers)));
}
if (Boolean.parseBoolean(excludeSamhsa)) {
filterSamhsa(eobs);
}
eobs.sort(R4ExplanationOfBenefitResourceProvider::compareByClaimIdThenClaimType);
// Add bene_id to MDC logs
TransformerUtilsV2.logBeneIdToMdc(Arrays.asList(beneficiaryId));
return TransformerUtilsV2.createBundle(paging, eobs, loadedFilterManager.getTransactionTime());
}
use of org.hl7.fhir.r4b.model.Range in project beneficiary-fhir-data by CMSgov.
the class R4ExplanationOfBenefitResourceProviderIT method searchEobWithLastUpdatedAndPaginationAndType.
/**
* Verifies that {@link
* gov.cms.bfd.server.war.r4.providers.ExplanationOfBenefitResourceProvider#findByPatient} works
* as with a lastUpdated parameter after yesterday.
*
* @throws FHIRException (indicates test failure)
*/
@Test
public void searchEobWithLastUpdatedAndPaginationAndType() throws FHIRException {
Beneficiary beneficiary = loadSampleA();
IGenericClient fhirClient = ServerTestUtils.get().createFhirClientV2();
// Search with lastUpdated range between yesterday and now
int expectedCount = 3;
Date yesterday = Date.from(Instant.now().minus(1, ChronoUnit.DAYS));
Date now = new Date();
DateRangeParam afterYesterday = new DateRangeParam(yesterday, now);
Bundle searchResultsAfter = fhirClient.search().forResource(ExplanationOfBenefit.class).where(ExplanationOfBenefit.PATIENT.hasId(TransformerUtilsV2.buildPatientId(beneficiary))).lastUpdated(afterYesterday).count(expectedCount).returnBundle(Bundle.class).execute();
assertEquals(expectedCount, searchResultsAfter.getEntry().size(), "Expected number resources return to be equal to count");
// Check self url
String selfLink = searchResultsAfter.getLink(IBaseBundle.LINK_SELF).getUrl();
assertTrue(selfLink.contains("lastUpdated"));
// Check next bundle
String nextLink = searchResultsAfter.getLink(IBaseBundle.LINK_NEXT).getUrl();
assertTrue(nextLink.contains("lastUpdated"));
Bundle nextResults = fhirClient.search().byUrl(nextLink).returnBundle(Bundle.class).execute();
assertEquals(expectedCount, nextResults.getEntry().size(), "Expected number resources return to be equal to count");
}
use of org.hl7.fhir.r4b.model.Range in project beneficiary-fhir-data by CMSgov.
the class R4ExplanationOfBenefitResourceProviderIT method searchEobWithLastUpdatedAndPagination.
/**
* Verifies that {@link
* gov.cms.bfd.server.war.r4.providers.ExplanationOfBenefitResourceProvider#findByPatient} works
* as with a lastUpdated parameter after yesterday.
*
* @throws FHIRException (indicates test failure)
*/
@Test
public void searchEobWithLastUpdatedAndPagination() throws FHIRException {
Beneficiary beneficiary = loadSampleA();
IGenericClient fhirClient = ServerTestUtils.get().createFhirClientV2();
// Search with lastUpdated range between yesterday and now
int expectedCount = 3;
Date yesterday = Date.from(Instant.now().minus(1, ChronoUnit.DAYS));
Date now = new Date();
DateRangeParam afterYesterday = new DateRangeParam(yesterday, now);
Bundle searchResultsAfter = fhirClient.search().forResource(ExplanationOfBenefit.class).where(ExplanationOfBenefit.PATIENT.hasId(TransformerUtilsV2.buildPatientId(beneficiary))).lastUpdated(afterYesterday).count(expectedCount).returnBundle(Bundle.class).execute();
assertEquals(expectedCount, searchResultsAfter.getEntry().size(), "Expected number resources return to be equal to count");
// Check self url
String selfLink = searchResultsAfter.getLink(IBaseBundle.LINK_SELF).getUrl();
assertTrue(selfLink.contains("lastUpdated"));
// Check next bundle
String nextLink = searchResultsAfter.getLink(IBaseBundle.LINK_NEXT).getUrl();
assertTrue(nextLink.contains("lastUpdated"));
Bundle nextResults = fhirClient.search().byUrl(nextLink).returnBundle(Bundle.class).execute();
assertEquals(expectedCount, nextResults.getEntry().size(), "Expected number resources return to be equal to count");
}
use of org.hl7.fhir.r4b.model.Range in project hl7v2-fhir-converter by LinuxForHealth.
the class Hl7MedicationRequestFHIRConversionTest method dosageInstructionTestDoseRangeRXE.
@Test
void dosageInstructionTestDoseRangeRXE() {
// Test dosageInstruction.DoseRange using RXE segment WITH a range
String hl7message = "MSH|^~\\&||||||S1|RDE^O11||T|2.6|||||||||\n" + "PID|||1234^^^^MR||DOE^JANE^|||F||||||||||||||||||||||\n" + "ORC|NW|||||E|||||||||||||||||||||||I\n" + // RXE.6 through RXE.44 not used.
"RXE||DUONEB3INH^3 ML PLAS CONT : IPRATROPIUM-ALBUTEROL 0.5-2.5 (3) MG/3ML IN SOLN^ADS|3|6|mL||||||||||||||||||||||||||||||||||\n";
List<BundleEntryComponent> e = ResourceUtils.createFHIRBundleFromHL7MessageReturnEntryList(ftv, hl7message);
List<Resource> medicationRequestList = ResourceUtils.getResourceList(e, ResourceType.MedicationRequest);
// Confirm that one medicationRequest was created.
assertThat(medicationRequestList).hasSize(1);
MedicationRequest medicationRequest = ResourceUtils.getResourceMedicationRequest(medicationRequestList.get(0), ResourceUtils.context);
Range doseRange = medicationRequest.getDosageInstructionFirstRep().getDoseAndRateFirstRep().getDoseRange();
// doseRange.low(RXE.3)
// RXE.3
assertThat(doseRange.getLow().getValue()).hasToString("3.0");
// RXE.5
assertThat(doseRange.getLow().getUnit()).isEqualTo("mL");
// Defaulted
assertThat(doseRange.getLow().getSystem()).isEqualTo("http://unitsofmeasure.org");
// doseRange.high(RXE.4)
assertThat(doseRange.getHigh().getValue()).hasToString("6.0");
// RXE.5
assertThat(doseRange.getHigh().getUnit()).isEqualTo("mL");
assertThat(doseRange.getHigh().getSystem()).isEqualTo("http://unitsofmeasure.org");
// Verify no extraneous resources
// Expect MedicationRequest, Patient
assertThat(e).hasSize(2);
}
Aggregations