From 238b854ce7b9bccda2005b1814acfaeb4024d765 Mon Sep 17 00:00:00 2001 From: Michael Seaton Date: Tue, 23 Jul 2024 13:49:31 -0400 Subject: [PATCH] EA-190 Improve API for retrieving inpatient visits (#235) --- README.md | 17 +- .../openmrs/module/emrapi/adt/AdtService.java | 8 + .../module/emrapi/adt/AdtServiceImpl.java | 63 ++- .../module/emrapi/adt/InpatientAdmission.java | 105 +++++ .../adt/InpatientAdmissionSearchCriteria.java | 41 ++ .../resources/hql/inpatient_admissions.hql | 17 + ...ispositions.hql => inpatient_requests.hql} | 0 .../module/emrapi/adt/AdtServiceImplTest.java | 431 ++++++++++++------ .../emrapi/adt/InpatientAdmissionTest.java | 130 ++++++ api/src/test/resources/baseTestDataset.xml | 9 + .../InpatientAdmissionConverter.java | 44 ++ .../InpatientAdmissionController.java | 47 ++ .../controller/InpatientVisitsController.java | 1 + 13 files changed, 754 insertions(+), 159 deletions(-) create mode 100644 api/src/main/java/org/openmrs/module/emrapi/adt/InpatientAdmission.java create mode 100644 api/src/main/java/org/openmrs/module/emrapi/adt/InpatientAdmissionSearchCriteria.java create mode 100644 api/src/main/resources/hql/inpatient_admissions.hql rename api/src/main/resources/hql/{inpatient_request_dispositions.hql => inpatient_requests.hql} (100%) create mode 100644 api/src/test/java/org/openmrs/module/emrapi/adt/InpatientAdmissionTest.java create mode 100644 omod/src/main/java/org/openmrs/module/emrapi/rest/converter/InpatientAdmissionConverter.java create mode 100644 omod/src/main/java/org/openmrs/module/emrapi/web/controller/InpatientAdmissionController.java diff --git a/README.md b/README.md index 7b088079..f64cbc5f 100644 --- a/README.md +++ b/README.md @@ -13,16 +13,16 @@ Higher-level APIs to support building EMR functionality in OpenMRS, to supplemen ## Required modules -* reporting (+ serialization.xstream, htmlwidgets, calculation) -* providermanagement -* metadatamapping * event +* metadatamapping * webservices.rest ## Aware of modules * fhir2 * metadatasharing +* providermanagement +* reporting # Configuration @@ -38,6 +38,9 @@ Higher-level APIs to support building EMR functionality in OpenMRS, to supplemen * Sets up the patient viewed event listener subscription * Ensures the person image folder exists +# REST API +See https://github.com/openmrs/openmrs-contrib-rest-api-docs + # API ## account @@ -58,10 +61,6 @@ Higher-level APIs to support building EMR functionality in OpenMRS, to supplemen * Provides implementations for merging patients and merging visits * Provides APIs for creating checkin encounters, adt encounters, and identify and get inpatient visits -* (reporting module) definitions and evaluators for getting: - * AwaitingAdmissionVisitQuery - any Visits that are in the state of "awaiting admission" - * MostRecentAdmissionRequestVisitDataDefinition - data from a Visit relevant for "admission request" - ## concept * Provides additional service methods for getting and searching for concepts @@ -141,7 +140,3 @@ Higher-level APIs to support building EMR functionality in OpenMRS, to supplemen * Service and parameter objects to find visits and return associated EncounterTransactions in that visit * Service methods to get diagnoses obs and patients with particular diagnoses * VisitDomainWrapper - convenience wrapper to get info around active / open status, encounters contained, diagnoses, dispositions, ADT status - -# condition-list - -This provides an implementation of condition list functionality, but condition was added to core in 2.2, so this is likely no longer needed diff --git a/api/src/main/java/org/openmrs/module/emrapi/adt/AdtService.java b/api/src/main/java/org/openmrs/module/emrapi/adt/AdtService.java index 996743ca..92babead 100644 --- a/api/src/main/java/org/openmrs/module/emrapi/adt/AdtService.java +++ b/api/src/main/java/org/openmrs/module/emrapi/adt/AdtService.java @@ -288,6 +288,7 @@ Encounter checkInPatient(Patient patient, Location where, Provider checkInClerk, * @param visitLocation * @return */ + @Deprecated List getInpatientVisits(Location visitLocation, Location ward); /** @@ -353,4 +354,11 @@ VisitDomainWrapper createRetrospectiveVisit(Patient patient, Location location, * @return List of the matching InpatientRequests that match the criteria */ List getInpatientRequests(InpatientRequestSearchCriteria criteria); + + /** + * Returns all List of InpatientAdmission that match the given search criteria + * @param criteria - represents the criteria by which inpatient admissions are searched and returned + * @return List of the matching InpatientAdmissions that match the criteria + */ + List getInpatientAdmissions(InpatientAdmissionSearchCriteria criteria); } diff --git a/api/src/main/java/org/openmrs/module/emrapi/adt/AdtServiceImpl.java b/api/src/main/java/org/openmrs/module/emrapi/adt/AdtServiceImpl.java index 16853108..dc269b3a 100644 --- a/api/src/main/java/org/openmrs/module/emrapi/adt/AdtServiceImpl.java +++ b/api/src/main/java/org/openmrs/module/emrapi/adt/AdtServiceImpl.java @@ -68,6 +68,7 @@ import java.util.Date; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -988,7 +989,7 @@ public List getInpatientRequests(InpatientRequestSearchCriteri parameters.put("visitIds", criteria.getVisitIds()); parameters.put("limitByVisit", criteria.getVisitIds() != null); - List reqs = emrApiDAO.executeHqlFromResource("hql/inpatient_request_dispositions.hql", parameters, List.class); + List reqs = emrApiDAO.executeHqlFromResource("hql/inpatient_requests.hql", parameters, List.class); List ret = new ArrayList<>(); for (Object req : reqs) { Object[] o = (Object[]) req; @@ -1010,4 +1011,64 @@ public List getInpatientRequests(InpatientRequestSearchCriteri } return ret; } + + @Override + @Transactional(readOnly = true) + public List getInpatientAdmissions(InpatientAdmissionSearchCriteria criteria) { + + // Determine whether to filter visits at a particular location + Location visitLocation = null ; + if (criteria.getVisitLocation() != null ) { + visitLocation = getLocationThatSupportsVisits(criteria.getVisitLocation()); + } + + EncounterType admissionEncounterType = emrApiProperties.getAdmissionEncounterType(); + EncounterType transferEncounterType = emrApiProperties.getTransferWithinHospitalEncounterType(); + EncounterType dischargeEncounterType = emrApiProperties.getExitFromInpatientEncounterType(); + + Map parameters = new HashMap<>(); + parameters.put("visitLocation", visitLocation); + parameters.put("admissionEncounterType", emrApiProperties.getAdmissionEncounterType()); + parameters.put("transferEncounterType", emrApiProperties.getTransferWithinHospitalEncounterType()); + parameters.put("dischargeEncounterType", emrApiProperties.getExitFromInpatientEncounterType()); + parameters.put("patientIds", criteria.getPatientIds()); + parameters.put("limitByPatient", criteria.getPatientIds() != null); + parameters.put("visitIds", criteria.getVisitIds()); + parameters.put("limitByVisit", criteria.getVisitIds() != null); + + List l = emrApiDAO.executeHqlFromResource("hql/inpatient_admissions.hql", parameters, List.class); + Map m = new LinkedHashMap<>(); + for (Object req : l) { + Object[] o = (Object[]) req; + Visit visit = (Visit)o[0]; + Patient patient = (Patient)o[1]; + Encounter encounter = (Encounter)o[2]; + InpatientAdmission admission = m.get(visit); + if (admission == null) { + admission = new InpatientAdmission(); + admission.setVisit(visit); + admission.setPatient(patient); + m.put(visit, admission); + } + if (encounter.getEncounterType().equals(admissionEncounterType)) { + admission.getAdmissionEncounters().add(encounter); + } + else if (encounter.getEncounterType().equals(transferEncounterType)) { + admission.getTransferEncounters().add(encounter); + } + else if (encounter.getEncounterType().equals(dischargeEncounterType)) { + admission.getDischargeEncounters().add(encounter); + } + } + + List ret = new ArrayList<>(); + for (InpatientAdmission admission : m.values()) { + if (criteria.getCurrentInpatientLocations() == null || criteria.getCurrentInpatientLocations().contains(admission.getCurrentInpatientLocation())) { + if (criteria.isIncludeDischarged() || !admission.isDischarged()) { + ret.add(admission); + } + } + } + return ret; + } } diff --git a/api/src/main/java/org/openmrs/module/emrapi/adt/InpatientAdmission.java b/api/src/main/java/org/openmrs/module/emrapi/adt/InpatientAdmission.java new file mode 100644 index 00000000..30276241 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/emrapi/adt/InpatientAdmission.java @@ -0,0 +1,105 @@ +package org.openmrs.module.emrapi.adt; + +import lombok.Data; +import org.openmrs.Encounter; +import org.openmrs.Location; +import org.openmrs.Patient; +import org.openmrs.Visit; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +/** + * Represents a hospital Admission + */ +@Data +public class InpatientAdmission { + + private Visit visit; + private Patient patient; + private Set admissionEncounters = new TreeSet<>(getEncounterComparator()); + private Set transferEncounters = new TreeSet<>(getEncounterComparator()); + private Set dischargeEncounters = new TreeSet<>(getEncounterComparator()); + + public List getAdmissionAndTransferEncounters() { + List encounters = new ArrayList<>(); + encounters.addAll(admissionEncounters); + encounters.addAll(transferEncounters); + encounters.sort(getEncounterComparator()); + return Collections.unmodifiableList(encounters); + } + + public List getAdtEncounters() { + List encounters = new ArrayList<>(); + encounters.addAll(admissionEncounters); + encounters.addAll(transferEncounters); + encounters.addAll(dischargeEncounters); + encounters.sort(getEncounterComparator()); + return Collections.unmodifiableList(encounters); + } + + public Encounter getFirstAdmissionOrTransferEncounter() { + List encounters = getAdmissionAndTransferEncounters(); + return encounters.isEmpty() ? null : encounters.get(0); + } + + public Encounter getLatestAdmissionOrTransferEncounter() { + List encounters = getAdmissionAndTransferEncounters(); + return encounters.isEmpty() ? null : encounters.get(encounters.size() - 1); + } + + public Encounter getLatestAdtEncounter() { + List encounters = getAdtEncounters(); + return encounters.isEmpty() ? null : encounters.get(encounters.size() - 1); + } + + public Location getCurrentInpatientLocation() { + if (isDischarged()) { + return null; + } + Encounter encounter = getLatestAdmissionOrTransferEncounter(); + return encounter == null ? null : encounter.getLocation(); + } + + public Encounter getEncounterAssigningToCurrentInpatientLocation() { + Location location = getCurrentInpatientLocation(); + if (location == null) { + return null; + } + List encounters = getAdmissionAndTransferEncounters(); + if (encounters.isEmpty()) { + return null; + } + Encounter ret = encounters.get(encounters.size() - 1); + if (!ret.getLocation().equals(location)) { // Sanity check, this should not happen + return null; + } + for (int i=encounters.size()-2; i>=0; i--) { + Encounter e = encounters.get(i); + if (e.getLocation().equals(location)) { + ret = e; + } + else { + return ret; + } + } + return ret; + } + + public boolean isDischarged() { + if (dischargeEncounters.isEmpty()) { + return false; + } + return dischargeEncounters.contains(getLatestAdtEncounter()); + } + + private Comparator getEncounterComparator() { + return Comparator.comparing(Encounter::getEncounterDatetime) + .thenComparing(Encounter::getDateCreated) + .thenComparing(Encounter::getEncounterId); + } +} diff --git a/api/src/main/java/org/openmrs/module/emrapi/adt/InpatientAdmissionSearchCriteria.java b/api/src/main/java/org/openmrs/module/emrapi/adt/InpatientAdmissionSearchCriteria.java new file mode 100644 index 00000000..83d54291 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/emrapi/adt/InpatientAdmissionSearchCriteria.java @@ -0,0 +1,41 @@ +package org.openmrs.module.emrapi.adt; + +import lombok.Data; +import org.openmrs.Location; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents criteria for searching for InpatientAdmissions + */ +@Data +public class InpatientAdmissionSearchCriteria { + + private Location visitLocation; + private List currentInpatientLocations; + private boolean includeDischarged = false; + private List patientIds; + private List visitIds; + + public void addCurrentInpatientLocation(Location location) { + if (currentInpatientLocations == null) { + currentInpatientLocations = new ArrayList<>(); + } + currentInpatientLocations.add(location); + } + + public void addPatientId(Integer patientId) { + if (patientIds == null) { + patientIds = new ArrayList<>(); + } + patientIds.add(patientId); + } + + public void addVisitId(Integer visitId) { + if (visitIds == null) { + visitIds = new ArrayList<>(); + } + visitIds.add(visitId); + } +} diff --git a/api/src/main/resources/hql/inpatient_admissions.hql b/api/src/main/resources/hql/inpatient_admissions.hql new file mode 100644 index 00000000..b094b27e --- /dev/null +++ b/api/src/main/resources/hql/inpatient_admissions.hql @@ -0,0 +1,17 @@ +select + visit, + patient, + encounter +from + Encounter as encounter +inner join encounter.visit as visit +inner join encounter.patient as patient +where encounter.voided = false + and visit.voided = false + and patient.voided = false + and (:visitLocation is null or visit.location = :visitLocation) + and visit.stopDatetime is null + and encounter.encounterType in (:admissionEncounterType, :transferEncounterType, :dischargeEncounterType) + and (:limitByPatient is false or patient.patientId in (:patientIds)) + and (:limitByVisit is false or visit.visitId in (:visitIds)) +order by visit.visitId, encounter.encounterDatetime, encounter.encounterId diff --git a/api/src/main/resources/hql/inpatient_request_dispositions.hql b/api/src/main/resources/hql/inpatient_requests.hql similarity index 100% rename from api/src/main/resources/hql/inpatient_request_dispositions.hql rename to api/src/main/resources/hql/inpatient_requests.hql diff --git a/api/src/test/java/org/openmrs/module/emrapi/adt/AdtServiceImplTest.java b/api/src/test/java/org/openmrs/module/emrapi/adt/AdtServiceImplTest.java index 28179b90..a3b499f0 100644 --- a/api/src/test/java/org/openmrs/module/emrapi/adt/AdtServiceImplTest.java +++ b/api/src/test/java/org/openmrs/module/emrapi/adt/AdtServiceImplTest.java @@ -63,8 +63,9 @@ public class AdtServiceImplTest extends EmrApiContextSensitiveTest { private Concept transferDisposition; private Concept dischargeDisposition; private Date visitDate; - InpatientRequestSearchCriteria criteria; + InpatientRequestSearchCriteria requestCriteria; List requests; + InpatientAdmissionSearchCriteria admissionCriteria; @Before public void setup() throws Exception { @@ -88,7 +89,8 @@ public void setup() throws Exception { patient = testDataManager.randomPatient().birthdate("2010-01-01").save(); visit = testDataManager.visit().patient(patient).visitType(emrApiProperties.getAtFacilityVisitType()).location(visitLocation).started("2020-10-30").save(); visitDate = visit.getStartDatetime(); - criteria = new InpatientRequestSearchCriteria(); + requestCriteria = new InpatientRequestSearchCriteria(); + admissionCriteria = new InpatientAdmissionSearchCriteria(); } private Encounter createEncounter(EncounterType encounterType, Location location, Date date) { @@ -142,11 +144,19 @@ private List assertNumRequests(InpatientRequestSearchCriteria return requests; } + private List assertNumAdmissions(InpatientAdmissionSearchCriteria criteria, int expected) { + List admissions = adtService.getInpatientAdmissions(criteria); + assertThat(admissions.size(), equalTo(expected)); + return admissions; + } + + //*********** INPATIENT REQUEST TESTS ***************** + @Test public void shouldGetInpatientRequest() { - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - requests = adtService.getInpatientRequests(criteria); + requests = adtService.getInpatientRequests(requestCriteria); assertThat(requests.size(), equalTo(1)); assertThat(requests.get(0).getDispositionType(), equalTo(DispositionType.ADMIT)); assertThat(requests.get(0).getDisposition(), equalTo(admitDisposition)); @@ -157,305 +167,432 @@ public void shouldGetInpatientRequest() { @Test public void shouldGetAdmissionRequestForVisitLocation() { - criteria.addDispositionType(DispositionType.ADMIT); - criteria.setVisitLocation(visitLocation); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + requestCriteria.setVisitLocation(visitLocation); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); } @Test public void shouldGetAdmissionRequestForParentVisitLocation() { - criteria.addDispositionType(DispositionType.ADMIT); - criteria.setVisitLocation(admissionLocation); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + requestCriteria.setVisitLocation(admissionLocation); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); } @Test public void shouldNotGetAdmissionRequestForDifferentVisitLocation() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); - criteria.setVisitLocation(otherVisitLocation); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 1); + requestCriteria.setVisitLocation(otherVisitLocation); + assertNumRequests(requestCriteria, 0); } // Filter based on Disposition Type @Test public void shouldGetInpatientRequestsBasedOnDispositionType() { - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); - criteria.setDispositionTypes(Collections.singletonList(DispositionType.ADMIT)); - assertNumRequests(criteria, 1); - criteria.setDispositionTypes(Collections.singletonList(DispositionType.TRANSFER)); - assertNumRequests(criteria, 0); - criteria.setDispositionTypes(Collections.singletonList(DispositionType.DISCHARGE)); - assertNumRequests(criteria, 0); - criteria.setDispositionTypes(Arrays.asList(DispositionType.ADMIT, DispositionType.TRANSFER)); - assertNumRequests(criteria, 1); - criteria.setDispositionTypes(Arrays.asList(DispositionType.ADMIT, DispositionType.DISCHARGE)); - assertNumRequests(criteria, 1); - criteria.setDispositionTypes(Arrays.asList(DispositionType.TRANSFER, DispositionType.DISCHARGE)); - assertNumRequests(criteria, 0); - criteria.setDispositionTypes(null); + assertNumRequests(requestCriteria, 1); + requestCriteria.setDispositionTypes(Collections.singletonList(DispositionType.ADMIT)); + assertNumRequests(requestCriteria, 1); + requestCriteria.setDispositionTypes(Collections.singletonList(DispositionType.TRANSFER)); + assertNumRequests(requestCriteria, 0); + requestCriteria.setDispositionTypes(Collections.singletonList(DispositionType.DISCHARGE)); + assertNumRequests(requestCriteria, 0); + requestCriteria.setDispositionTypes(Arrays.asList(DispositionType.ADMIT, DispositionType.TRANSFER)); + assertNumRequests(requestCriteria, 1); + requestCriteria.setDispositionTypes(Arrays.asList(DispositionType.ADMIT, DispositionType.DISCHARGE)); + assertNumRequests(requestCriteria, 1); + requestCriteria.setDispositionTypes(Arrays.asList(DispositionType.TRANSFER, DispositionType.DISCHARGE)); + assertNumRequests(requestCriteria, 0); + requestCriteria.setDispositionTypes(null); createTransferRequest(DateUtils.addHours(visitDate, 4)); - assertNumRequests(criteria, 1); - criteria.setDispositionTypes(Collections.singletonList(DispositionType.ADMIT)); - assertNumRequests(criteria, 0); - criteria.setDispositionTypes(Collections.singletonList(DispositionType.TRANSFER)); - assertNumRequests(criteria, 1); - criteria.setDispositionTypes(Collections.singletonList(DispositionType.DISCHARGE)); - assertNumRequests(criteria, 0); - criteria.setDispositionTypes(Arrays.asList(DispositionType.ADMIT, DispositionType.TRANSFER)); - assertNumRequests(criteria, 1); - criteria.setDispositionTypes(Arrays.asList(DispositionType.ADMIT, DispositionType.DISCHARGE)); - assertNumRequests(criteria, 0); - criteria.setDispositionTypes(Arrays.asList(DispositionType.TRANSFER, DispositionType.DISCHARGE)); - assertNumRequests(criteria, 1); - criteria.setDispositionTypes(null); + assertNumRequests(requestCriteria, 1); + requestCriteria.setDispositionTypes(Collections.singletonList(DispositionType.ADMIT)); + assertNumRequests(requestCriteria, 0); + requestCriteria.setDispositionTypes(Collections.singletonList(DispositionType.TRANSFER)); + assertNumRequests(requestCriteria, 1); + requestCriteria.setDispositionTypes(Collections.singletonList(DispositionType.DISCHARGE)); + assertNumRequests(requestCriteria, 0); + requestCriteria.setDispositionTypes(Arrays.asList(DispositionType.ADMIT, DispositionType.TRANSFER)); + assertNumRequests(requestCriteria, 1); + requestCriteria.setDispositionTypes(Arrays.asList(DispositionType.ADMIT, DispositionType.DISCHARGE)); + assertNumRequests(requestCriteria, 0); + requestCriteria.setDispositionTypes(Arrays.asList(DispositionType.TRANSFER, DispositionType.DISCHARGE)); + assertNumRequests(requestCriteria, 1); + requestCriteria.setDispositionTypes(null); createDischargeRequest(DateUtils.addHours(visitDate, 6), preAdmissionLocation); - assertNumRequests(criteria, 1); - criteria.setDispositionTypes(Collections.singletonList(DispositionType.ADMIT)); - assertNumRequests(criteria, 0); - criteria.setDispositionTypes(Collections.singletonList(DispositionType.TRANSFER)); - assertNumRequests(criteria, 0); - criteria.setDispositionTypes(Collections.singletonList(DispositionType.DISCHARGE)); - assertNumRequests(criteria, 1); - criteria.setDispositionTypes(Arrays.asList(DispositionType.ADMIT, DispositionType.TRANSFER)); - assertNumRequests(criteria, 0); - criteria.setDispositionTypes(Arrays.asList(DispositionType.ADMIT, DispositionType.DISCHARGE)); - assertNumRequests(criteria, 1); - criteria.setDispositionTypes(Arrays.asList(DispositionType.TRANSFER, DispositionType.DISCHARGE)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); + requestCriteria.setDispositionTypes(Collections.singletonList(DispositionType.ADMIT)); + assertNumRequests(requestCriteria, 0); + requestCriteria.setDispositionTypes(Collections.singletonList(DispositionType.TRANSFER)); + assertNumRequests(requestCriteria, 0); + requestCriteria.setDispositionTypes(Collections.singletonList(DispositionType.DISCHARGE)); + assertNumRequests(requestCriteria, 1); + requestCriteria.setDispositionTypes(Arrays.asList(DispositionType.ADMIT, DispositionType.TRANSFER)); + assertNumRequests(requestCriteria, 0); + requestCriteria.setDispositionTypes(Arrays.asList(DispositionType.ADMIT, DispositionType.DISCHARGE)); + assertNumRequests(requestCriteria, 1); + requestCriteria.setDispositionTypes(Arrays.asList(DispositionType.TRANSFER, DispositionType.DISCHARGE)); + assertNumRequests(requestCriteria, 1); } // Filter based on disposition location @Test public void shouldGetInpatientRequestsBasedOnDispositionLocation() { - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); - criteria.addDispositionLocation(preAdmissionLocation); - assertNumRequests(criteria, 0); - criteria.addDispositionLocation(transferLocation); - assertNumRequests(criteria, 0); - criteria.addDispositionLocation(admissionLocation); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); + requestCriteria.addDispositionLocation(preAdmissionLocation); + assertNumRequests(requestCriteria, 0); + requestCriteria.addDispositionLocation(transferLocation); + assertNumRequests(requestCriteria, 0); + requestCriteria.addDispositionLocation(admissionLocation); + assertNumRequests(requestCriteria, 1); } // Filter based on patient ids @Test public void shouldGetInpatientRequestsBasedOnPatient() { - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); - criteria.addPatientId(patient.getPatientId() + 1); - assertNumRequests(criteria, 0); - criteria.addPatientId(patient.getPatientId() + 2); - assertNumRequests(criteria, 0); - criteria.addPatientId(patient.getPatientId()); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); + requestCriteria.addPatientId(patient.getPatientId() + 1); + assertNumRequests(requestCriteria, 0); + requestCriteria.addPatientId(patient.getPatientId() + 2); + assertNumRequests(requestCriteria, 0); + requestCriteria.addPatientId(patient.getPatientId()); + assertNumRequests(requestCriteria, 1); } // Filter based on visit ids @Test public void shouldGetInpatientRequestsBasedOnVisit() { - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); - criteria.addVisitId(visit.getVisitId() + 1); - assertNumRequests(criteria, 0); - criteria.addVisitId(visit.getVisitId() + 2); - assertNumRequests(criteria, 0); - criteria.addVisitId(visit.getVisitId()); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); + requestCriteria.addVisitId(visit.getVisitId() + 1); + assertNumRequests(requestCriteria, 0); + requestCriteria.addVisitId(visit.getVisitId() + 2); + assertNumRequests(requestCriteria, 0); + requestCriteria.addVisitId(visit.getVisitId()); + assertNumRequests(requestCriteria, 1); } // Filter based on timeline of disposition obs and encounters within visit @Test public void shouldNotGetAdmissionRequestIfPatientHasBeenAdmitted() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); createAdmissionEncounter(DateUtils.addHours(visitDate, 3)); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); } @Test public void shouldGetAdmissionRequestIfAdmissionEncounterIsVoided() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); Encounter e = createAdmissionEncounter(DateUtils.addHours(visitDate, 3)); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); testDataManager.getEncounterService().voidEncounter(e, "Unknown"); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); } @Test public void shouldOnlyReturnLatestDispositionRequestWithinAGivenVisit() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); createAdmissionRequest(DateUtils.addHours(visitDate, 3)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); } @Test public void shouldOnlyReturnAdmitIfItIsLaterThanDischarge() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); createDischargeRequest(DateUtils.addHours(visitDate, 3), preAdmissionLocation); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 4)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); } @Test public void shouldGetAdmissionRequestIfAfterAdmissionEncounter() { - criteria.addDispositionType(DispositionType.ADMIT); + requestCriteria.addDispositionType(DispositionType.ADMIT); createAdmissionEncounter(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 4)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); } // Filter based on timeline of disposition obs and denial obs within visit @Test public void shouldNotGetAdmissionRequestIfPatientHasBeenDenied() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); createAdmissionDeniedEncounter(DateUtils.addHours(visitDate, 3)); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); } @Test public void shouldGetAdmissionRequestIfPatientHasAnAdmissionRequestAfterADenial() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); createAdmissionDeniedEncounter(DateUtils.addHours(visitDate, 3)); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 4)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); } @Test public void shouldGetAdmissionRequestIfPatientHasAnAdmissionDecisionThatIsNotDeny() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); Encounter e = createAdmissionDeniedEncounter(DateUtils.addHours(visitDate, 3)); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); for (Obs o : e.getAllObs()) { if (o.getConcept().equals(emrApiProperties.getAdmissionDecisionConcept())) { o.setValueCoded(emrApiProperties.getPatientDiedConcept()); testDataManager.getObsService().saveObs(o, "Unknown"); } } - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); } @Test public void shouldGetAdmissionRequestWithDispositionOfAdmitIfPrecededByAdmissionDenialObs() { - criteria.addDispositionType(DispositionType.ADMIT); + requestCriteria.addDispositionType(DispositionType.ADMIT); createAdmissionDeniedEncounter(DateUtils.addHours(visitDate, 1)); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); } @Test public void shouldGetAdmissionRequestWithDispositionOfAdmitIfFollowedByAdmissionDenialObsThatIsVoided() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); Encounter e = createAdmissionDeniedEncounter(DateUtils.addHours(visitDate, 3)); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); for (Obs o : e.getAllObs()) { if (o.getConcept().equals(emrApiProperties.getAdmissionDecisionConcept())) { testDataManager.getObsService().voidObs(o, "Unknown"); } } - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); } // Filter out patients who have died or whose visit is ended @Test public void shouldNotGetAdmissionRequestIfPatientHasDied() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); patient.setDead(true); patient.setCauseOfDeathNonCoded("Unknown"); testDataManager.getPatientService().savePatient(patient); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); } @Test - public void shouldGetInpatientRequestsForEndedVisits() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + public void shouldNotGetInpatientRequestsForEndedVisits() { + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); testDataManager.getVisitService().endVisit(visit, DateUtils.addHours(visitDate, 4)); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); } // Filter out voided data @Test public void shouldNotGetAdmissionRequestIfPatientIsVoided() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - assertNumRequests(criteria, 1); + assertNumRequests(requestCriteria, 1); testDataManager.getPatientService().voidPatient(patient, "Unknown"); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); } @Test public void shouldNotGetAdmissionRequestIfEncounterIsVoided() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); Obs o = createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - requests = assertNumRequests(criteria, 1); + requests = assertNumRequests(requestCriteria, 1); testDataManager.getEncounterService().voidEncounter(o.getEncounter(), "Unknown"); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); } @Test public void shouldNotGetAdmissionRequestIfObsIsVoided() { - criteria.addDispositionType(DispositionType.ADMIT); - assertNumRequests(criteria, 0); + requestCriteria.addDispositionType(DispositionType.ADMIT); + assertNumRequests(requestCriteria, 0); Obs o = createAdmissionRequest(DateUtils.addHours(visitDate, 2)); - requests = assertNumRequests(criteria, 1); + requests = assertNumRequests(requestCriteria, 1); testDataManager.getObsService().voidObs(o, "Unknown"); - assertNumRequests(criteria, 0); + assertNumRequests(requestCriteria, 0); + } + + //*********** INPATIENT ADMISSION TESTS ***************** + + @Test + public void shouldNotGetAdmissionIfNoAdtEncounters() { + assertNumAdmissions(admissionCriteria, 0); + createAdmissionRequest(DateUtils.addHours(visitDate, 2)); + assertNumAdmissions(admissionCriteria, 0); + } + + @Test + public void shouldGetAdmissionIfAdmissionEncounters() { + assertNumAdmissions(admissionCriteria, 0); + Encounter e = createAdmissionEncounter(DateUtils.addHours(visitDate, 2)); + List admissions = assertNumAdmissions(admissionCriteria, 1); + InpatientAdmission admission = admissions.get(0); + assertThat(admission.getAdmissionEncounters().size(), equalTo(1)); + assertThat(admission.getTransferEncounters().size(), equalTo(0)); + assertThat(admission.getDischargeEncounters().size(), equalTo(0)); + assertThat(admission.getAdmissionEncounters().iterator().next(), equalTo(e)); + } + + @Test + public void shouldGetAdmissionIfTransferEncounters() { + assertNumAdmissions(admissionCriteria, 0); + Encounter e = createTransferEncounter(DateUtils.addHours(visitDate, 2)); + List admissions = assertNumAdmissions(admissionCriteria, 1); + InpatientAdmission admission = admissions.get(0); + assertThat(admission.getAdmissionEncounters().size(), equalTo(0)); + assertThat(admission.getTransferEncounters().size(), equalTo(1)); + assertThat(admission.getDischargeEncounters().size(), equalTo(0)); + assertThat(admission.getTransferEncounters().iterator().next(), equalTo(e)); + } + + @Test + public void shouldGetAdmissionIfDischargeEncounters() { + admissionCriteria.setIncludeDischarged(true); + assertNumAdmissions(admissionCriteria, 0); + Encounter e = createDischarge(DateUtils.addHours(visitDate, 2), visitLocation); + List admissions = assertNumAdmissions(admissionCriteria, 1); + InpatientAdmission admission = admissions.get(0); + assertThat(admission.getAdmissionEncounters().size(), equalTo(0)); + assertThat(admission.getTransferEncounters().size(), equalTo(0)); + assertThat(admission.getDischargeEncounters().size(), equalTo(1)); + assertThat(admission.getDischargeEncounters().iterator().next(), equalTo(e)); } + + @Test + public void shouldGetAdmissionForVisitLocation() { + admissionCriteria.setVisitLocation(visitLocation); + assertNumAdmissions(admissionCriteria, 0); + createAdmissionEncounter(DateUtils.addHours(visitDate, 2)); + admissionCriteria.setVisitLocation(visitLocation); + assertNumAdmissions(admissionCriteria, 1); + } + + @Test + public void shouldGetAdmissionForParentVisitLocation() { + admissionCriteria.setVisitLocation(visitLocation); + assertNumAdmissions(admissionCriteria, 0); + createAdmissionEncounter(DateUtils.addHours(visitDate, 2)); + admissionCriteria.setVisitLocation(admissionLocation); + assertNumAdmissions(admissionCriteria, 1); + } + + @Test + public void shouldNotGetAdmissionForDifferentVisitLocation() { + admissionCriteria.setVisitLocation(visitLocation); + assertNumAdmissions(admissionCriteria, 0); + createAdmissionEncounter(DateUtils.addHours(visitDate, 2)); + admissionCriteria.setVisitLocation(otherVisitLocation); + assertNumAdmissions(admissionCriteria, 0); + } + + @Test + public void shouldGetAdmissionForInpatientLocation() { + admissionCriteria.addCurrentInpatientLocation(admissionLocation); + assertNumAdmissions(admissionCriteria, 0); + createAdmissionEncounter(DateUtils.addHours(visitDate, 2)); + assertNumAdmissions(admissionCriteria, 1); + createTransferEncounter(DateUtils.addHours(visitDate, 4)); + assertNumAdmissions(admissionCriteria, 0); + admissionCriteria.addCurrentInpatientLocation(transferLocation); + assertNumAdmissions(admissionCriteria, 1); + } + + @Test + public void shouldGetAdmissionForPatient() { + admissionCriteria.addPatientId(patient.getPatientId()); + assertNumAdmissions(admissionCriteria, 0); + createAdmissionEncounter(DateUtils.addHours(visitDate, 2)); + assertNumAdmissions(admissionCriteria, 1); + admissionCriteria.setPatientIds(Collections.singletonList(patient.getPatientId() + 1)); + assertNumAdmissions(admissionCriteria, 0); + } + + @Test + public void shouldGetAdmissionForVisit() { + admissionCriteria.addVisitId(visit.getVisitId()); + assertNumAdmissions(admissionCriteria, 0); + createAdmissionEncounter(DateUtils.addHours(visitDate, 2)); + assertNumAdmissions(admissionCriteria, 1); + admissionCriteria.setVisitIds(Collections.singletonList(visit.getVisitId() + 1)); + assertNumAdmissions(admissionCriteria, 0); + } + + @Test + public void shouldGetAdmissionThatHasBeenDischarged() { + admissionCriteria.addVisitId(visit.getVisitId()); + assertNumAdmissions(admissionCriteria, 0); + createAdmissionEncounter(DateUtils.addHours(visitDate, 2)); + assertNumAdmissions(admissionCriteria, 1); + createDischarge(DateUtils.addHours(visitDate, 4), admissionLocation); + assertNumAdmissions(admissionCriteria, 0); + admissionCriteria.setIncludeDischarged(true); + assertNumAdmissions(admissionCriteria, 1); + } + + @Test + public void shouldNotGetAdmissionsForEndedVisits() { + assertNumAdmissions(admissionCriteria, 0); + createAdmissionEncounter(DateUtils.addHours(visitDate, 2)); + assertNumAdmissions(admissionCriteria, 1); + testDataManager.getVisitService().endVisit(visit, DateUtils.addHours(visitDate, 4)); + assertNumAdmissions(admissionCriteria, 0); + } + } diff --git a/api/src/test/java/org/openmrs/module/emrapi/adt/InpatientAdmissionTest.java b/api/src/test/java/org/openmrs/module/emrapi/adt/InpatientAdmissionTest.java new file mode 100644 index 00000000..3944151a --- /dev/null +++ b/api/src/test/java/org/openmrs/module/emrapi/adt/InpatientAdmissionTest.java @@ -0,0 +1,130 @@ +/* + * The contents of this file are subject to the OpenMRS Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://license.openmrs.org + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * + * Copyright (C) OpenMRS, LLC. All Rights Reserved. + */ + +package org.openmrs.module.emrapi.adt; + +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Encounter; +import org.openmrs.Location; +import org.openmrs.contrib.testdata.TestDataManager; + +import java.util.List; + +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + +public class InpatientAdmissionTest { + + TestDataManager tdm; + InpatientAdmission admission; + Location location1; + Location location2; + Encounter encounter1; + Encounter encounter2; + Encounter encounter3; + Encounter encounter4; + Encounter encounter5; + Encounter encounter6; + + @Before + public void setup() throws Exception { + tdm = new TestDataManager(); + admission = new InpatientAdmission(); + location1 = new Location(); + location2 = new Location(); + encounter1 = createEncounter("2020-08-15 13:00:00", "2020-08-15 13:00:00", 10); + encounter2 = createEncounter("2020-08-15 14:00:00", "2020-08-15 14:00:00", 20); + encounter3 = createEncounter("2020-08-15 15:00:00", "2020-08-15 15:00:00", 30); + encounter4 = createEncounter("2020-08-15 16:00:00", "2020-08-15 16:00:00", 40); + encounter5 = createEncounter("2020-08-15 16:00:00", "2020-08-15 15:00:00", 50); + encounter6 = createEncounter("2020-08-15 16:00:00", "2020-08-15 15:00:00", 35); + admission.getAdmissionEncounters().add(encounter1); + admission.getAdmissionEncounters().add(encounter2); + admission.getTransferEncounters().add(encounter3); + admission.getTransferEncounters().add(encounter4); + admission.getTransferEncounters().add(encounter5); + admission.getDischargeEncounters().add(encounter6); + } + + @Test + public void shouldGetAdtEncountersInOrder() { + List encounters = admission.getAdtEncounters(); + assertThat(encounters.size(), equalTo(6)); + assertThat(encounters, contains(encounter1, encounter2, encounter3, encounter6, encounter5, encounter4)); + } + + @Test + public void shouldGetAdmissionAndTransferEncountersInOrder() { + List encounters = admission.getAdmissionAndTransferEncounters(); + assertThat(encounters.size(), equalTo(5)); + assertThat(encounters, contains(encounter1, encounter2, encounter3, encounter5, encounter4)); + } + + @Test + public void shouldGetFirstAdmissionOrTransferEncounter() { + assertThat(admission.getFirstAdmissionOrTransferEncounter(), equalTo(encounter1)); + } + + @Test + public void shouldGetLatestAdmissionOrTransferEncounter() { + assertThat(admission.getLatestAdmissionOrTransferEncounter(), equalTo(encounter4)); + } + + @Test + public void shouldGetLatestAdtEncounter() { + assertThat(admission.getLatestAdtEncounter(), equalTo(encounter4)); + } + + @Test + public void shouldGetCurrentInpatientLocation() { + assertThat(admission.getCurrentInpatientLocation(), nullValue()); + encounter6.setLocation(location1); + assertThat(admission.getCurrentInpatientLocation(), nullValue()); + encounter4.setLocation(location1); + assertThat(admission.getCurrentInpatientLocation(), equalTo(location1)); + } + + @Test + public void shouldGetEncounterAssigningToCurrentInpatientLocation() { + assertThat(admission.getEncounterAssigningToCurrentInpatientLocation(), nullValue()); + encounter1.setLocation(location1); + encounter2.setLocation(location2); + encounter3.setLocation(location1); + encounter6.setLocation(location1); // This is a discharge encounter, so not applicable + encounter5.setLocation(location1); + encounter4.setLocation(location1); + assertThat(admission.getEncounterAssigningToCurrentInpatientLocation(), equalTo(encounter3)); + encounter3.setLocation(location2); + assertThat(admission.getEncounterAssigningToCurrentInpatientLocation(), equalTo(encounter5)); + encounter5.setLocation(location2); + assertThat(admission.getEncounterAssigningToCurrentInpatientLocation(), equalTo(encounter4)); + } + + @Test + public void shouldGetIsDischarged() { + assertThat(admission.isDischarged(), equalTo(false)); + admission.getTransferEncounters().remove(encounter4); + admission.getTransferEncounters().remove(encounter5); + assertThat(admission.isDischarged(), equalTo(true)); + } + + private Encounter createEncounter(String encounterDate, String dateCreated, Integer encounterId) { + Encounter encounter = tdm.encounter().dateCreated(dateCreated).encounterDatetime(encounterDate).get(); + encounter.setEncounterId(encounterId); + return encounter; + } +} diff --git a/api/src/test/resources/baseTestDataset.xml b/api/src/test/resources/baseTestDataset.xml index 520368a8..5178d0e7 100644 --- a/api/src/test/resources/baseTestDataset.xml +++ b/api/src/test/resources/baseTestDataset.xml @@ -90,6 +90,15 @@ + + + + diff --git a/omod/src/main/java/org/openmrs/module/emrapi/rest/converter/InpatientAdmissionConverter.java b/omod/src/main/java/org/openmrs/module/emrapi/rest/converter/InpatientAdmissionConverter.java new file mode 100644 index 00000000..ef0db2af --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/emrapi/rest/converter/InpatientAdmissionConverter.java @@ -0,0 +1,44 @@ +package org.openmrs.module.emrapi.rest.converter; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openmrs.annotation.Handler; +import org.openmrs.module.emrapi.adt.InpatientAdmission; +import org.openmrs.module.webservices.rest.web.representation.CustomRepresentation; +import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; +import org.openmrs.module.webservices.rest.web.representation.FullRepresentation; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; + +@Handler(supports = InpatientAdmission.class, order = 0) +public class InpatientAdmissionConverter extends SimpleBeanConverter { + + private final Log log = LogFactory.getLog(getClass()); + + @Override + public DelegatingResourceDescription getResourceDescription(InpatientAdmission req, Representation representation) { + DelegatingResourceDescription ret = super.getResourceDescription(req, representation); + if (representation instanceof DefaultRepresentation) { + DelegatingResourceDescription rep = new DelegatingResourceDescription(); + rep.addProperty("visit", Representation.DEFAULT); + rep.addProperty("currentInpatientLocation", Representation.REF); + rep.addProperty("firstAdmissionOrTransferEncounter", getEncounterRepresentation()); + rep.addProperty("latestAdmissionOrTransferEncounter", getEncounterRepresentation()); + rep.addProperty("encounterAssigningToCurrentInpatientLocation", getEncounterRepresentation()); + rep.addProperty("discharged"); + return rep; + } + else if (representation instanceof FullRepresentation) { + for (String property : ret.getProperties().keySet()) { + if (!property.equals("visit")) { + ret.addProperty(property, Representation.DEFAULT); + } + } + } + return ret; + } + + public Representation getEncounterRepresentation() { + return new CustomRepresentation("uuid,display,encounterDatetime,location:ref,encounterType:ref"); + } +} diff --git a/omod/src/main/java/org/openmrs/module/emrapi/web/controller/InpatientAdmissionController.java b/omod/src/main/java/org/openmrs/module/emrapi/web/controller/InpatientAdmissionController.java new file mode 100644 index 00000000..a8106c1d --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/emrapi/web/controller/InpatientAdmissionController.java @@ -0,0 +1,47 @@ +package org.openmrs.module.emrapi.web.controller; + +import org.openmrs.Location; +import org.openmrs.module.emrapi.adt.AdtService; +import org.openmrs.module.emrapi.adt.InpatientAdmission; +import org.openmrs.module.emrapi.adt.InpatientAdmissionSearchCriteria; +import org.openmrs.module.emrapi.rest.converter.InpatientAdmissionConverter; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestUtil; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +@Controller +public class InpatientAdmissionController { + + @Autowired + private AdtService adtService; + + @RequestMapping(method = RequestMethod.GET, value = "/rest/**/emrapi/inpatient/admission") + @ResponseBody + public SimpleObject getInpatientAdmissions( + HttpServletRequest request, + HttpServletResponse response, + @RequestParam(required = false, value = "visitLocation") Location visitLocation, + @RequestParam(required = false, value = "currentInpatientLocation") List currentInpatientLocations, + @RequestParam(required = false, value = "includeDischarged") boolean includeDischarged + ) { + RequestContext context = RestUtil.getRequestContext(request, response, Representation.DEFAULT); + InpatientAdmissionSearchCriteria criteria = new InpatientAdmissionSearchCriteria(); + criteria.setVisitLocation(visitLocation); + criteria.setCurrentInpatientLocations(currentInpatientLocations); + criteria.setIncludeDischarged(includeDischarged); + List requests = adtService.getInpatientAdmissions(criteria); + return new NeedsPaging<>(requests, context).toSimpleObject(new InpatientAdmissionConverter()); + } +} diff --git a/omod/src/main/java/org/openmrs/module/emrapi/web/controller/InpatientVisitsController.java b/omod/src/main/java/org/openmrs/module/emrapi/web/controller/InpatientVisitsController.java index d4ddd4ce..7361560f 100644 --- a/omod/src/main/java/org/openmrs/module/emrapi/web/controller/InpatientVisitsController.java +++ b/omod/src/main/java/org/openmrs/module/emrapi/web/controller/InpatientVisitsController.java @@ -18,6 +18,7 @@ @Controller @RequestMapping(value = "/rest/**/emrapi/inpatient") +@Deprecated public class InpatientVisitsController { @Autowired