Skip to content
This repository has been archived by the owner on Mar 2, 2022. It is now read-only.

Commit

Permalink
Spring updates
Browse files Browse the repository at this point in the history
  • Loading branch information
pmanko committed Mar 1, 2022
1 parent b489f86 commit 2f7c97e
Show file tree
Hide file tree
Showing 3 changed files with 355 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package org.openmrs.module.labonfhir.api.fhir;

import static org.hibernate.criterion.Restrictions.and;
import static org.hibernate.criterion.Restrictions.or;

import java.util.Optional;
import java.util.stream.Stream;

import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.TokenAndListParam;
import lombok.AccessLevel;
import lombok.Setter;
import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.openmrs.Obs;
import org.openmrs.TestOrder;
import org.openmrs.module.fhir2.FhirConstants;
import org.openmrs.module.fhir2.api.dao.FhirServiceRequestDao;
import org.openmrs.module.fhir2.api.dao.impl.BaseFhirDao;
import org.openmrs.module.fhir2.api.search.param.SearchParameterMap;
import org.openmrs.module.labonfhir.LabOnFhirConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

@Primary
@Component
@Setter(AccessLevel.PACKAGE)
public class ServiceRequestDaoImpl extends BaseFhirDao<Obs> implements FhirServiceRequestDao<Obs> {

@Autowired
private LabOnFhirConfig config;

@Override
protected void setupSearchParams(Criteria criteria, SearchParameterMap theParams) {
theParams.getParameters().forEach(entry -> {
switch (entry.getKey()) {
case FhirConstants.ENCOUNTER_REFERENCE_SEARCH_HANDLER:
entry.getValue().forEach(param -> handleEncounterReference("e", (ReferenceAndListParam) param.getParam())
.ifPresent(c -> criteria.createAlias("encounter", "e").add(c)));
break;
case FhirConstants.PATIENT_REFERENCE_SEARCH_HANDLER:
entry.getValue().forEach(patientReference -> handlePatientReference(criteria,
(ReferenceAndListParam) patientReference.getParam(), "patient"));
break;
case FhirConstants.CODED_SEARCH_HANDLER:
entry.getValue().forEach(code -> handleCodedConcept(criteria, (TokenAndListParam) code.getParam()));
break;
case FhirConstants.PARTICIPANT_REFERENCE_SEARCH_HANDLER:
entry.getValue().forEach(participantReference -> handleProviderReference(criteria,
(ReferenceAndListParam) participantReference.getParam()));
break;
case FhirConstants.DATE_RANGE_SEARCH_HANDLER:
entry.getValue().forEach(dateRangeParam -> handleDateRange((DateRangeParam) dateRangeParam.getParam())
.ifPresent(criteria::add));
break;
case FhirConstants.COMMON_SEARCH_HANDLER:
handleCommonSearchParameters(entry.getValue()).ifPresent(criteria::add);
break;
}
});
}

private void handleCodedConcept(Criteria criteria, TokenAndListParam code) {
if (code != null) {
if (lacksAlias(criteria, "c")) {
criteria.createAlias("concept", "c");
}

handleCodeableConcept(criteria, code, "c", "cm", "crt").ifPresent(criteria::add);
}
}

private Optional<Criterion> handleDateRange(DateRangeParam dateRangeParam) {
if (dateRangeParam == null) {
return Optional.empty();
}

return Optional.of(and(toCriteriaArray(Stream.of(
Optional.of(or(toCriteriaArray(Stream.of(handleDate("scheduledDate", dateRangeParam.getLowerBound()),
handleDate("dateActivated", dateRangeParam.getLowerBound()))))),
Optional.of(or(toCriteriaArray(Stream.of(handleDate("dateStopped", dateRangeParam.getUpperBound()),
handleDate("autoExpireDate", dateRangeParam.getUpperBound())))))))));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package org.openmrs.module.labonfhir.api.fhir;


import java.util.HashSet;

import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.TokenAndListParam;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import org.hl7.fhir.r4.model.ServiceRequest;
import org.openmrs.Obs;
import org.openmrs.TestOrder;
import org.openmrs.module.fhir2.FhirConstants;
import org.openmrs.module.fhir2.api.FhirServiceRequestService;
import org.openmrs.module.fhir2.api.dao.FhirServiceRequestDao;
import org.openmrs.module.fhir2.api.impl.BaseFhirService;
import org.openmrs.module.fhir2.api.search.SearchQuery;
import org.openmrs.module.fhir2.api.search.SearchQueryInclude;
import org.openmrs.module.fhir2.api.search.param.SearchParameterMap;
import org.openmrs.module.fhir2.api.translators.ServiceRequestTranslator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Primary
@Component
@Transactional
@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.PACKAGE)
public class ServiceRequestServiceImpl extends BaseFhirService<ServiceRequest, Obs> implements FhirServiceRequestService {

@Autowired
private ServiceRequestTranslator<Obs> translator;

@Autowired
private FhirServiceRequestDao<Obs> dao;

@Autowired
private SearchQueryInclude<ServiceRequest> searchQueryInclude;

@Autowired
private SearchQuery<Obs, ServiceRequest, FhirServiceRequestDao<Obs>, ServiceRequestTranslator<Obs>, SearchQueryInclude<ServiceRequest>> searchQuery;

@Override
public IBundleProvider searchForServiceRequests(ReferenceAndListParam patientReference, TokenAndListParam code,
ReferenceAndListParam encounterReference, ReferenceAndListParam participantReference, DateRangeParam occurrence,
TokenAndListParam uuid, DateRangeParam lastUpdated, HashSet<Include> includes) {

SearchParameterMap theParams = new SearchParameterMap()
.addParameter(FhirConstants.PATIENT_REFERENCE_SEARCH_HANDLER, patientReference)
.addParameter(FhirConstants.CODED_SEARCH_HANDLER, code)
.addParameter(FhirConstants.ENCOUNTER_REFERENCE_SEARCH_HANDLER, encounterReference)
.addParameter(FhirConstants.PARTICIPANT_REFERENCE_SEARCH_HANDLER, participantReference)
.addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER, occurrence)
.addParameter(FhirConstants.COMMON_SEARCH_HANDLER, FhirConstants.ID_PROPERTY, uuid)
.addParameter(FhirConstants.COMMON_SEARCH_HANDLER, FhirConstants.LAST_UPDATED_PROPERTY, lastUpdated)
.addParameter(FhirConstants.INCLUDE_SEARCH_HANDLER, includes);

return searchQuery.getQueryResults(theParams, dao, translator, searchQueryInclude);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
package org.openmrs.module.labonfhir.api.fhir;
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/

import static org.apache.commons.lang3.Validate.notNull;

import javax.annotation.Nonnull;

import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Set;
import java.util.stream.Collectors;

import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.ReferenceOrListParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
import lombok.AccessLevel;
import lombok.Setter;
import org.hl7.fhir.r4.model.Period;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.ServiceRequest;
import org.hl7.fhir.r4.model.Task;
import org.openmrs.Encounter;
import org.openmrs.EncounterProvider;
import org.openmrs.Obs;
import org.openmrs.Order;
import org.openmrs.Patient;
import org.openmrs.Provider;
import org.openmrs.TestOrder;
import org.openmrs.module.fhir2.api.FhirTaskService;
import org.openmrs.module.fhir2.api.translators.ConceptTranslator;
import org.openmrs.module.fhir2.api.translators.EncounterReferenceTranslator;
import org.openmrs.module.fhir2.api.translators.OrderIdentifierTranslator;
import org.openmrs.module.fhir2.api.translators.PatientReferenceTranslator;
import org.openmrs.module.fhir2.api.translators.PractitionerReferenceTranslator;
import org.openmrs.module.fhir2.api.translators.ServiceRequestTranslator;
import org.openmrs.module.fhir2.api.translators.impl.BaseReferenceHandlingTranslator;
import org.openmrs.module.labonfhir.LabOnFhirConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

@Primary
@Component
@Setter(AccessLevel.PACKAGE)
public class ServiceRequestTranslatorImpl extends BaseReferenceHandlingTranslator implements ServiceRequestTranslator<Obs> {

private static final int START_INDEX = 0;

private static final int END_INDEX = 10;

@Autowired
private LabOnFhirConfig config;

@Autowired
private FhirTaskService taskService;

@Autowired
private ConceptTranslator conceptTranslator;

@Autowired
private PatientReferenceTranslator patientReferenceTranslator;

@Autowired
private EncounterReferenceTranslator<Encounter> encounterReferenceTranslator;

@Autowired
private PractitionerReferenceTranslator<Provider> providerReferenceTranslator;

@Autowired
private OrderIdentifierTranslator orderIdentifierTranslator;

@Override
public ServiceRequest toFhirResource(@Nonnull Obs order) {
notNull(order, "The Obs object should not be null");

if (!order.getConcept().getUuid().equals(config.getTestOrderConceptUuid())) {
return null;
}

ServiceRequest serviceRequest = new ServiceRequest();

serviceRequest.setId(order.getUuid());

serviceRequest.setStatus(determineServiceRequestStatus(order));

serviceRequest.setCode(conceptTranslator.toFhirResource(order.getValueCoded()));

serviceRequest.setIntent(ServiceRequest.ServiceRequestIntent.ORDER);

serviceRequest.setSubject(patientReferenceTranslator.toFhirResource((Patient) order.getPerson()));

serviceRequest.setEncounter(encounterReferenceTranslator.toFhirResource(order.getEncounter()));

serviceRequest.setRequester(providerReferenceTranslator.toFhirResource(determineRequester(order)));

serviceRequest.setPerformer(Collections.singletonList(determineServiceRequestPerformer(order.getUuid())));

serviceRequest.getMeta().setLastUpdated(order.getDateChanged());

// TODO: Figure out how Obs structure translates to these fields
/*
serviceRequest
.setOccurrence(new Period().setStart(order.getEffectiveStartDate()).setEnd(order.getEffectiveStopDate()));
if (order.getPreviousOrder() != null
&& (order.getAction() == Order.Action.DISCONTINUE || order.getAction() == Order.Action.REVISE)) {
serviceRequest.setReplaces((Collections.singletonList(createOrderReference(order.getPreviousOrder())
.setIdentifier(orderIdentifierTranslator.toFhirResource(order.getPreviousOrder())))));
} else if (order.getPreviousOrder() != null && order.getAction() == Order.Action.RENEW) {
serviceRequest.setBasedOn(Collections.singletonList(createOrderReference(order.getPreviousOrder())
.setIdentifier(orderIdentifierTranslator.toFhirResource(order.getPreviousOrder()))));
}
*/

return serviceRequest;
}

private Provider determineRequester(Obs obs) {
if (obs.getEncounter() != null) {
Encounter encounter = obs.getEncounter();

Set<EncounterProvider> encounterProviders = encounter.getEncounterProviders();

if (encounterProviders != null && !encounterProviders.isEmpty()) {
try {
return encounterProviders.iterator().next().getProvider();
} catch (Exception ignored) {}
}
}

return null;
}

@Override
public Obs toOpenmrsType(@Nonnull ServiceRequest resource) {
throw new UnsupportedOperationException();
}

private ServiceRequest.ServiceRequestStatus determineServiceRequestStatus(Obs order) {

Date currentDate = new Date();

IBundleProvider results = taskService.searchForTasks(
new ReferenceAndListParam()
.addAnd(new ReferenceOrListParam().add(new ReferenceParam("ServiceRequest", null, order.getUuid()))),
null, null, null, null, null);

Collection<Task> serviceRequestTasks = results.getResources(START_INDEX, END_INDEX).stream().map(p -> (Task) p)
.collect(Collectors.toList());

ServiceRequest.ServiceRequestStatus serviceRequestStatus = ServiceRequest.ServiceRequestStatus.UNKNOWN;

if (serviceRequestTasks.size() != 1) {
return serviceRequestStatus;
}

Task serviceRequestTask = serviceRequestTasks.iterator().next();

if (serviceRequestTask.getStatus() != null) {
switch (serviceRequestTask.getStatus()) {
case ACCEPTED:
case REQUESTED:
serviceRequestStatus = ServiceRequest.ServiceRequestStatus.ACTIVE;
break;
case REJECTED:
serviceRequestStatus = ServiceRequest.ServiceRequestStatus.REVOKED;
break;
case COMPLETED:
serviceRequestStatus = ServiceRequest.ServiceRequestStatus.COMPLETED;
break;
}
}
return serviceRequestStatus;
}

private Reference determineServiceRequestPerformer(String orderUuid) {
IBundleProvider results = taskService.searchForTasks(
new ReferenceAndListParam()
.addAnd(new ReferenceOrListParam().add(new ReferenceParam("ServiceRequest", null, orderUuid))),
null, null, null, null, null);

Collection<Task> serviceRequestTasks = results.getResources(START_INDEX, END_INDEX).stream().map(p -> (Task) p)
.collect(Collectors.toList());

if (serviceRequestTasks.size() != 1) {
return null;
}

return serviceRequestTasks.iterator().next().getOwner();
}
}

0 comments on commit 2f7c97e

Please sign in to comment.