diff --git a/api/src/main/java/org/openmrs/module/queue/api/QueueEntryService.java b/api/src/main/java/org/openmrs/module/queue/api/QueueEntryService.java index 72499a2..7bd0e7c 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/QueueEntryService.java +++ b/api/src/main/java/org/openmrs/module/queue/api/QueueEntryService.java @@ -11,13 +11,14 @@ import javax.validation.constraints.NotNull; -import java.util.Collection; +import java.util.List; import java.util.Optional; import org.openmrs.Location; import org.openmrs.Visit; import org.openmrs.VisitAttributeType; import org.openmrs.api.APIException; +import org.openmrs.module.queue.api.search.QueueEntrySearchCriteria; import org.openmrs.module.queue.model.Queue; import org.openmrs.module.queue.model.QueueEntry; @@ -45,15 +46,15 @@ public interface QueueEntryService { * @param queueEntry the queue entry to be saved * @return saved {@link org.openmrs.module.queue.model.QueueEntry} */ - QueueEntry createQueueEntry(@NotNull QueueEntry queueEntry); + QueueEntry saveQueueEntry(@NotNull QueueEntry queueEntry); /** * Voids a queue entry * - * @param queueEntryUuid uuid of the queue entry to be voided + * @param queueEntry the queue entry to be voided * @param voidReason the reason for voiding the queue entry */ - void voidQueueEntry(@NotNull String queueEntryUuid, String voidReason); + void voidQueueEntry(@NotNull QueueEntry queueEntry, String voidReason); /** * Completely remove a queue entry from the database @@ -64,21 +65,15 @@ public interface QueueEntryService { void purgeQueueEntry(@NotNull QueueEntry queueEntry) throws APIException; /** - * Search for queue entries by conceptStatus - * - * @param conceptStatus queue entry conceptStatus - * @param includeVoided include/exclude voided queue entries - * @return {@link java.util.Collection} of queue entries with the specified statuses + * @return {@link List} of queue entries that match the given %{@link QueueEntrySearchCriteria} */ - Collection searchQueueEntriesByConceptStatus(@NotNull String conceptStatus, boolean includeVoided); + List getQueueEntries(@NotNull QueueEntrySearchCriteria searchCriteria); /** - * Gets count of queue entries by status - * - * @param status the queue entry status - * @return {@link java.lang.Long} count of queue entries by specified status + * @return {@link Long} count of queue entries that match the given + * %{@link QueueEntrySearchCriteria} */ - Long getQueueEntriesCountByStatus(@NotNull String status); + Long getCountOfQueueEntries(@NotNull QueueEntrySearchCriteria searchCriteria); /** * @param location diff --git a/api/src/main/java/org/openmrs/module/queue/api/QueueRoomService.java b/api/src/main/java/org/openmrs/module/queue/api/QueueRoomService.java index cd282ad..753463f 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/QueueRoomService.java +++ b/api/src/main/java/org/openmrs/module/queue/api/QueueRoomService.java @@ -14,9 +14,8 @@ import java.util.List; import java.util.Optional; -import org.openmrs.Location; import org.openmrs.api.APIException; -import org.openmrs.module.queue.model.Queue; +import org.openmrs.module.queue.api.search.QueueRoomSearchCriteria; import org.openmrs.module.queue.model.QueueRoom; public interface QueueRoomService { @@ -25,11 +24,13 @@ public interface QueueRoomService { Optional getQueueRoomById(@NotNull int id); - QueueRoom createQueueRoom(@NotNull QueueRoom queueRoom); + List getAllQueueRooms(); - List getQueueRoomsByServiceAndLocation(Queue queue, Location location); + QueueRoom saveQueueRoom(@NotNull QueueRoom queueRoom); - void voidQueueRoom(@NotNull String queueRoomUuid, String voidReason); + List getQueueRooms(QueueRoomSearchCriteria searchCriteria); - void purgeQueueRoom(QueueRoom queueRoom) throws APIException; + void retireQueueRoom(@NotNull QueueRoom queueRoom, String voidReason); + + void purgeQueueRoom(@NotNull QueueRoom queueRoom) throws APIException; } diff --git a/api/src/main/java/org/openmrs/module/queue/api/QueueService.java b/api/src/main/java/org/openmrs/module/queue/api/QueueService.java index a38ab13..b56bd85 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/QueueService.java +++ b/api/src/main/java/org/openmrs/module/queue/api/QueueService.java @@ -11,12 +11,11 @@ import javax.validation.constraints.NotNull; -import java.util.Collection; import java.util.List; import java.util.Optional; -import org.openmrs.Concept; import org.openmrs.api.APIException; +import org.openmrs.module.queue.api.search.QueueSearchCriteria; import org.openmrs.module.queue.model.Queue; /** @@ -46,30 +45,25 @@ public interface QueueService { * @param queue the queue to be saved * @return saved {@link org.openmrs.module.queue.model.Queue} */ - Queue createQueue(@NotNull Queue queue); + Queue saveQueue(@NotNull Queue queue); /** - * Gets all queues related to a specified location. - * - * @param locationUuid UUID of the location being queried. - * @return {@link java.util.List} of {@link org.openmrs.module.queue.model.Queue} + * @return all queues */ - List getAllQueuesByLocation(@NotNull String locationUuid); + List getAllQueues(); /** - * Gets all queues - * - * @return all queues + * @return {@link List} of queues that match the given %{@link QueueSearchCriteria} */ - Collection getAllQueues(); + List getQueues(@NotNull QueueSearchCriteria searchCriteria); /** * Voids a queue * - * @param queueUuid uuid of the queue to be voided - * @param voidReason the reason for voiding the queue + * @param queue the queue to retire + * @param retireReason the reason for voiding the queue */ - void voidQueue(@NotNull String queueUuid, String voidReason); + void retireQueue(@NotNull Queue queue, String retireReason); /** * Completely remove a queue from the database @@ -78,12 +72,4 @@ public interface QueueService { * @throws APIException Should delete the given queue from the database */ void purgeQueue(@NotNull Queue queue) throws APIException; - - /** - * Returns average weight time for patients in a queue - * - * @param queue - * @return - */ - Double getQueueAverageWaitTime(@NotNull Queue queue, Concept status); } diff --git a/api/src/main/java/org/openmrs/module/queue/api/QueueServicesWrapper.java b/api/src/main/java/org/openmrs/module/queue/api/QueueServicesWrapper.java new file mode 100644 index 0000000..ad155a0 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/queue/api/QueueServicesWrapper.java @@ -0,0 +1,260 @@ +/* + * 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. + */ +package org.openmrs.module.queue.api; + +import java.util.ArrayList; +import java.util.List; + +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; +import org.openmrs.Concept; +import org.openmrs.Location; +import org.openmrs.Patient; +import org.openmrs.Provider; +import org.openmrs.Visit; +import org.openmrs.api.ConceptService; +import org.openmrs.api.LocationService; +import org.openmrs.api.PatientService; +import org.openmrs.api.ProviderService; +import org.openmrs.api.VisitService; +import org.openmrs.module.queue.model.Queue; +import org.openmrs.module.queue.model.QueueRoom; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +@Component +@Getter +public class QueueServicesWrapper { + + private final QueueService queueService; + + private final QueueEntryService queueEntryService; + + private final QueueRoomService queueRoomService; + + private final RoomProviderMapService roomProviderMapService; + + private final ConceptService conceptService; + + private final LocationService locationService; + + private final PatientService patientService; + + private final VisitService visitService; + + private final ProviderService providerService; + + @Autowired + public QueueServicesWrapper(@Qualifier("queue.QueueService") QueueService queueService, + @Qualifier("queue.QueueEntryService") QueueEntryService queueEntryService, + @Qualifier("queue.QueueRoomService") QueueRoomService queueRoomService, + @Qualifier("queue.RoomProviderMapService") RoomProviderMapService roomProviderMapService, + ConceptService conceptService, LocationService locationService, PatientService patientService, + VisitService visitService, ProviderService providerService) { + this.queueService = queueService; + this.queueEntryService = queueEntryService; + this.queueRoomService = queueRoomService; + this.roomProviderMapService = roomProviderMapService; + this.conceptService = conceptService; + this.locationService = locationService; + this.patientService = patientService; + this.visitService = visitService; + this.providerService = providerService; + } + + /** + * @param conceptRefs array of concept references + * @return a List of Concepts matching those references + */ + public List getConcepts(String[] conceptRefs) { + List ret = new ArrayList<>(); + for (String conceptRef : conceptRefs) { + ret.add(getConcept(conceptRef.trim())); + } + return ret; + } + + /** + * @param conceptRef a uuid, source:mapping, or unique name for the concept to retrieve + * @return the concept that matches the conceptRef + */ + public Concept getConcept(String conceptRef) { + if (StringUtils.isBlank(conceptRef)) { + return null; + } + Concept c = getConceptService().getConceptByUuid(conceptRef); + if (c != null) { + return c; + } + //handle mapping + int idx = conceptRef.indexOf(":"); + if (idx >= 0 && idx < conceptRef.length() - 1) { + String conceptSource = conceptRef.substring(0, idx); + String conceptCode = conceptRef.substring(idx + 1); + c = getConceptService().getConceptByMapping(conceptCode, conceptSource); + if (c != null) { + return c; + } + } + //handle name + List concepts = getConceptService().getConceptsByName(conceptRef); + if (concepts.size() == 1) { + return concepts.get(0); + } else if (concepts.size() > 1) { + throw new IllegalArgumentException("More than one concept is found with name: " + conceptRef); + } + throw new IllegalArgumentException("Unable to find concept: " + conceptRef); + } + + /** + * @param locationRefs array of concept references + * @return a List of Locations matching those references + */ + public List getLocations(String[] locationRefs) { + List ret = new ArrayList<>(); + for (String locationRef : locationRefs) { + ret.add(getLocation(locationRef.trim())); + } + return ret; + } + + /** + * @param locationRef a uuid or unique name for the location to retrieve + * @return the location that matches the locationRef + */ + public Location getLocation(String locationRef) { + if (StringUtils.isBlank(locationRef)) { + return null; + } + Location l = getLocationService().getLocationByUuid(locationRef); + if (l != null) { + return l; + } + List locations = getLocationService().getLocations(locationRef); + if (locations.size() == 1) { + return locations.get(0); + } else if (locations.size() > 1) { + throw new IllegalArgumentException("More than one location is found with name: " + locationRef); + } + throw new IllegalArgumentException("Unable to find location: " + locationRef); + } + + /** + * @param patientRef a uuid for the patient to retrieve + * @return the patient that matches the patientRef + */ + public Patient getPatient(String patientRef) { + if (StringUtils.isBlank(patientRef)) { + return null; + } + Patient p = getPatientService().getPatientByUuid(patientRef); + if (p != null) { + return p; + } + throw new IllegalArgumentException("Unable to find patient: " + patientRef); + } + + /** + * @param visitRef a uuid for the Visit to retrieve + * @return the Visit that matches the visitRef + */ + public Visit getVisit(String visitRef) { + if (StringUtils.isBlank(visitRef)) { + return null; + } + Visit v = getVisitService().getVisitByUuid(visitRef); + if (v != null) { + return v; + } + throw new IllegalArgumentException("Unable to find Visit: " + visitRef); + } + + /** + * @param queueRefs array of Queue references + * @return a List of Queues matching those references + */ + public List getQueues(String[] queueRefs) { + List ret = new ArrayList<>(); + for (String queueRef : queueRefs) { + ret.add(getQueue(queueRef.trim())); + } + return ret; + } + + /** + * @param queueRef a uuid for the queue to retrieve + * @return the queue that matches the queueRef + */ + public Queue getQueue(String queueRef) { + if (StringUtils.isBlank(queueRef)) { + return null; + } + Queue queue = getQueueService().getQueueByUuid(queueRef).orElse(null); + if (queue != null) { + return queue; + } + throw new IllegalArgumentException("Unable to find queue: " + queueRef); + } + + /** + * @param providerRefs array of Provider references + * @return a List of Providers matching those references + */ + public List getProviders(String[] providerRefs) { + List ret = new ArrayList<>(); + for (String providerRef : providerRefs) { + ret.add(getProvider(providerRef.trim())); + } + return ret; + } + + /** + * @param providerRef a uuid for the provider to retrieve + * @return the provider that matches the providerRef + */ + public Provider getProvider(String providerRef) { + if (StringUtils.isBlank(providerRef)) { + return null; + } + Provider provider = getProviderService().getProviderByUuid(providerRef); + if (provider != null) { + return provider; + } + throw new IllegalArgumentException("Unable to find provider: " + providerRef); + } + + /** + * @param queueRoomRefs array of QueueRoom references + * @return a List of QueueRooms matching those references + */ + public List getQueueRooms(String[] queueRoomRefs) { + List ret = new ArrayList<>(); + for (String queueRoomRef : queueRoomRefs) { + ret.add(getQueueRoom(queueRoomRef.trim())); + } + return ret; + } + + /** + * @param queueRoomRef a uuid for the queueRoom to retrieve + * @return the queueRoom that matches the queueRoomRef + */ + public QueueRoom getQueueRoom(String queueRoomRef) { + if (StringUtils.isBlank(queueRoomRef)) { + return null; + } + QueueRoom queueRoom = getQueueRoomService().getQueueRoomByUuid(queueRoomRef).orElse(null); + if (queueRoom != null) { + return queueRoom; + } + throw new IllegalArgumentException("Unable to find queueRoom: " + queueRoomRef); + } +} diff --git a/api/src/main/java/org/openmrs/module/queue/api/RoomProviderMapService.java b/api/src/main/java/org/openmrs/module/queue/api/RoomProviderMapService.java index 8605e1d..7e30a50 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/RoomProviderMapService.java +++ b/api/src/main/java/org/openmrs/module/queue/api/RoomProviderMapService.java @@ -14,9 +14,8 @@ import java.util.List; import java.util.Optional; -import org.openmrs.Provider; import org.openmrs.api.APIException; -import org.openmrs.module.queue.model.QueueRoom; +import org.openmrs.module.queue.api.search.RoomProviderMapSearchCriteria; import org.openmrs.module.queue.model.RoomProviderMap; public interface RoomProviderMapService { @@ -25,12 +24,14 @@ public interface RoomProviderMapService { Optional getRoomProviderMapById(@NotNull int id); - RoomProviderMap createRoomProviderMap(@NotNull RoomProviderMap roomProviderMap); + RoomProviderMap saveRoomProviderMap(@NotNull RoomProviderMap roomProviderMap); - List getRoomProvider(Provider provider, QueueRoom queueRoom); + List getAllRoomProviderMaps(); - void voidRoomProviderMap(@NotNull String roomProviderMapUuid, String voidReason); + List getRoomProviderMaps(RoomProviderMapSearchCriteria searchCriteria); - void purgeRoomProviderMap(RoomProviderMap roomProviderMap) throws APIException; + void voidRoomProviderMap(@NotNull RoomProviderMap roomProviderMap, String voidReason); + + void purgeRoomProviderMap(@NotNull RoomProviderMap roomProviderMap) throws APIException; } diff --git a/api/src/main/java/org/openmrs/module/queue/api/VisitQueueEntryService.java b/api/src/main/java/org/openmrs/module/queue/api/VisitQueueEntryService.java deleted file mode 100644 index ee74ad0..0000000 --- a/api/src/main/java/org/openmrs/module/queue/api/VisitQueueEntryService.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.api; - -import javax.validation.constraints.NotNull; - -import java.util.Collection; -import java.util.Optional; - -import org.openmrs.api.APIException; -import org.openmrs.module.queue.model.VisitQueueEntry; - -public interface VisitQueueEntryService { - - /** - * Gets a visit queue entry given UUID. - * - * @param uuid uuid of the visit queue entry to be returned. - * @return {@link org.openmrs.module.queue.model.VisitQueueEntry} - */ - Optional getVisitQueueEntryByUuid(@NotNull String uuid); - - /** - * Saves a visit queue entry record - * - * @param visitQueueEntry the visit queue entry to be saved - * @return saved {@link org.openmrs.module.queue.model.VisitQueueEntry} - */ - VisitQueueEntry createVisitQueueEntry(@NotNull VisitQueueEntry visitQueueEntry); - - /** - * Finds all {@link VisitQueueEntry} in the database - * - * @return {@link Collection} of all visit queue entries in the db - */ - Collection findAllVisitQueueEntries(); - - /** - * Gets only active queue entries (If endDate is null & not voided) - * - * @return {@link Collection} of queue entries - */ - Collection getActiveVisitQueueEntries(); - - /** - * Find visitQueueEntries by service and status i.e. Find patients waiting for(status) certain - * service - * - * @param status concept name for queueEntry status - * @param service concept name for queue service - * @param locationUuid location uuid for the queue location - * @return {@link Collection} visitQueueEntries matching specified parameters - */ - Collection findVisitQueueEntries(String status, String service, String locationUuid, - String patientUuid); - - /** - * Voids a visit queue entry record - * - * @param visitQueueEntryUuid uuid of the queue entry to be voided - * @param voidReason the reason for voiding the queue entry - */ - void voidVisitQueueEntry(@NotNull String visitQueueEntryUuid, String voidReason); - - /** - * Completely remove a visit queue entry from the database - * - * @param visitQueueEntry visit queue entry to be deleted - * @throws org.openmrs.api.APIException - */ - void purgeQueueEntry(@NotNull VisitQueueEntry visitQueueEntry) throws APIException; - - /** - * Gets count of visit queue entries filtered by status - * - * @param status concept status name - * @return {@link Long} count of visit queue entries - */ - Long getVisitQueueEntriesCountByStatus(@NotNull String status); - - /** - * Gets count of visit queue entries filtered by service - * - * @param service concept service name - * @return {@link Long} count of visit queue entries - */ - Long getVisitQueueEntriesCountByService(@NotNull String service); - - /** - * Gets count of visit queue entries filtered by location - * - * @param locationUuid location uuid - * @return {@link Long} count of visit queue entries - */ - Long getVisitQueueEntriesCountByLocation(@NotNull String locationUuid); - - /** - * Gets count of visit queue entries filtered by location, service and status - * - * @param service concept service name - * @param status concept status name - * @param locaitonUuid location uuid - * @return {@link Long} count of visit queue entries - */ - Long getVisitQueueEntriesCountByLocationStatusAndService(@NotNull String status, String service, String locationUUid); - -} diff --git a/api/src/main/java/org/openmrs/module/queue/api/dao/BaseQueueDao.java b/api/src/main/java/org/openmrs/module/queue/api/dao/BaseQueueDao.java index 485a582..9df2833 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/dao/BaseQueueDao.java +++ b/api/src/main/java/org/openmrs/module/queue/api/dao/BaseQueueDao.java @@ -11,7 +11,7 @@ import javax.validation.constraints.NotNull; -import java.util.Collection; +import java.util.List; import java.util.Optional; import org.openmrs.Auditable; @@ -33,8 +33,8 @@ public interface BaseQueueDao { void delete(@NotNull String uuid); @Transactional(readOnly = true) - Collection findAll(); + List findAll(); @Transactional(readOnly = true) - Collection findAll(boolean includeVoided); + List findAll(boolean includeVoided); } diff --git a/api/src/main/java/org/openmrs/module/queue/api/dao/QueueDao.java b/api/src/main/java/org/openmrs/module/queue/api/dao/QueueDao.java index d3d740f..c5912d6 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/dao/QueueDao.java +++ b/api/src/main/java/org/openmrs/module/queue/api/dao/QueueDao.java @@ -11,19 +11,15 @@ import javax.validation.constraints.NotNull; -import java.time.LocalDate; import java.util.List; -import org.openmrs.Auditable; -import org.openmrs.Concept; -import org.openmrs.OpenmrsObject; +import org.openmrs.module.queue.api.search.QueueSearchCriteria; import org.openmrs.module.queue.model.Queue; -public interface QueueDao extends BaseQueueDao { +public interface QueueDao extends BaseQueueDao { - List getAllQueuesByLocation(@NotNull String locationUuid); - - List getAllQueuesByLocation(@NotNull String locationUuid, boolean includeVoided); - - Double getQueueAverageWaitTime(@NotNull Queue queue, Concept status, LocalDate today); + /** + * @return {@link List} of queues that match the given %{@link QueueSearchCriteria} + */ + List getQueues(@NotNull QueueSearchCriteria searchCriteria); } diff --git a/api/src/main/java/org/openmrs/module/queue/api/dao/QueueEntryDao.java b/api/src/main/java/org/openmrs/module/queue/api/dao/QueueEntryDao.java index 45b7b26..ea761c2 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/dao/QueueEntryDao.java +++ b/api/src/main/java/org/openmrs/module/queue/api/dao/QueueEntryDao.java @@ -11,51 +11,24 @@ import javax.validation.constraints.NotNull; -import java.util.Collection; import java.util.List; import org.openmrs.Auditable; -import org.openmrs.Location; import org.openmrs.OpenmrsObject; -import org.openmrs.api.ConceptNameType; -import org.openmrs.module.queue.model.Queue; +import org.openmrs.module.queue.api.search.QueueEntrySearchCriteria; import org.openmrs.module.queue.model.QueueEntry; public interface QueueEntryDao extends BaseQueueDao { /** - * Searches queue entries by conceptStatus - * - * @param conceptStatus the queueEntry conceptStatus - * @param includeVoided Include/exclude voided queue entries - * @return {@link java.util.Collection} of queue entries with the specified conceptStatus + * @return {@link List} of queue entries that match the given %{@link QueueEntrySearchCriteria} */ - Collection SearchQueueEntriesByConceptStatus(@NotNull String conceptStatus, ConceptNameType conceptNameType, - boolean localePreferred, boolean includeVoided); + List getQueueEntries(@NotNull QueueEntrySearchCriteria searchCriteria); /** - * Gets count of queue entries by given status - * - * @param conceptStatus the queue entry status - * @param conceptNameType the conceptNameType e.g. FULLY_SPECIFIED - * @param localePreferred locale preferred either true or false - * @return {@link java.lang.Long} count of queue entries by status + * @return {@link Long} of the number of queue entries that match the given + * %{@link QueueEntrySearchCriteria} */ - Long getQueueEntriesCountByConceptStatus(@NotNull String conceptStatus, ConceptNameType conceptNameType, - boolean localePreferred); - - /** - * @param location - * @param queue - * @return VisitQueueNumber - used to identify patients in the queue instead of using patient name - */ - String generateVisitQueueNumber(@NotNull Location location, @NotNull Queue queue); - - /** - * Gets active queue entries - * - * @return List of active queue entries - */ - List getActiveQueueEntries(); + Long getCountOfQueueEntries(@NotNull QueueEntrySearchCriteria searchCriteria); } diff --git a/api/src/main/java/org/openmrs/module/queue/api/dao/QueueRoomDao.java b/api/src/main/java/org/openmrs/module/queue/api/dao/QueueRoomDao.java index 3c1107e..732a842 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/dao/QueueRoomDao.java +++ b/api/src/main/java/org/openmrs/module/queue/api/dao/QueueRoomDao.java @@ -11,11 +11,10 @@ import java.util.List; -import org.openmrs.Location; -import org.openmrs.module.queue.model.Queue; +import org.openmrs.module.queue.api.search.QueueRoomSearchCriteria; import org.openmrs.module.queue.model.QueueRoom; public interface QueueRoomDao extends BaseQueueDao { - List getQueueRoomsByServiceAndLocation(Queue queue, Location location); + List getQueueRooms(QueueRoomSearchCriteria searchCriteria); } diff --git a/api/src/main/java/org/openmrs/module/queue/api/dao/RoomProviderMapDao.java b/api/src/main/java/org/openmrs/module/queue/api/dao/RoomProviderMapDao.java index 80f1944..98a1e38 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/dao/RoomProviderMapDao.java +++ b/api/src/main/java/org/openmrs/module/queue/api/dao/RoomProviderMapDao.java @@ -11,12 +11,11 @@ import java.util.List; -import org.openmrs.Provider; -import org.openmrs.module.queue.model.QueueRoom; +import org.openmrs.module.queue.api.search.RoomProviderMapSearchCriteria; import org.openmrs.module.queue.model.RoomProviderMap; public interface RoomProviderMapDao extends BaseQueueDao { - List getRoomProvider(Provider provider, QueueRoom queueRoom); + List getRoomProviderMaps(RoomProviderMapSearchCriteria searchCriteria); } diff --git a/api/src/main/java/org/openmrs/module/queue/api/dao/VisitQueueEntryDao.java b/api/src/main/java/org/openmrs/module/queue/api/dao/VisitQueueEntryDao.java deleted file mode 100644 index cb2c09b..0000000 --- a/api/src/main/java/org/openmrs/module/queue/api/dao/VisitQueueEntryDao.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.api.dao; - -import java.util.Collection; - -import org.openmrs.Auditable; -import org.openmrs.OpenmrsObject; -import org.openmrs.api.ConceptNameType; -import org.openmrs.module.queue.model.VisitQueueEntry; - -public interface VisitQueueEntryDao extends BaseQueueDao { - - /** - * Finds {@link VisitQueueEntry} by conceptStatus and conceptService. - * - * @param conceptStatus conceptName for queueEntry conceptStatus concept. - * @param conceptService conceptName for queue conceptService concept. - * @param locationUuid location uuid for queue. - * @return {@link Collection} of visitQueueEntries matching specified parameters. - */ - Collection findVisitQueueEntriesByConceptStatusAndConceptService(String conceptStatus, - String conceptService, ConceptNameType conceptNameType, boolean localePreferred, String locationUuid, - String patientUuid); - - /** - * Gets visit queue entries filtered by service and status e.g. count of patient waiting for triage - * - * @param conceptStatus the status of patient in the queue - * @param conceptService which service is the patient waiting/attending to - * @param conceptNameType the concept name type e.g. fully_specified - * @param localePreferred locale preferred concept name - * @return {@link Long} count of patients matching the specified parameters - */ - Long getVisitQueueEntriesCountByLocationStatusAndService(String conceptStatus, String conceptService, - ConceptNameType conceptNameType, boolean localePreferred, String locationUuid); -} diff --git a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/AbstractBaseQueueDaoImpl.java b/api/src/main/java/org/openmrs/module/queue/api/dao/impl/AbstractBaseQueueDaoImpl.java index e80e970..a5319a0 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/AbstractBaseQueueDaoImpl.java +++ b/api/src/main/java/org/openmrs/module/queue/api/dao/impl/AbstractBaseQueueDaoImpl.java @@ -15,6 +15,7 @@ import java.lang.reflect.ParameterizedType; import java.util.Collection; +import java.util.List; import java.util.Optional; import lombok.AccessLevel; @@ -24,16 +25,11 @@ import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; -import org.hibernate.criterion.Conjunction; -import org.hibernate.criterion.DetachedCriteria; -import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.openmrs.Auditable; -import org.openmrs.ConceptName; import org.openmrs.OpenmrsObject; import org.openmrs.Retireable; import org.openmrs.Voidable; -import org.openmrs.api.ConceptNameType; import org.openmrs.module.queue.api.dao.BaseQueueDao; @Slf4j @@ -85,12 +81,12 @@ public void delete(@NotNull String uuid) { } @Override - public Collection findAll() { + public List findAll() { return this.findAll(false); } @Override - public Collection findAll(boolean includeVoided) { + public List findAll(boolean includeVoided) { Criteria criteria = getCurrentSession().createCriteria(clazz); includeVoidedObjects(criteria, includeVoided); return criteria.list(); @@ -123,22 +119,47 @@ protected void includeVoidedObjects(Criteria criteria, boolean includeRetired) { } /** - * Creates concept names subQuery - * - * @param conceptName Concept name - * @return {@link DetachedCriteria} conceptName subQuery + * If the passed value is null, return without limiting If the passed value is not null, add clause + * that the property must be equal to the value */ - protected DetachedCriteria conceptByNameDetachedCriteria(@NotNull String conceptName, boolean localePreferred, - ConceptNameType conceptNameType) { - DetachedCriteria detachedCriteria = DetachedCriteria.forClass(ConceptName.class, "cn"); - Conjunction and = Restrictions.conjunction(); - and.add(Restrictions.eq("cn.name", conceptName)); - //An option to restrict by localePreferred - and.add(Restrictions.eq("cn.localePreferred", localePreferred)); - and.add(Restrictions.eq("cn.conceptNameType", conceptNameType)); - - detachedCriteria.add(and); - detachedCriteria.setProjection(Projections.property("cn.concept")); - return detachedCriteria; + protected void limitToEqualsProperty(Criteria criteria, String property, Object value) { + if (value != null) { + criteria.add(Restrictions.eq(property, value)); + } + } + + /** + * If the passed value is null, return without limiting If the passed value is not null, add clause + * that the property must greater or equal to the value + */ + protected void limitToGreaterThanOrEqualToProperty(Criteria criteria, String property, Object value) { + if (value != null) { + criteria.add(Restrictions.ge(property, value)); + } + } + + /** + * If the passed value is null, return without limiting If the passed value is not null, add clause + * that the property must be less or equal to the value + */ + protected void limitToLessThanOrEqualToProperty(Criteria criteria, String property, Object value) { + if (value != null) { + criteria.add(Restrictions.le(property, value)); + } + } + + /** + * If the passed values is null, return without limiting If the passed values is empty, add clause + * that the property must be null If the passed values is not empty, add clause that the property + * must be one of the given values + */ + protected void limitByCollectionProperty(Criteria criteria, String property, Collection values) { + if (values != null) { + if (values.isEmpty()) { + criteria.add(Restrictions.isNull(property)); + } else { + criteria.add(Restrictions.in(property, values)); + } + } } } diff --git a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueDaoImpl.java b/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueDaoImpl.java index 387cc85..908308d 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueDaoImpl.java +++ b/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueDaoImpl.java @@ -9,91 +9,28 @@ */ package org.openmrs.module.queue.api.dao.impl; -import javax.validation.constraints.NotNull; - -import java.time.Duration; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Date; import java.util.List; import org.hibernate.Criteria; import org.hibernate.SessionFactory; -import org.hibernate.criterion.Conjunction; -import org.hibernate.criterion.Restrictions; -import org.openmrs.Concept; -import org.openmrs.api.APIException; import org.openmrs.module.queue.api.dao.QueueDao; +import org.openmrs.module.queue.api.search.QueueSearchCriteria; import org.openmrs.module.queue.model.Queue; -import org.openmrs.module.queue.model.QueueEntry; import org.springframework.beans.factory.annotation.Qualifier; @SuppressWarnings("unchecked") -public class QueueDaoImpl extends AbstractBaseQueueDaoImpl implements QueueDao { +public class QueueDaoImpl extends AbstractBaseQueueDaoImpl implements QueueDao { public QueueDaoImpl(@Qualifier(value = "sessionFactory") SessionFactory sessionFactory) { super(sessionFactory); } @Override - public List getAllQueuesByLocation(@NotNull String locationUuid) { - return this.getAllQueuesByLocation(locationUuid, false); - } - - @Override - public List getAllQueuesByLocation(@NotNull String locationUuid, boolean includeVoided) { - Criteria criteria = getCurrentSession().createCriteria(Queue.class); - //Include/exclude retired queues - includeVoidedObjects(criteria, includeVoided); - Criteria locationCriteria = criteria.createCriteria("location", "ql"); - locationCriteria.add(Restrictions.eq("ql.uuid", locationUuid)); - return (List) locationCriteria.list(); - } - - @Override - public Double getQueueAverageWaitTime(@NotNull Queue queue, Concept status, LocalDate today) { - if (queue == null) { - throw new APIException("Queue cannot be null"); - } - LocalDate minDate = LocalDate.now(); - LocalDate maxDate = LocalDate.now().plusDays(1); - - Date date1 = Date.from(minDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); - Date date2 = Date.from(maxDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); - - Criteria criteria = getCurrentSession().createCriteria(QueueEntry.class, "qe"); - handleVoidable(criteria); - - Conjunction queueEntryStartedAtCheck = Restrictions.conjunction(); - queueEntryStartedAtCheck.add(Restrictions.ge("startedAt", date1)); - queueEntryStartedAtCheck.add(Restrictions.lt("startedAt", date2)); - - Conjunction queueEntryEndedAtCheck = Restrictions.conjunction(); - queueEntryEndedAtCheck.add(Restrictions.ge("endedAt", date1)); - queueEntryEndedAtCheck.add(Restrictions.lt("endedAt", date2)); - - criteria.add(Restrictions.and(queueEntryStartedAtCheck, queueEntryEndedAtCheck, Restrictions.eq("queue", queue))); - - if (status != null) { - criteria.add(Restrictions.and(Restrictions.eq("status", status))); - } - List queuedToday = criteria.list(); - - Double averageWaitTime = 0.0; - - if (!queuedToday.isEmpty()) { - Double totalWaitTime = 0.0; - for (QueueEntry e : queuedToday) { - LocalDateTime startedAt = e.getStartedAt().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); - LocalDateTime endedAt = e.getEndedAt().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); - - totalWaitTime += Duration.between(startedAt, endedAt).toMinutes(); - - } - return totalWaitTime / (queuedToday.size()); - } - - return averageWaitTime; + public List getQueues(QueueSearchCriteria searchCriteria) { + Criteria c = getCurrentSession().createCriteria(Queue.class, "q"); + includeVoidedObjects(c, searchCriteria.isIncludeRetired()); + limitByCollectionProperty(c, "q.location", searchCriteria.getLocations()); + limitByCollectionProperty(c, "q.service", searchCriteria.getServices()); + return c.list(); } } diff --git a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueEntryDaoImpl.java b/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueEntryDaoImpl.java index 477edde..29471f5 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueEntryDaoImpl.java +++ b/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueEntryDaoImpl.java @@ -9,29 +9,15 @@ */ package org.openmrs.module.queue.api.dao.impl; -import static org.hibernate.criterion.Restrictions.eq; - -import javax.validation.constraints.NotNull; - -import java.time.LocalDate; -import java.time.ZoneId; -import java.util.Collection; -import java.util.Date; import java.util.List; -import org.apache.commons.lang3.StringUtils; import org.hibernate.Criteria; import org.hibernate.SessionFactory; -import org.hibernate.criterion.Conjunction; import org.hibernate.criterion.Projections; -import org.hibernate.criterion.Property; import org.hibernate.criterion.Restrictions; -import org.openmrs.Location; -import org.openmrs.api.ConceptNameType; import org.openmrs.module.queue.api.dao.QueueEntryDao; -import org.openmrs.module.queue.model.Queue; +import org.openmrs.module.queue.api.search.QueueEntrySearchCriteria; import org.openmrs.module.queue.model.QueueEntry; -import org.openmrs.module.queue.model.VisitQueueEntry; import org.springframework.beans.factory.annotation.Qualifier; @SuppressWarnings("unchecked") @@ -41,84 +27,50 @@ public QueueEntryDaoImpl(@Qualifier("sessionFactory") SessionFactory sessionFact super(sessionFactory); } - /** - * @see QueueEntryDao#SearchQueueEntriesByConceptStatus(String, ConceptNameType, boolean, boolean) - */ @Override - public Collection SearchQueueEntriesByConceptStatus(@NotNull String status, ConceptNameType conceptNameType, - boolean localePreferred, boolean includeVoided) { - Criteria criteria = getCurrentSession().createCriteria(QueueEntry.class, "qe"); - //Include/exclude retired queues - includeVoidedObjects(criteria, includeVoided); - criteria.add( - Property.forName("qe.status").in(conceptByNameDetachedCriteria(status, localePreferred, conceptNameType))); - + public List getQueueEntries(QueueEntrySearchCriteria searchCriteria) { + Criteria criteria = createCriteriaFromSearchCriteria(searchCriteria); return criteria.list(); } - /** - * @see org.openmrs.module.queue.api.dao.QueueEntryDao#getQueueEntriesCountByConceptStatus(String, - * ConceptNameType, boolean) - */ @Override - public Long getQueueEntriesCountByConceptStatus(@NotNull String conceptStatus, ConceptNameType conceptNameType, - boolean localePreferred) { - Criteria criteria = getCurrentSession().createCriteria(QueueEntry.class, "qe"); - //Include/exclude retired queues - includeVoidedObjects(criteria, false); - criteria.add(Restrictions.and(Restrictions.isNull("qe.endedAt"), Restrictions.isNotNull("qe.startedAt"))); - criteria.add(Property.forName("qe.status") - .in(conceptByNameDetachedCriteria(conceptStatus, localePreferred, conceptNameType))); + public Long getCountOfQueueEntries(QueueEntrySearchCriteria searchCriteria) { + Criteria criteria = createCriteriaFromSearchCriteria(searchCriteria); criteria.setProjection(Projections.rowCount()); - return (Long) criteria.uniqueResult(); } - @Override - public String generateVisitQueueNumber(Location location, Queue queue) { - Criteria criteriaVisitQueueEntries = getCurrentSession().createCriteria(VisitQueueEntry.class, "_vqe"); - includeVoidedObjects(criteriaVisitQueueEntries, false); - Criteria criteriaQueueEntries = criteriaVisitQueueEntries.createCriteria("_vqe.queueEntry", "_qe"); - Criteria criteriaQueue = criteriaQueueEntries.createCriteria("_qe.queue", "_q"); - Criteria criteriaQueueLocation = criteriaQueue.createCriteria("_q.location", "_ql"); - criteriaQueueLocation.add(eq("_ql.uuid", location.getUuid())); - criteriaQueueLocation.add(eq("_q.uuid", queue.getUuid())); - - LocalDate minDate = LocalDate.now(); - LocalDate maxDate = LocalDate.now().plusDays(1); - - Date startOfDay = Date.from(minDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); - Date endOfDay = Date.from(maxDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); - - Conjunction queueEntryStartedAtCheck = Restrictions.conjunction(); - queueEntryStartedAtCheck.add(Restrictions.ge("startedAt", startOfDay)); - queueEntryStartedAtCheck.add(Restrictions.lt("startedAt", endOfDay)); - criteriaQueueEntries.add(queueEntryStartedAtCheck); - - List queueEntryList = criteriaQueueLocation.list(); - - int visitQueueNumber = 1; - - if (!queueEntryList.isEmpty()) { - visitQueueNumber = queueEntryList.size() + 1; - } - - String paddedString = StringUtils.leftPad(String.valueOf(visitQueueNumber), 3, "0"); - - String serviceName = queue.getName().toUpperCase(); - String prefix = serviceName.length() < 3 ? serviceName : serviceName.substring(0, 3); - return prefix + "-" + paddedString; - } - /** - * @see QueueEntryDao#getActiveQueueEntries() + * Convert the given {@link QueueEntrySearchCriteria} into ORM criteria */ - @Override - public List getActiveQueueEntries() { - Criteria criteria = getCurrentSession().createCriteria(QueueEntry.class); - // exclude voided queue entries - includeVoidedObjects(criteria, false); - criteria.add(Restrictions.isNull("endedAt")); - return (List) criteria.list(); + private Criteria createCriteriaFromSearchCriteria(QueueEntrySearchCriteria searchCriteria) { + Criteria c = getCurrentSession().createCriteria(QueueEntry.class, "qe"); + c.createAlias("queue", "q"); + includeVoidedObjects(c, searchCriteria.isIncludedVoided()); + limitByCollectionProperty(c, "queue", searchCriteria.getQueues()); + limitByCollectionProperty(c, "q.location", searchCriteria.getLocations()); + limitByCollectionProperty(c, "q.service", searchCriteria.getServices()); + limitToEqualsProperty(c, "qe.patient", searchCriteria.getPatient()); + limitToEqualsProperty(c, "qe.visit", searchCriteria.getVisit()); + limitByCollectionProperty(c, "qe.priority", searchCriteria.getPriorities()); + limitByCollectionProperty(c, "qe.status", searchCriteria.getStatuses()); + limitByCollectionProperty(c, "qe.locationWaitingFor", searchCriteria.getLocationsWaitingFor()); + limitByCollectionProperty(c, "qe.providerWaitingFor", searchCriteria.getProvidersWaitingFor()); + limitByCollectionProperty(c, "qe.queueComingFrom", searchCriteria.getQueuesComingFrom()); + limitToGreaterThanOrEqualToProperty(c, "qe.startedAt", searchCriteria.getStartedOnOrAfter()); + limitToLessThanOrEqualToProperty(c, "qe.startedAt", searchCriteria.getStartedOnOrBefore()); + limitToGreaterThanOrEqualToProperty(c, "qe.endedAt", searchCriteria.getEndedOnOrAfter()); + limitToLessThanOrEqualToProperty(c, "qe.endedAt", searchCriteria.getEndedOnOrBefore()); + if (searchCriteria.getHasVisit() == Boolean.TRUE) { + c.add(Restrictions.isNotNull("qe.visit")); + } else if (searchCriteria.getHasVisit() == Boolean.FALSE) { + c.add(Restrictions.isNull("qe.visit")); + } + if (searchCriteria.getIsEnded() == Boolean.TRUE) { + c.add(Restrictions.isNotNull("qe.endedAt")); + } else if (searchCriteria.getIsEnded() == Boolean.FALSE) { + c.add(Restrictions.isNull("qe.endedAt")); + } + return c; } } diff --git a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueRoomDaoImpl.java b/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueRoomDaoImpl.java index d895c40..f305081 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueRoomDaoImpl.java +++ b/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueRoomDaoImpl.java @@ -11,12 +11,10 @@ import java.util.List; -import org.hibernate.Query; +import org.hibernate.Criteria; import org.hibernate.SessionFactory; -import org.openmrs.Location; -import org.openmrs.api.APIException; import org.openmrs.module.queue.api.dao.QueueRoomDao; -import org.openmrs.module.queue.model.Queue; +import org.openmrs.module.queue.api.search.QueueRoomSearchCriteria; import org.openmrs.module.queue.model.QueueRoom; import org.springframework.beans.factory.annotation.Qualifier; @@ -27,27 +25,15 @@ public QueueRoomDaoImpl(@Qualifier("sessionFactory") SessionFactory sessionFacto } @Override - public List getQueueRoomsByServiceAndLocation(Queue queue, Location location) { - if (queue == null && location == null) { - throw new APIException("Both Queue and Location cannot be null"); - } - String stringQuery = "Select queueRoom from QueueRoom as queueRoom WHERE retired = 0 "; - if (queue != null) { - stringQuery += "AND queueRoom.queue = :queue "; - } - if (location != null) { - stringQuery += "AND queueRoom.queue.location = :location "; - } - - Query query = super.getSessionFactory().getCurrentSession().createQuery(stringQuery); - if (queue != null) { - query.setParameter("queue", queue); - } - if (location != null) { - query.setParameter("location", location); - } - - return query.list(); + @SuppressWarnings("unchecked") + public List getQueueRooms(QueueRoomSearchCriteria searchCriteria) { + Criteria c = getCurrentSession().createCriteria(QueueRoom.class, "qr"); + c.createAlias("queue", "q"); + includeVoidedObjects(c, searchCriteria.isIncludeRetired()); + limitByCollectionProperty(c, "qr.queue", searchCriteria.getQueues()); + limitByCollectionProperty(c, "q.location", searchCriteria.getLocations()); + limitByCollectionProperty(c, "q.service", searchCriteria.getServices()); + return c.list(); } } diff --git a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/RoomProviderMapDaoImpl.java b/api/src/main/java/org/openmrs/module/queue/api/dao/impl/RoomProviderMapDaoImpl.java index 2a41e02..f2a81fc 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/RoomProviderMapDaoImpl.java +++ b/api/src/main/java/org/openmrs/module/queue/api/dao/impl/RoomProviderMapDaoImpl.java @@ -11,12 +11,10 @@ import java.util.List; -import org.hibernate.Query; +import org.hibernate.Criteria; import org.hibernate.SessionFactory; -import org.openmrs.Provider; -import org.openmrs.api.APIException; import org.openmrs.module.queue.api.dao.RoomProviderMapDao; -import org.openmrs.module.queue.model.QueueRoom; +import org.openmrs.module.queue.api.search.RoomProviderMapSearchCriteria; import org.openmrs.module.queue.model.RoomProviderMap; import org.springframework.beans.factory.annotation.Qualifier; @@ -27,27 +25,12 @@ public RoomProviderMapDaoImpl(@Qualifier("sessionFactory") SessionFactory sessio } @Override - public List getRoomProvider(Provider provider, QueueRoom queueRoom) { - if (provider == null && queueRoom == null) { - throw new APIException("Both QueueRoom and Provider cannot be null"); - } - String stringQuery = "Select roomProviderMap from RoomProviderMap as roomProviderMap WHERE voided = 0 "; - if (provider != null && queueRoom != null) { - stringQuery += "AND ( roomProviderMap.provider = :provider or roomProviderMap.queueRoom = :queueRoom ) "; - } else if (provider != null) { - stringQuery += "AND roomProviderMap.provider = :provider "; - } else if (queueRoom != null) { - stringQuery += "AND roomProviderMap.queueRoom = :queueRoom "; - } - - Query query = super.getSessionFactory().getCurrentSession().createQuery(stringQuery); - if (provider != null) { - query.setParameter("provider", provider); - } - if (queueRoom != null) { - query.setParameter("queueRoom", queueRoom); - } - - return query.list(); + @SuppressWarnings("unchecked") + public List getRoomProviderMaps(RoomProviderMapSearchCriteria searchCriteria) { + Criteria c = getCurrentSession().createCriteria(RoomProviderMap.class, "rpm"); + includeVoidedObjects(c, searchCriteria.isIncludeVoided()); + limitByCollectionProperty(c, "rpm.queueRoom", searchCriteria.getQueueRooms()); + limitByCollectionProperty(c, "rpm.provider", searchCriteria.getProviders()); + return c.list(); } } diff --git a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/VisitQueueEntryDaoImpl.java b/api/src/main/java/org/openmrs/module/queue/api/dao/impl/VisitQueueEntryDaoImpl.java deleted file mode 100644 index 1955866..0000000 --- a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/VisitQueueEntryDaoImpl.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.api.dao.impl; - -import static org.hibernate.criterion.Restrictions.and; -import static org.hibernate.criterion.Restrictions.eq; - -import java.util.Collection; - -import lombok.extern.slf4j.Slf4j; -import org.hibernate.Criteria; -import org.hibernate.SessionFactory; -import org.hibernate.criterion.Order; -import org.hibernate.criterion.Projections; -import org.hibernate.criterion.Restrictions; -import org.hibernate.criterion.Subqueries; -import org.openmrs.api.ConceptNameType; -import org.openmrs.module.queue.api.dao.VisitQueueEntryDao; -import org.openmrs.module.queue.model.VisitQueueEntry; -import org.springframework.beans.factory.annotation.Qualifier; - -@Slf4j -@SuppressWarnings("unchecked") -public class VisitQueueEntryDaoImpl extends AbstractBaseQueueDaoImpl implements VisitQueueEntryDao { - - public VisitQueueEntryDaoImpl(@Qualifier("sessionFactory") SessionFactory sessionFactory) { - super(sessionFactory); - } - - /** - * @see VisitQueueEntryDao#findVisitQueueEntriesByConceptStatusAndConceptService(String, String, - * ConceptNameType, boolean, String, String) - */ - @Override - public Collection findVisitQueueEntriesByConceptStatusAndConceptService(String conceptStatus, - String conceptService, ConceptNameType conceptNameType, boolean localePreferred, String locationUuid, - String patientUuid) { - return handleVisitQueueEntriesCriteria(conceptStatus, conceptService, conceptNameType, localePreferred, locationUuid, - patientUuid).list(); - } - - @Override - public Long getVisitQueueEntriesCountByLocationStatusAndService(String conceptStatus, String conceptService, - ConceptNameType conceptNameType, boolean localePreferred, String locationUuid) { - Criteria criteria = handleVisitQueueEntriesCriteria(conceptStatus, conceptService, conceptNameType, localePreferred, - locationUuid, null); - criteria.setProjection(Projections.rowCount()); - return (Long) criteria.uniqueResult(); - } - - private Criteria handleVisitQueueEntriesCriteria(String conceptStatus, String conceptService, - ConceptNameType conceptNameType, boolean localePreferred, String locationUuid, String patientUuid) { - - // Filter queue entries for today - // LocalDate date = LocalDate.now(); - // Date startOfDay = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant()); - // Date endOfDay = Date.from(date.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant()); - - Criteria criteriaVisitQueueEntries = getCurrentSession().createCriteria(VisitQueueEntry.class, "_vqe"); - includeVoidedObjects(criteriaVisitQueueEntries, false); - Criteria criteriaQueueEntries = criteriaVisitQueueEntries.createCriteria("_vqe.queueEntry", "_qe") - .addOrder(Order.desc("_qe.sortWeight")).addOrder(Order.asc("_qe.startedAt")); - Criteria criteriaQueue = criteriaQueueEntries.createCriteria("_qe.queue", "_q"); - Criteria criteriaQueueLocation = criteriaQueue.createCriteria("_q.location", "_ql"); - - criteriaQueueLocation - .add(Restrictions.and(Restrictions.isNull("_qe.endedAt"), Restrictions.isNotNull("_qe.startedAt"))); - // criteriaQueueLocation.add( - // Restrictions.and(Restrictions.ge("_qe.startedAt", startOfDay), Restrictions.lt("_qe.startedAt", endOfDay))); - if (locationUuid != null) { - criteriaQueueLocation.add(eq("_ql.uuid", locationUuid)); - } - - if (patientUuid != null) { - criteriaQueueLocation.createAlias("_qe.patient", "patient"); - criteriaQueueLocation.add(Restrictions.eq("patient.uuid", patientUuid)); - } - - if (conceptStatus != null && conceptService != null) { - criteriaQueueLocation.add(and( - Subqueries.propertiesIn(new String[] { "_qe.status" }, - conceptByNameDetachedCriteria(conceptStatus, localePreferred, conceptNameType)), - Subqueries.propertiesIn(new String[] { "_q.service" }, - conceptByNameDetachedCriteria(conceptService, localePreferred, conceptNameType)))); - } else if (conceptStatus != null) { - criteriaQueueLocation.add(Subqueries.propertiesIn(new String[] { "_qe.status" }, - conceptByNameDetachedCriteria(conceptStatus, localePreferred, conceptNameType))); - } else if (conceptService != null) { - criteriaQueueLocation.add(Subqueries.propertiesIn(new String[] { "_q.service" }, - conceptByNameDetachedCriteria(conceptService, localePreferred, conceptNameType))); - } - - return criteriaQueueLocation; - } - -} diff --git a/api/src/main/java/org/openmrs/module/queue/api/impl/QueueEntryServiceImpl.java b/api/src/main/java/org/openmrs/module/queue/api/impl/QueueEntryServiceImpl.java index a57a5ed..70f7cf1 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/impl/QueueEntryServiceImpl.java +++ b/api/src/main/java/org/openmrs/module/queue/api/impl/QueueEntryServiceImpl.java @@ -11,7 +11,10 @@ import javax.validation.constraints.NotNull; -import java.util.Collection; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Optional; @@ -19,16 +22,18 @@ import lombok.AccessLevel; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.openmrs.Location; import org.openmrs.Visit; import org.openmrs.VisitAttribute; import org.openmrs.VisitAttributeType; import org.openmrs.api.APIException; -import org.openmrs.api.ConceptNameType; +import org.openmrs.api.VisitService; import org.openmrs.api.context.Context; import org.openmrs.api.impl.BaseOpenmrsService; import org.openmrs.module.queue.api.QueueEntryService; import org.openmrs.module.queue.api.dao.QueueEntryDao; +import org.openmrs.module.queue.api.search.QueueEntrySearchCriteria; import org.openmrs.module.queue.model.Queue; import org.openmrs.module.queue.model.QueueEntry; import org.springframework.transaction.annotation.Transactional; @@ -40,73 +45,77 @@ public class QueueEntryServiceImpl extends BaseOpenmrsService implements QueueEn private QueueEntryDao dao; + private VisitService visitService; + public void setDao(QueueEntryDao dao) { this.dao = dao; } + public void setVisitService(VisitService visitService) { + this.visitService = visitService; + } + /** - * @see org.openmrs.module.queue.api.QueueEntryService#getQueueEntryByUuid(String) + * @see QueueEntryService#getQueueEntryByUuid(String) */ @Override + @Transactional(readOnly = true) public Optional getQueueEntryByUuid(@NotNull String queueEntryUuid) { - return this.dao.get(queueEntryUuid); + return dao.get(queueEntryUuid); } /** - * @see org.openmrs.module.queue.api.QueueEntryService#getQueueEntryById(Integer) + * @see QueueEntryService#getQueueEntryById(Integer) */ @Override + @Transactional(readOnly = true) public Optional getQueueEntryById(@NotNull Integer queueEntryId) { - return this.dao.get(queueEntryId); + return dao.get(queueEntryId); } /** - * @see org.openmrs.module.queue.api.QueueEntryService#createQueueEntry(org.openmrs.module.queue.model.QueueEntry) + * @see QueueEntryService#saveQueueEntry(org.openmrs.module.queue.model.QueueEntry) */ @Override - public QueueEntry createQueueEntry(QueueEntry queueEntry) { - return this.dao.createOrUpdate(queueEntry); + public QueueEntry saveQueueEntry(QueueEntry queueEntry) { + if (queueEntry.getVisit() != null) { + if (!queueEntry.getVisit().getPatient().equals(queueEntry.getPatient())) { + throw new IllegalArgumentException("Patient mismatch - visit.patient does not match patient"); + } + } + return dao.createOrUpdate(queueEntry); } /** - * @see org.openmrs.module.queue.api.QueueEntryService#voidQueueEntry(String, String) + * @see QueueEntryService#voidQueueEntry(QueueEntry, String) */ @Override - public void voidQueueEntry(String queueEntryUuid, String voidReason) { - this.dao.get(queueEntryUuid).ifPresent(queueEntry -> { - queueEntry.setVoided(true); - queueEntry.setVoidReason(voidReason); - queueEntry.setDateVoided(new Date()); - queueEntry.setVoidedBy(Context.getAuthenticatedUser()); - //Update - this.dao.createOrUpdate(queueEntry); - }); + public void voidQueueEntry(QueueEntry queueEntry, String voidReason) { + queueEntry.setVoided(true); + queueEntry.setVoidReason(voidReason); + queueEntry.setDateVoided(new Date()); + queueEntry.setVoidedBy(Context.getAuthenticatedUser()); + dao.createOrUpdate(queueEntry); } /** - * @see org.openmrs.module.queue.api.QueueEntryService#purgeQueueEntry(org.openmrs.module.queue.model.QueueEntry) + * @see QueueEntryService#purgeQueueEntry(org.openmrs.module.queue.model.QueueEntry) */ @Override public void purgeQueueEntry(QueueEntry queueEntry) throws APIException { - this.dao.delete(queueEntry); + dao.delete(queueEntry); } - /** - * @see org.openmrs.module.queue.api.QueueEntryService#searchQueueEntriesByConceptStatus(String, - * boolean) - */ @Override - public Collection searchQueueEntriesByConceptStatus(String conceptStatus, boolean includeVoided) { - return this.dao.SearchQueueEntriesByConceptStatus(conceptStatus, ConceptNameType.FULLY_SPECIFIED, false, - includeVoided); + @Transactional(readOnly = true) + public List getQueueEntries(QueueEntrySearchCriteria searchCriteria) { + return dao.getQueueEntries(searchCriteria); } - /** - * @see org.openmrs.module.queue.api.QueueEntryService#getQueueEntriesCountByStatus(String) - */ @Override - public Long getQueueEntriesCountByStatus(@NotNull String status) { - return this.dao.getQueueEntriesCountByConceptStatus(status, ConceptNameType.FULLY_SPECIFIED, false); + @Transactional(readOnly = true) + public Long getCountOfQueueEntries(QueueEntrySearchCriteria searchCriteria) { + return dao.getCountOfQueueEntries(searchCriteria); } @Override @@ -115,20 +124,34 @@ public String generateVisitQueueNumber(Location location, Queue queue, Visit vis if (location == null || queue == null || visit == null || visitAttributeType == null) { throw new APIException("Sufficient parameters not supplied for generation of VisitQueueNumber"); } - String queueNumber = dao.generateVisitQueueNumber(location, queue); + QueueEntrySearchCriteria criteria = new QueueEntrySearchCriteria(); + criteria.setHasVisit(Boolean.TRUE); + criteria.setQueues(Collections.singletonList(queue)); + criteria.setLocations(Collections.singletonList(location)); + Date onOrAfter = Date.from(LocalDateTime.now().with(LocalTime.MIN).atZone(ZoneId.systemDefault()).toInstant()); + criteria.setStartedOnOrAfter(onOrAfter); + Date onOrBefore = Date.from(LocalDateTime.now().with(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant()); + criteria.setStartedOnOrAfter(onOrBefore); + Long nextQueueNumber = getCountOfQueueEntries(criteria) + 1; + String paddedString = StringUtils.leftPad(String.valueOf(nextQueueNumber), 3, "0"); + String serviceName = queue.getName().toUpperCase(); + String prefix = serviceName.length() < 3 ? serviceName : serviceName.substring(0, 3); + String queueNumber = prefix + "-" + paddedString; // Create Visit Attribute using generated queue number VisitAttribute visitQueueNumber = new VisitAttribute(); visitQueueNumber.setAttributeType(visitAttributeType); visitQueueNumber.setValue(queueNumber); visit.setAttribute(visitQueueNumber); - Context.getVisitService().saveVisit(visit); + visitService.saveVisit(visit); return queueNumber; } @Override public void closeActiveQueueEntries() { - List queueEntries = dao.getActiveQueueEntries(); + QueueEntrySearchCriteria criteria = new QueueEntrySearchCriteria(); + criteria.setIsEnded(Boolean.FALSE); + List queueEntries = getQueueEntries(criteria); queueEntries.forEach(this::endQueueEntry); } diff --git a/api/src/main/java/org/openmrs/module/queue/api/impl/QueueRoomServiceImpl.java b/api/src/main/java/org/openmrs/module/queue/api/impl/QueueRoomServiceImpl.java index f23682c..333b44c 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/impl/QueueRoomServiceImpl.java +++ b/api/src/main/java/org/openmrs/module/queue/api/impl/QueueRoomServiceImpl.java @@ -18,13 +18,12 @@ import lombok.AccessLevel; import lombok.Setter; import lombok.extern.slf4j.Slf4j; -import org.openmrs.Location; import org.openmrs.api.APIException; import org.openmrs.api.context.Context; import org.openmrs.api.impl.BaseOpenmrsService; import org.openmrs.module.queue.api.QueueRoomService; import org.openmrs.module.queue.api.dao.QueueRoomDao; -import org.openmrs.module.queue.model.Queue; +import org.openmrs.module.queue.api.search.QueueRoomSearchCriteria; import org.openmrs.module.queue.model.QueueRoom; import org.springframework.transaction.annotation.Transactional; @@ -40,38 +39,45 @@ public void setDao(QueueRoomDao dao) { } @Override + @Transactional(readOnly = true) public Optional getQueueRoomByUuid(String uuid) { - return this.dao.get(uuid); + return dao.get(uuid); } @Override + @Transactional(readOnly = true) public Optional getQueueRoomById(int id) { - return this.dao.get(id); + return dao.get(id); } @Override - public QueueRoom createQueueRoom(QueueRoom queueRoom) { - return this.dao.createOrUpdate(queueRoom); + public QueueRoom saveQueueRoom(QueueRoom queueRoom) { + return dao.createOrUpdate(queueRoom); } @Override - public List getQueueRoomsByServiceAndLocation(Queue queue, Location location) { - return this.dao.getQueueRoomsByServiceAndLocation(queue, location); + @Transactional(readOnly = true) + public List getAllQueueRooms() { + return getQueueRooms(new QueueRoomSearchCriteria()); } @Override - public void voidQueueRoom(@NotNull String queueRoomUuid, String voidReason) { - this.dao.get(queueRoomUuid).ifPresent(queueRoom -> { - queueRoom.setRetired(true); - queueRoom.setDateRetired(new Date()); - queueRoom.setRetireReason(voidReason); - queueRoom.setRetiredBy(Context.getAuthenticatedUser()); - this.dao.createOrUpdate(queueRoom); - }); + @Transactional(readOnly = true) + public List getQueueRooms(QueueRoomSearchCriteria searchCriteria) { + return dao.getQueueRooms(searchCriteria); + } + + @Override + public void retireQueueRoom(@NotNull QueueRoom queueRoom, String retireReason) { + queueRoom.setRetired(true); + queueRoom.setDateRetired(new Date()); + queueRoom.setRetireReason(retireReason); + queueRoom.setRetiredBy(Context.getAuthenticatedUser()); + dao.createOrUpdate(queueRoom); } @Override public void purgeQueueRoom(QueueRoom queueRoom) throws APIException { - this.dao.delete(queueRoom); + dao.delete(queueRoom); } } diff --git a/api/src/main/java/org/openmrs/module/queue/api/impl/QueueServiceImpl.java b/api/src/main/java/org/openmrs/module/queue/api/impl/QueueServiceImpl.java index 556d897..2cbeb14 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/impl/QueueServiceImpl.java +++ b/api/src/main/java/org/openmrs/module/queue/api/impl/QueueServiceImpl.java @@ -11,20 +11,18 @@ import javax.validation.constraints.NotNull; -import java.time.LocalDate; -import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Optional; import lombok.AccessLevel; import lombok.Setter; -import org.openmrs.Concept; import org.openmrs.api.APIException; import org.openmrs.api.context.Context; import org.openmrs.api.impl.BaseOpenmrsService; import org.openmrs.module.queue.api.QueueService; import org.openmrs.module.queue.api.dao.QueueDao; +import org.openmrs.module.queue.api.search.QueueSearchCriteria; import org.openmrs.module.queue.model.Queue; import org.springframework.transaction.annotation.Transactional; @@ -32,9 +30,9 @@ @Setter(AccessLevel.MODULE) public class QueueServiceImpl extends BaseOpenmrsService implements QueueService { - private QueueDao dao; + private QueueDao dao; - public void setDao(QueueDao dao) { + public void setDao(QueueDao dao) { this.dao = dao; } @@ -44,7 +42,7 @@ public void setDao(QueueDao dao) { @Override @Transactional(readOnly = true) public Optional getQueueByUuid(@NotNull String queueUuid) { - return this.dao.get(queueUuid); + return dao.get(queueUuid); } /** @@ -53,24 +51,24 @@ public Optional getQueueByUuid(@NotNull String queueUuid) { @Override @Transactional(readOnly = true) public Optional getQueueById(@NotNull Integer queueId) { - return this.dao.get(queueId); + return dao.get(queueId); } /** - * @see org.openmrs.module.queue.api.QueueService#createQueue(org.openmrs.module.queue.model.Queue) + * @see org.openmrs.module.queue.api.QueueService#saveQueue(Queue) */ @Override - public Queue createQueue(@NotNull Queue queue) { - return this.dao.createOrUpdate(queue); + public Queue saveQueue(@NotNull Queue queue) { + return dao.createOrUpdate(queue); } /** - * @see org.openmrs.module.queue.api.QueueService#getAllQueuesByLocation(String) + * @see org.openmrs.module.queue.api.QueueService#getQueues(QueueSearchCriteria) */ @Override @Transactional(readOnly = true) - public List getAllQueuesByLocation(@NotNull String locationUuid) { - return this.dao.getAllQueuesByLocation(locationUuid); + public List getQueues(@NotNull QueueSearchCriteria searchCriteria) { + return dao.getQueues(searchCriteria); } /** @@ -78,35 +76,27 @@ public List getAllQueuesByLocation(@NotNull String locationUuid) { */ @Override @Transactional(readOnly = true) - public Collection getAllQueues() { - return this.dao.findAll(); + public List getAllQueues() { + return dao.findAll(); } /** - * @see org.openmrs.module.queue.api.QueueService#voidQueue(String, String) + * @see org.openmrs.module.queue.api.QueueService#retireQueue(Queue, String) */ @Override - public void voidQueue(@NotNull String queueUuid, String voidReason) { - this.dao.get(queueUuid).ifPresent(queue -> { - queue.setRetired(true); - queue.setDateRetired(new Date()); - queue.setRetireReason(voidReason); - queue.setRetiredBy(Context.getAuthenticatedUser()); - //Effect the change - this.dao.createOrUpdate(queue); - }); + public void retireQueue(@NotNull Queue queue, String retireReason) { + queue.setRetired(true); + queue.setDateRetired(new Date()); + queue.setRetireReason(retireReason); + queue.setRetiredBy(Context.getAuthenticatedUser()); + dao.createOrUpdate(queue); } /** - * @see org.openmrs.module.queue.api.QueueService#purgeQueue(org.openmrs.module.queue.model.Queue) + * @see org.openmrs.module.queue.api.QueueService#purgeQueue(Queue) */ @Override public void purgeQueue(Queue queue) throws APIException { this.dao.delete(queue); } - - @Override - public Double getQueueAverageWaitTime(Queue queue, Concept status) { - return dao.getQueueAverageWaitTime(queue, status, LocalDate.now()); - } } diff --git a/api/src/main/java/org/openmrs/module/queue/api/impl/RoomProviderMapServiceImpl.java b/api/src/main/java/org/openmrs/module/queue/api/impl/RoomProviderMapServiceImpl.java index 7c58e1e..4111607 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/impl/RoomProviderMapServiceImpl.java +++ b/api/src/main/java/org/openmrs/module/queue/api/impl/RoomProviderMapServiceImpl.java @@ -9,6 +9,7 @@ */ package org.openmrs.module.queue.api.impl; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Optional; @@ -16,13 +17,12 @@ import lombok.AccessLevel; import lombok.Setter; import lombok.extern.slf4j.Slf4j; -import org.openmrs.Provider; import org.openmrs.api.APIException; import org.openmrs.api.context.Context; import org.openmrs.api.impl.BaseOpenmrsService; import org.openmrs.module.queue.api.RoomProviderMapService; import org.openmrs.module.queue.api.dao.RoomProviderMapDao; -import org.openmrs.module.queue.model.QueueRoom; +import org.openmrs.module.queue.api.search.RoomProviderMapSearchCriteria; import org.openmrs.module.queue.model.RoomProviderMap; import org.springframework.transaction.annotation.Transactional; @@ -37,47 +37,54 @@ public void setDao(RoomProviderMapDao dao) { this.dao = dao; } + @Transactional(readOnly = true) @Override public Optional getRoomProviderMapByUuid(String uuid) { - return this.dao.get(uuid); + return dao.get(uuid); } + @Transactional(readOnly = true) @Override public Optional getRoomProviderMapById(int id) { - return this.dao.get(id); + return dao.get(id); } @Override - public RoomProviderMap createRoomProviderMap(RoomProviderMap roomProviderMap) { + public RoomProviderMap saveRoomProviderMap(RoomProviderMap roomProviderMap) { if (roomProviderMap.getId() == null) { - List existingAssignedRooms = getRoomProvider(roomProviderMap.getProvider(), - roomProviderMap.getQueueRoom()); - existingAssignedRooms.forEach(roomProviderMap1 -> voidRoomProviderMap(roomProviderMap1.getUuid(), "Api call")); - - return this.dao.createOrUpdate(roomProviderMap); + RoomProviderMapSearchCriteria criteria = new RoomProviderMapSearchCriteria(); + criteria.setProviders(Collections.singletonList(roomProviderMap.getProvider())); + criteria.setQueueRooms(Collections.singletonList(roomProviderMap.getQueueRoom())); + for (RoomProviderMap existingAssignedRoom : getRoomProviderMaps(criteria)) { + voidRoomProviderMap(existingAssignedRoom, "Api call"); + } } - roomProviderMap.setDateChanged(new Date()); - return this.dao.createOrUpdate(roomProviderMap); + return dao.createOrUpdate(roomProviderMap); } @Override - public List getRoomProvider(Provider provider, QueueRoom queueRoom) { - return this.dao.getRoomProvider(provider, queueRoom); + @Transactional(readOnly = true) + public List getAllRoomProviderMaps() { + return getRoomProviderMaps(new RoomProviderMapSearchCriteria()); } + @Transactional(readOnly = true) @Override - public void voidRoomProviderMap(String roomProviderMapUuid, String voidReason) { - this.dao.get(roomProviderMapUuid).ifPresent(obj -> { - obj.setVoided(true); - obj.setDateVoided(new Date()); - obj.setVoidReason(voidReason); - obj.setVoidedBy(Context.getAuthenticatedUser()); - this.dao.createOrUpdate(obj); - }); + public List getRoomProviderMaps(RoomProviderMapSearchCriteria searchCriteria) { + return dao.getRoomProviderMaps(searchCriteria); + } + + @Override + public void voidRoomProviderMap(RoomProviderMap roomProviderMap, String voidReason) { + roomProviderMap.setVoided(true); + roomProviderMap.setDateVoided(new Date()); + roomProviderMap.setVoidReason(voidReason); + roomProviderMap.setVoidedBy(Context.getAuthenticatedUser()); + dao.createOrUpdate(roomProviderMap); } @Override public void purgeRoomProviderMap(RoomProviderMap roomProviderMap) throws APIException { - this.dao.delete(roomProviderMap); + dao.delete(roomProviderMap); } } diff --git a/api/src/main/java/org/openmrs/module/queue/api/impl/VisitQueueEntryServiceImpl.java b/api/src/main/java/org/openmrs/module/queue/api/impl/VisitQueueEntryServiceImpl.java deleted file mode 100644 index e7fd498..0000000 --- a/api/src/main/java/org/openmrs/module/queue/api/impl/VisitQueueEntryServiceImpl.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.api.impl; - -import javax.validation.constraints.NotNull; - -import java.util.Collection; -import java.util.Date; -import java.util.Optional; -import java.util.stream.Collectors; - -import lombok.AccessLevel; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.openmrs.Patient; -import org.openmrs.Visit; -import org.openmrs.api.APIException; -import org.openmrs.api.ConceptNameType; -import org.openmrs.api.context.Context; -import org.openmrs.api.impl.BaseOpenmrsService; -import org.openmrs.module.queue.api.QueueEntryService; -import org.openmrs.module.queue.api.VisitQueueEntryService; -import org.openmrs.module.queue.api.dao.VisitQueueEntryDao; -import org.openmrs.module.queue.model.QueueEntry; -import org.openmrs.module.queue.model.VisitQueueEntry; -import org.springframework.transaction.annotation.Transactional; - -@Slf4j -@Transactional -@Setter(AccessLevel.MODULE) -public class VisitQueueEntryServiceImpl extends BaseOpenmrsService implements VisitQueueEntryService { - - private VisitQueueEntryDao dao; - - public void setDao(VisitQueueEntryDao dao) { - this.dao = dao; - } - - @Override - public Optional getVisitQueueEntryByUuid(@NotNull String uuid) { - return this.dao.get(uuid); - } - - @Override - public VisitQueueEntry createVisitQueueEntry(@NotNull VisitQueueEntry visitQueueEntry) { - //verify visit -patient & queue entry patient - //Todo more refactor - Visit visit = Context.getVisitService().getVisitByUuid(visitQueueEntry.getVisit().getUuid()); - Patient visitPatient = visit.getPatient(); - Patient queueEntryPatient = visitQueueEntry.getQueueEntry().getPatient(); - if (visitPatient != null & queueEntryPatient != null) { - boolean isPatientSame = visitPatient.getUuid().equals(queueEntryPatient.getUuid()); - if (!isPatientSame) { - throw new IllegalArgumentException("Patient mismatch - visit.patient does not match queueEntry.patient"); - } - QueueEntry newlyCreatedQueueEntry = Context.getService(QueueEntryService.class) - .createQueueEntry(visitQueueEntry.getQueueEntry()); - visitQueueEntry.setQueueEntry(newlyCreatedQueueEntry); - return this.dao.createOrUpdate(visitQueueEntry); - } - return null; - } - - /** - * @see VisitQueueEntryService#findAllVisitQueueEntries() - */ - @Override - public Collection findAllVisitQueueEntries() { - return dao.findAll(); - } - - @Override - public Collection getActiveVisitQueueEntries() { - Collection queueEntries = this.dao.findAll(false); - - //Remove inactive queue entries - //queueEntries.removeIf((vqe -> vqe.getQueueEntry().getEndedAt() != null)); - return queueEntries.stream().filter(visitQueueEntry -> visitQueueEntry.getQueueEntry().getEndedAt() == null) - .collect(Collectors.toList()); - } - - @Override - public Collection findVisitQueueEntries(String status, String service, String locationUuid, - String patientUuid) { - //Restrict to fully_specified concept names - return dao.findVisitQueueEntriesByConceptStatusAndConceptService(status, service, ConceptNameType.FULLY_SPECIFIED, - true, locationUuid, patientUuid); - } - - @Override - public void voidVisitQueueEntry(@NotNull String visitQueueEntryUuid, String voidReason) { - this.dao.get(visitQueueEntryUuid).ifPresent(visitQueueEntry -> { - visitQueueEntry.setVoided(true); - visitQueueEntry.setDateVoided(new Date()); - visitQueueEntry.setVoidReason(voidReason); - visitQueueEntry.setVoidedBy(Context.getAuthenticatedUser()); - this.dao.createOrUpdate(visitQueueEntry); - }); - } - - @Override - public void purgeQueueEntry(@NotNull VisitQueueEntry visitQueueEntry) throws APIException { - this.dao.delete(visitQueueEntry); - } - - /** - * @see VisitQueueEntryService#getVisitQueueEntriesCountByStatus(String) - */ - @Override - public Long getVisitQueueEntriesCountByStatus(String status) { - return dao.getVisitQueueEntriesCountByLocationStatusAndService(status, null, ConceptNameType.FULLY_SPECIFIED, true, - null); - } - - /** - * @see VisitQueueEntryService#getVisitQueueEntriesCountByService(String) - */ - @Override - public Long getVisitQueueEntriesCountByService(String service) { - return dao.getVisitQueueEntriesCountByLocationStatusAndService(null, service, ConceptNameType.FULLY_SPECIFIED, true, - null); - } - - /** - * @see VisitQueueEntryService#getVisitQueueEntriesCountByLocation(String) - */ - @Override - public Long getVisitQueueEntriesCountByLocation(String locaitonUuid) { - return dao.getVisitQueueEntriesCountByLocationStatusAndService(null, null, null, false, locaitonUuid); - } - - /** - * @see VisitQueueEntryService#getVisitQueueEntriesCountByLocationStatusAndService(String, String, - * String) - */ - @Override - public Long getVisitQueueEntriesCountByLocationStatusAndService(String status, String service, String locationUuid) { - return dao.getVisitQueueEntriesCountByLocationStatusAndService(status, service, ConceptNameType.FULLY_SPECIFIED, - true, locationUuid); - } -} diff --git a/api/src/main/java/org/openmrs/module/queue/api/search/QueueEntrySearchCriteria.java b/api/src/main/java/org/openmrs/module/queue/api/search/QueueEntrySearchCriteria.java new file mode 100644 index 0000000..db30fb1 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/queue/api/search/QueueEntrySearchCriteria.java @@ -0,0 +1,71 @@ +/* + * 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. + */ +package org.openmrs.module.queue.api.search; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Date; + +import lombok.Data; +import org.openmrs.Concept; +import org.openmrs.Location; +import org.openmrs.Patient; +import org.openmrs.Provider; +import org.openmrs.Visit; +import org.openmrs.module.queue.model.Queue; + +/** + * Bean definition used for retrieving Queue Entries that meet specific criteria All properties + * should be considered to further limit results (ANDed together) Any property that is null will not + * limit by the related property Any Collection that is empty will return only those results for + * which the related property is null Any Boolean property without a default value will not limit if + * the property is null For example, to not limit by priority, set the priority property to null To + * limit to only those entries whose priority is null, set the priority property to an empty + * collection + */ +@Data +public class QueueEntrySearchCriteria implements Serializable { + + private static final long serialVersionUID = 1L; + + private Collection queues; + + private Collection locations; + + private Collection services; + + private Patient patient; + + private Visit visit; + + private Boolean hasVisit; + + private Collection priorities; + + private Collection statuses; + + private Collection locationsWaitingFor; + + private Collection providersWaitingFor; + + private Collection queuesComingFrom; + + private Date startedOnOrAfter; + + private Date startedOnOrBefore; + + private Boolean isEnded = Boolean.FALSE; + + private Date endedOnOrAfter; + + private Date endedOnOrBefore; + + private boolean includedVoided = false; +} diff --git a/api/src/main/java/org/openmrs/module/queue/api/search/QueueRoomSearchCriteria.java b/api/src/main/java/org/openmrs/module/queue/api/search/QueueRoomSearchCriteria.java new file mode 100644 index 0000000..a7ae89b --- /dev/null +++ b/api/src/main/java/org/openmrs/module/queue/api/search/QueueRoomSearchCriteria.java @@ -0,0 +1,41 @@ +/* + * 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. + */ +package org.openmrs.module.queue.api.search; + +import java.io.Serializable; +import java.util.Collection; + +import lombok.Data; +import org.openmrs.Concept; +import org.openmrs.Location; +import org.openmrs.module.queue.model.Queue; + +/** + * Bean definition used for retrieving Queue Rooms that meet specific criteria All properties should + * be considered to further limit results (ANDed together) Any property that is null will not limit + * by the related property Any Collection that is empty will return only those results for which the + * related property is null Any Boolean property without a default value will not limit if the + * property is null For example, to not limit by priority, set the priority property to null To + * limit to only those entries whose priority is null, set the priority property to an empty + * collection + */ +@Data +public class QueueRoomSearchCriteria implements Serializable { + + private static final long serialVersionUID = 1L; + + private Collection queues; + + private Collection locations; + + private Collection services; + + private boolean includeRetired = false; +} diff --git a/api/src/main/java/org/openmrs/module/queue/api/search/QueueSearchCriteria.java b/api/src/main/java/org/openmrs/module/queue/api/search/QueueSearchCriteria.java new file mode 100644 index 0000000..d9623a6 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/queue/api/search/QueueSearchCriteria.java @@ -0,0 +1,38 @@ +/* + * 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. + */ +package org.openmrs.module.queue.api.search; + +import java.io.Serializable; +import java.util.Collection; + +import lombok.Data; +import org.openmrs.Concept; +import org.openmrs.Location; + +/** + * Bean definition used for retrieving Queues that meet specific criteria All properties should be + * considered to further limit results (ANDed together) Any property that is null will not limit by + * the related property Any Collection that is empty will return only those results for which the + * related property is null Any Boolean property without a default value will not limit if the + * property is null For example, to not limit by priority, set the priority property to null To + * limit to only those entries whose priority is null, set the priority property to an empty + * collection + */ +@Data +public class QueueSearchCriteria implements Serializable { + + private static final long serialVersionUID = 1L; + + private Collection locations; + + private Collection services; + + private boolean includeRetired = false; +} diff --git a/api/src/main/java/org/openmrs/module/queue/api/search/RoomProviderMapSearchCriteria.java b/api/src/main/java/org/openmrs/module/queue/api/search/RoomProviderMapSearchCriteria.java new file mode 100644 index 0000000..d868c72 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/queue/api/search/RoomProviderMapSearchCriteria.java @@ -0,0 +1,38 @@ +/* + * 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. + */ +package org.openmrs.module.queue.api.search; + +import java.io.Serializable; +import java.util.Collection; + +import lombok.Data; +import org.openmrs.Provider; +import org.openmrs.module.queue.model.QueueRoom; + +/** + * Bean definition used for retrieving RoomProviderMaps that meet specific criteria All properties + * should be considered to further limit results (ANDed together) Any property that is null will not + * limit by the related property Any Collection that is empty will return only those results for + * which the related property is null Any Boolean property without a default value will not limit if + * the property is null For example, to not limit by priority, set the priority property to null To + * limit to only those entries whose priority is null, set the priority property to an empty + * collection + */ +@Data +public class RoomProviderMapSearchCriteria implements Serializable { + + private static final long serialVersionUID = 1L; + + private Collection queueRooms; + + private Collection providers; + + private boolean includeVoided = false; +} diff --git a/api/src/main/java/org/openmrs/module/queue/exceptions/QueueException.java b/api/src/main/java/org/openmrs/module/queue/exceptions/QueueException.java deleted file mode 100644 index 6127760..0000000 --- a/api/src/main/java/org/openmrs/module/queue/exceptions/QueueException.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.exceptions; - -public class QueueException extends RuntimeException { - - private static final long serialVersionUID = 12345L; - - private final Throwable clothedThrowable; - - public QueueException(final String exceptionMessage) { - super(exceptionMessage); - clothedThrowable = null; - } - - /** - * @param exceptionMessage The message to register. - * @param clothedThrowable A throwable object that caused the Exception. - */ - public QueueException(final String exceptionMessage, final Throwable clothedThrowable) { - super(exceptionMessage, clothedThrowable); - this.clothedThrowable = clothedThrowable; - } - - /** - * @param clothedThrowable A throwable object that caused the Exception. - */ - public QueueException(final Throwable clothedThrowable) { - super(clothedThrowable); - this.clothedThrowable = clothedThrowable; - } - - /** - * returns the wrapped Throwable that caused this MethodInvocationException to be thrown - * - * @return Throwable thrown by method invocation - */ - public Throwable getWrappedThrowable() { - return clothedThrowable; - } -} diff --git a/api/src/main/java/org/openmrs/module/queue/model/QueueEntry.java b/api/src/main/java/org/openmrs/module/queue/model/QueueEntry.java index 074978d..d97a154 100644 --- a/api/src/main/java/org/openmrs/module/queue/model/QueueEntry.java +++ b/api/src/main/java/org/openmrs/module/queue/model/QueueEntry.java @@ -31,6 +31,7 @@ import org.openmrs.Location; import org.openmrs.Patient; import org.openmrs.Provider; +import org.openmrs.Visit; @EqualsAndHashCode(callSuper = true) @NoArgsConstructor @@ -57,6 +58,10 @@ public class QueueEntry extends BaseChangeableOpenmrsData { @JoinColumn(name = "patient_id", nullable = false) private Patient patient; + @ManyToOne + @JoinColumn(name = "visit_id") + private Visit visit; + @ManyToOne @JoinColumn(name = "priority", referencedColumnName = "concept_id", nullable = false) private Concept priority; diff --git a/api/src/main/java/org/openmrs/module/queue/model/VisitQueueEntry.java b/api/src/main/java/org/openmrs/module/queue/model/VisitQueueEntry.java deleted file mode 100644 index 67018d3..0000000 --- a/api/src/main/java/org/openmrs/module/queue/model/VisitQueueEntry.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.model; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.openmrs.BaseOpenmrsData; -import org.openmrs.Visit; - -@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true) -@Data -@Entity -@Table(name = "visit_queue_entries") -public class VisitQueueEntry extends BaseOpenmrsData { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - @Column(name = "visit_queue_entry_id") - private Integer id; - - @ManyToOne - @JoinColumn(name = "visit_id", nullable = false) - private Visit visit; - - @ManyToOne - @JoinColumn(name = "queue_entry_id", nullable = false) - private QueueEntry queueEntry; -} diff --git a/api/src/main/java/org/openmrs/module/queue/tasks/AutoCloseVisitQueueEntryTask.java b/api/src/main/java/org/openmrs/module/queue/tasks/AutoCloseVisitQueueEntryTask.java index a977949..aaa519b 100644 --- a/api/src/main/java/org/openmrs/module/queue/tasks/AutoCloseVisitQueueEntryTask.java +++ b/api/src/main/java/org/openmrs/module/queue/tasks/AutoCloseVisitQueueEntryTask.java @@ -9,16 +9,15 @@ */ package org.openmrs.module.queue.tasks; -import java.util.Collection; import java.util.Date; +import java.util.List; import lombok.extern.slf4j.Slf4j; import org.openmrs.Visit; import org.openmrs.api.context.Context; import org.openmrs.module.queue.api.QueueEntryService; -import org.openmrs.module.queue.api.VisitQueueEntryService; +import org.openmrs.module.queue.api.search.QueueEntrySearchCriteria; import org.openmrs.module.queue.model.QueueEntry; -import org.openmrs.module.queue.model.VisitQueueEntry; /** * This iterates over all active VisitQueueEntries If the Visit associated with any of these has @@ -39,19 +38,16 @@ public void run() { log.debug("Executing: " + getClass()); try { currentlyExecuting = true; - Collection queueEntries = getActiveVisitQueueEntries(); + List queueEntries = getActiveVisitQueueEntries(); log.debug("There are " + queueEntries.size() + " active visit queue entries"); - for (VisitQueueEntry visitQueueEntry : queueEntries) { - Visit visit = visitQueueEntry.getVisit(); - QueueEntry queueEntry = visitQueueEntry.getQueueEntry(); - if (visit != null) { - Date visitStopDatetime = visit.getStopDatetime(); - if (visitStopDatetime != null) { - log.debug("Visit " + visit.getVisitId() + " is closed at " + visitStopDatetime); - log.debug("Auto closing queue entry " + queueEntry.getQueueEntryId()); - queueEntry.setEndedAt(visitStopDatetime); - saveQueueEntry(queueEntry); - } + for (QueueEntry queueEntry : queueEntries) { + Visit visit = queueEntry.getVisit(); + Date visitStopDatetime = visit.getStopDatetime(); + if (visitStopDatetime != null) { + log.debug("Visit " + visit.getVisitId() + " is closed at " + visitStopDatetime); + log.debug("Auto closing queue entry " + queueEntry.getQueueEntryId()); + queueEntry.setEndedAt(visitStopDatetime); + saveQueueEntry(queueEntry); } } } @@ -63,8 +59,11 @@ public void run() { /** * @return the active VisitQueueEntries */ - protected Collection getActiveVisitQueueEntries() { - return Context.getService(VisitQueueEntryService.class).getActiveVisitQueueEntries(); + protected List getActiveVisitQueueEntries() { + QueueEntrySearchCriteria criteria = new QueueEntrySearchCriteria(); + criteria.setIsEnded(false); + criteria.setHasVisit(true); + return Context.getService(QueueEntryService.class).getQueueEntries(criteria); } /** @@ -72,6 +71,6 @@ protected Collection getActiveVisitQueueEntries() { * @return the saved QueueEntry */ protected void saveQueueEntry(QueueEntry queueEntry) { - Context.getService(QueueEntryService.class).createQueueEntry(queueEntry); + Context.getService(QueueEntryService.class).saveQueueEntry(queueEntry); } } diff --git a/api/src/main/java/org/openmrs/module/queue/utils/QueueUtils.java b/api/src/main/java/org/openmrs/module/queue/utils/QueueUtils.java new file mode 100644 index 0000000..d361fe5 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/queue/utils/QueueUtils.java @@ -0,0 +1,77 @@ +/* + * 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. + */ +package org.openmrs.module.queue.utils; + +import java.text.SimpleDateFormat; +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; +import java.util.List; + +import lombok.extern.slf4j.Slf4j; +import org.openmrs.module.queue.model.QueueEntry; + +/** + * Utility class for static methods useful within the Queue module + */ +@Slf4j +public class QueueUtils { + + /** + * Utility method for parsing a date from a string into a Date. TODO: This will need review and + * testing related to handling of timezones and other date formats + * + * @param dateVal the date value ot parse + * @return the resulting date object + */ + public static Date parseDate(String dateVal) { + try { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateVal); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * @param date the date to convert + * @return a LocalDateTime representation of the given date at the system timezone + */ + public static LocalDateTime convertToLocalDateTimeInSystemDefaultTimezone(Date date) { + if (date == null) { + return null; + } + return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); + } + + /** + * @param queueEntries the QueueEntries to check + * @return the average duration for the entries, in minutes, between startedAt and endedAt, where + * both are non-null + */ + public static double computeAverageWaitTimeInMinutes(List queueEntries) { + double averageWaitTime = 0.0; + if (queueEntries != null && !queueEntries.isEmpty()) { + double totalWaitTime = 0.0; + int numEntries = 0; + for (QueueEntry e : queueEntries) { + LocalDateTime startedAt = convertToLocalDateTimeInSystemDefaultTimezone(e.getStartedAt()); + LocalDateTime endedAt = convertToLocalDateTimeInSystemDefaultTimezone(e.getEndedAt()); + if (startedAt != null && endedAt != null) { + totalWaitTime += Duration.between(startedAt, endedAt).toMinutes(); + numEntries++; + } + } + averageWaitTime = totalWaitTime / numEntries; + } + return averageWaitTime; + } +} diff --git a/api/src/main/java/org/openmrs/module/queue/validators/VisitQueueEntryValidator.java b/api/src/main/java/org/openmrs/module/queue/validators/VisitQueueEntryValidator.java deleted file mode 100644 index 7e73806..0000000 --- a/api/src/main/java/org/openmrs/module/queue/validators/VisitQueueEntryValidator.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.validators; - -import org.openmrs.annotation.Handler; -import org.openmrs.module.queue.model.VisitQueueEntry; -import org.openmrs.module.queue.utils.QueueValidationUtils; -import org.springframework.validation.Errors; -import org.springframework.validation.ValidationUtils; -import org.springframework.validation.Validator; - -@Handler(supports = { VisitQueueEntry.class }, order = 50) -public class VisitQueueEntryValidator implements Validator { - - @Override - public boolean supports(Class clazz) { - return VisitQueueEntry.class.isAssignableFrom(clazz); - } - - @Override - public void validate(Object target, Errors errors) { - if (!(target instanceof VisitQueueEntry)) { - throw new IllegalArgumentException("the parameter target must be of type " + VisitQueueEntry.class); - } - //Reject null visit & queueEntry - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "visit", "visitQueueEntry.visit.null", - "The property visit should not be null"); - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "queueEntry", "visitQueueEntry.queueEntry.null", - "The property queueEntry should not be null"); - - VisitQueueEntry visitQueueEntry = (VisitQueueEntry) target; - QueueValidationUtils.validateQueueEntry(visitQueueEntry.getQueueEntry(), errors); - } -} diff --git a/api/src/main/resources/liquibase.xml b/api/src/main/resources/liquibase.xml index 8acb6c6..5ad1210 100644 --- a/api/src/main/resources/liquibase.xml +++ b/api/src/main/resources/liquibase.xml @@ -385,4 +385,37 @@ schedulable_class = 'org.openmrs.module.queue.tasks.AutoCloseQueueEntryTask' + + + + + + + + Add column visit_id to queue entry table + + + + + + + + + + + + + update queue_entry qe + inner join visit_queue_entries vqe on qe.queue_entry_id = vqe.queue_entry_id + set qe.visit_id = vqe.visit_id; + + + + + + + + + + diff --git a/api/src/main/resources/messages.properties b/api/src/main/resources/messages.properties deleted file mode 100644 index e31dee0..0000000 --- a/api/src/main/resources/messages.properties +++ /dev/null @@ -1,11 +0,0 @@ -# -# 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. -# - -queue.title=Queue diff --git a/api/src/main/resources/messages_es.properties b/api/src/main/resources/messages_es.properties deleted file mode 100644 index e31dee0..0000000 --- a/api/src/main/resources/messages_es.properties +++ /dev/null @@ -1,11 +0,0 @@ -# -# 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. -# - -queue.title=Queue diff --git a/api/src/main/resources/messages_fr.properties b/api/src/main/resources/messages_fr.properties deleted file mode 100644 index e31dee0..0000000 --- a/api/src/main/resources/messages_fr.properties +++ /dev/null @@ -1,11 +0,0 @@ -# -# 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. -# - -queue.title=Queue diff --git a/api/src/main/resources/moduleApplicationContext.xml b/api/src/main/resources/moduleApplicationContext.xml index 60ae554..441f902 100644 --- a/api/src/main/resources/moduleApplicationContext.xml +++ b/api/src/main/resources/moduleApplicationContext.xml @@ -50,6 +50,7 @@ + @@ -63,26 +64,6 @@ - - - - - - - - - - - - - - - org.openmrs.module.queue.api.VisitQueueEntryService - - - - @@ -127,9 +108,6 @@ - - - diff --git a/api/src/test/java/org/openmrs/module/queue/api/QueueEntryServiceTest.java b/api/src/test/java/org/openmrs/module/queue/api/QueueEntryServiceTest.java index 530f470..a658b48 100644 --- a/api/src/test/java/org/openmrs/module/queue/api/QueueEntryServiceTest.java +++ b/api/src/test/java/org/openmrs/module/queue/api/QueueEntryServiceTest.java @@ -10,9 +10,13 @@ package org.openmrs.module.queue.api; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Optional; @@ -20,13 +24,23 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.junit.MockitoJUnitRunner; import org.openmrs.Concept; -import org.openmrs.api.ConceptNameType; +import org.openmrs.Location; +import org.openmrs.User; +import org.openmrs.Visit; +import org.openmrs.VisitAttributeType; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; import org.openmrs.module.queue.api.dao.QueueEntryDao; import org.openmrs.module.queue.api.impl.QueueEntryServiceImpl; +import org.openmrs.module.queue.api.search.QueueEntrySearchCriteria; +import org.openmrs.module.queue.model.Queue; import org.openmrs.module.queue.model.QueueEntry; @RunWith(MockitoJUnitRunner.class) @@ -36,20 +50,23 @@ public class QueueEntryServiceTest { private static final Integer QUEUE_ENTRY_ID = 14; - private static final String QUEUE_ENTRY_STATUS = "Waiting for Service"; - - private static final String BAD_QUEUE_ENTRY_STATUS = "Waiting for Service"; - private QueueEntryServiceImpl queueEntryService; @Mock private QueueEntryDao dao; + @Mock + private VisitService visitService; + + @Captor + ArgumentCaptor queueEntrySearchCriteriaArgumentCaptor; + @Before public void setupMocks() { MockitoAnnotations.openMocks(this); queueEntryService = new QueueEntryServiceImpl(); queueEntryService.setDao(dao); + queueEntryService.setVisitService(visitService); } @Test @@ -85,7 +102,7 @@ public void shouldCreateNewQueueEntryRecord() { when(queueEntry.getPriority()).thenReturn(conceptPriority); when(dao.createOrUpdate(queueEntry)).thenReturn(queueEntry); - QueueEntry result = queueEntryService.createQueueEntry(queueEntry); + QueueEntry result = queueEntryService.saveQueueEntry(queueEntry); assertThat(result, notNullValue()); assertThat(result.getQueueEntryId(), is(QUEUE_ENTRY_ID)); assertThat(result.getStatus(), is(conceptStatus)); @@ -93,36 +110,59 @@ public void shouldCreateNewQueueEntryRecord() { } @Test - public void shouldVoidQueue() { - when(dao.get(QUEUE_ENTRY_UUID)).thenReturn(Optional.empty()); - - queueEntryService.voidQueueEntry(QUEUE_ENTRY_UUID, "voidReason"); - - assertThat(queueEntryService.getQueueEntryByUuid(QUEUE_ENTRY_UUID).isPresent(), is(false)); + public void shouldVoidQueueEntry() { + User user = new User(); + UserContext userContext = mock(UserContext.class); + when(userContext.getAuthenticatedUser()).thenReturn(user); + Context.setUserContext(userContext); + QueueEntry queueEntry = new QueueEntry(); + when(dao.createOrUpdate(queueEntry)).thenReturn(queueEntry); + assertThat(queueEntry.getVoided(), equalTo(false)); + assertThat(queueEntry.getDateVoided(), nullValue()); + assertThat(queueEntry.getVoidedBy(), nullValue()); + assertThat(queueEntry.getVoidReason(), nullValue()); + queueEntryService.voidQueueEntry(queueEntry, "voidReason"); + assertThat(queueEntry.getVoided(), equalTo(true)); + assertThat(queueEntry.getDateVoided(), notNullValue()); + assertThat(queueEntry.getVoidedBy(), equalTo(user)); + assertThat(queueEntry.getVoidReason(), equalTo("voidReason")); } @Test - public void shouldPurgeQueue() { + public void shouldPurgeQueueEntry() { QueueEntry queueEntry = mock(QueueEntry.class); when(dao.get(QUEUE_ENTRY_UUID)).thenReturn(Optional.empty()); - queueEntryService.purgeQueueEntry(queueEntry); assertThat(queueEntryService.getQueueEntryByUuid(QUEUE_ENTRY_UUID).isPresent(), is(false)); } @Test public void shouldReturnCountOfQueueEntriesByStatus() { - when(dao.getQueueEntriesCountByConceptStatus(QUEUE_ENTRY_STATUS, ConceptNameType.FULLY_SPECIFIED, false)) - .thenReturn(1L); - - assertThat(queueEntryService.getQueueEntriesCountByStatus(QUEUE_ENTRY_STATUS), is(1L)); + QueueEntrySearchCriteria criteria = new QueueEntrySearchCriteria(); + when(dao.getCountOfQueueEntries(criteria)).thenReturn(1L); + assertThat(queueEntryService.getCountOfQueueEntries(criteria), is(1L)); } @Test - public void shouldReturnZeroForBadGivenStatus() { - when(dao.getQueueEntriesCountByConceptStatus(BAD_QUEUE_ENTRY_STATUS, ConceptNameType.FULLY_SPECIFIED, false)) - .thenReturn(0L); - - assertThat(queueEntryService.getQueueEntriesCountByStatus(QUEUE_ENTRY_STATUS), is(0L)); + public void shouldGetQueuesEntriesByCriteria() { + QueueEntrySearchCriteria criteria = new QueueEntrySearchCriteria(); + queueEntryService.getQueueEntries(criteria); + verify(dao).getQueueEntries(queueEntrySearchCriteriaArgumentCaptor.capture()); + QueueEntrySearchCriteria daoCriteria = queueEntrySearchCriteriaArgumentCaptor.getValue(); + assertThat(daoCriteria, equalTo(criteria)); + } + + @Test + public void shouldGenerateVisitQueueNumber() { + Visit visit = new Visit(); + Location location = new Location(); + Queue queue = new Queue(); + queue.setName("Consultation Queue"); + VisitAttributeType visitAttributeType = new VisitAttributeType(); + when(visitService.saveVisit(visit)).thenReturn(visit); + when(queueEntryService.getCountOfQueueEntries(any())).thenReturn(52L); + String queueNumber = queueEntryService.generateVisitQueueNumber(location, queue, visit, visitAttributeType); + assertThat(queueNumber, notNullValue()); + assertThat(queueNumber, equalTo("CON-053")); } } diff --git a/api/src/test/java/org/openmrs/module/queue/api/QueueRoomServiceTest.java b/api/src/test/java/org/openmrs/module/queue/api/QueueRoomServiceTest.java index fc80791..87765a9 100644 --- a/api/src/test/java/org/openmrs/module/queue/api/QueueRoomServiceTest.java +++ b/api/src/test/java/org/openmrs/module/queue/api/QueueRoomServiceTest.java @@ -10,26 +10,30 @@ package org.openmrs.module.queue.api; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.Collections; -import java.util.List; import java.util.Optional; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.junit.MockitoJUnitRunner; -import org.openmrs.Location; +import org.openmrs.User; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; import org.openmrs.module.queue.api.dao.QueueRoomDao; import org.openmrs.module.queue.api.impl.QueueRoomServiceImpl; -import org.openmrs.module.queue.model.Queue; +import org.openmrs.module.queue.api.search.QueueRoomSearchCriteria; import org.openmrs.module.queue.model.QueueRoom; @RunWith(MockitoJUnitRunner.class) @@ -48,6 +52,9 @@ public class QueueRoomServiceTest { @Mock private QueueRoomDao dao; + @Captor + ArgumentCaptor queueRoomSearchCriteriaArgumentCaptor; + @Before public void setupMocks() { MockitoAnnotations.openMocks(this); @@ -67,57 +74,51 @@ public void shouldGetByUuid() { } @Test - public void shouldCreateNewQueue() { + public void shouldCreateNewQueueRoom() { QueueRoom queueRoom = mock(QueueRoom.class); when(queueRoom.getUuid()).thenReturn(QUEUE_ROOM_UUID); when(queueRoom.getName()).thenReturn(QUEUE_ROOM_NAME); when(dao.createOrUpdate(queueRoom)).thenReturn(queueRoom); - QueueRoom result = queueRoomService.createQueueRoom(queueRoom); + QueueRoom result = queueRoomService.saveQueueRoom(queueRoom); assertThat(result, notNullValue()); assertThat(result.getUuid(), is(QUEUE_ROOM_UUID)); assertThat(result.getName(), is(QUEUE_ROOM_NAME)); } @Test - public void shouldVoidQueue() { - when(dao.get(QUEUE_ROOM_UUID)).thenReturn(Optional.empty()); - - queueRoomService.voidQueueRoom(QUEUE_ROOM_UUID, "API Call"); - - assertThat(queueRoomService.getQueueRoomByUuid(QUEUE_ROOM_UUID).isPresent(), is(false)); + public void shouldRetireQueueRoom() { + User user = new User(); + UserContext userContext = mock(UserContext.class); + when(userContext.getAuthenticatedUser()).thenReturn(user); + Context.setUserContext(userContext); + QueueRoom queueRoom = new QueueRoom(); + when(dao.createOrUpdate(queueRoom)).thenReturn(queueRoom); + assertThat(queueRoom.getRetired(), equalTo(false)); + assertThat(queueRoom.getDateRetired(), nullValue()); + assertThat(queueRoom.getRetiredBy(), nullValue()); + assertThat(queueRoom.getRetireReason(), nullValue()); + queueRoomService.retireQueueRoom(queueRoom, "retireReason"); + assertThat(queueRoom.getRetired(), equalTo(true)); + assertThat(queueRoom.getDateRetired(), notNullValue()); + assertThat(queueRoom.getRetiredBy(), equalTo(user)); + assertThat(queueRoom.getRetireReason(), equalTo("retireReason")); } @Test - public void shouldPurgeQueue() { + public void shouldPurgeQueueRoom() { QueueRoom queueRoom = mock(QueueRoom.class); when(dao.get(QUEUE_ROOM_UUID)).thenReturn(Optional.empty()); - queueRoomService.purgeQueueRoom(queueRoom); assertThat(queueRoomService.getQueueRoomByUuid(QUEUE_ROOM_UUID).isPresent(), is(false)); } @Test - public void shouldGetAllQueueRoomsByLocation() { - QueueRoom queueRoom = mock(QueueRoom.class); - Location location = new Location(); - location.setUuid(LOCATION_UUID); - when(dao.getQueueRoomsByServiceAndLocation(null, location)).thenReturn(Collections.singletonList(queueRoom)); - - List queueRoomsByLocation = queueRoomService.getQueueRoomsByServiceAndLocation(null, location); - assertThat(queueRoomsByLocation, notNullValue()); - assertThat(queueRoomsByLocation, hasSize(1)); - } - - @Test - public void shouldGetAllQueueRoomsByQueue() { - QueueRoom queueRoom = mock(QueueRoom.class); - Queue queue = new Queue(); - queue.setUuid(QUEUE_UUID); - when(dao.getQueueRoomsByServiceAndLocation(queue, null)).thenReturn(Collections.singletonList(queueRoom)); - - List queueRoomsByLocation = queueRoomService.getQueueRoomsByServiceAndLocation(queue, null); - assertThat(queueRoomsByLocation, notNullValue()); - assertThat(queueRoomsByLocation, hasSize(1)); + public void shouldGetQueueRoomsByCriteria() { + QueueRoomSearchCriteria criteria = new QueueRoomSearchCriteria(); + queueRoomService.getQueueRooms(criteria); + verify(dao).getQueueRooms(queueRoomSearchCriteriaArgumentCaptor.capture()); + QueueRoomSearchCriteria daoCriteria = queueRoomSearchCriteriaArgumentCaptor.getValue(); + assertThat(daoCriteria, equalTo(criteria)); } } diff --git a/api/src/test/java/org/openmrs/module/queue/api/QueueServiceTest.java b/api/src/test/java/org/openmrs/module/queue/api/QueueServiceTest.java index b2bc31e..ded4247 100644 --- a/api/src/test/java/org/openmrs/module/queue/api/QueueServiceTest.java +++ b/api/src/test/java/org/openmrs/module/queue/api/QueueServiceTest.java @@ -10,24 +10,35 @@ package org.openmrs.module.queue.api; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.Collections; +import java.util.Arrays; import java.util.List; import java.util.Optional; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.junit.MockitoJUnitRunner; +import org.openmrs.Concept; +import org.openmrs.Location; +import org.openmrs.User; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; import org.openmrs.module.queue.api.dao.QueueDao; import org.openmrs.module.queue.api.impl.QueueServiceImpl; +import org.openmrs.module.queue.api.search.QueueSearchCriteria; import org.openmrs.module.queue.model.Queue; @RunWith(MockitoJUnitRunner.class) @@ -39,12 +50,16 @@ public class QueueServiceTest { private static final Integer QUEUE_ID = 123; - private static final String LOCATION_UUID = "h6f6bb90-86f4-4d9c-8b6c-3713d748ef89"; - private QueueServiceImpl queueService; @Mock - private QueueDao dao; + private QueueDao dao; + + @Captor + ArgumentCaptor queueArgumentCaptor; + + @Captor + ArgumentCaptor queueSearchCriteriaArgumentCaptor; @Before public void setupMocks() { @@ -58,7 +73,6 @@ public void shouldGetByUuid() { Queue queue = mock(Queue.class); when(queue.getUuid()).thenReturn(QUEUE_UUID); when(dao.get(QUEUE_UUID)).thenReturn(Optional.of(queue)); - Optional result = queueService.getQueueByUuid(QUEUE_UUID); assertThat(result.isPresent(), is(true)); result.ifPresent(q -> assertThat(q.getUuid(), is(QUEUE_UUID))); @@ -69,7 +83,6 @@ public void shouldGetById() { Queue queue = mock(Queue.class); when(queue.getId()).thenReturn(QUEUE_ID); when(dao.get(QUEUE_ID)).thenReturn(Optional.of(queue)); - Optional result = queueService.getQueueById(QUEUE_ID); assertThat(result.isPresent(), is(true)); result.ifPresent(q -> assertThat(q.getId(), is(QUEUE_ID))); @@ -81,38 +94,56 @@ public void shouldCreateNewQueue() { when(queue.getUuid()).thenReturn(QUEUE_UUID); when(queue.getName()).thenReturn(QUEUE_NAME); when(dao.createOrUpdate(queue)).thenReturn(queue); - - Queue result = queueService.createQueue(queue); + Queue result = queueService.saveQueue(queue); assertThat(result, notNullValue()); assertThat(result.getUuid(), is(QUEUE_UUID)); assertThat(result.getName(), is(QUEUE_NAME)); } @Test - public void shouldVoidQueue() { - when(dao.get(QUEUE_UUID)).thenReturn(Optional.empty()); - - queueService.voidQueue(QUEUE_UUID, "voidReason"); - - assertThat(queueService.getQueueByUuid(QUEUE_UUID).isPresent(), is(false)); + public void shouldRetireQueue() { + User user = new User(); + UserContext userContext = mock(UserContext.class); + when(userContext.getAuthenticatedUser()).thenReturn(user); + Context.setUserContext(userContext); + Queue queue = new Queue(); + when(dao.createOrUpdate(queue)).thenReturn(queue); + assertThat(queue.getRetired(), equalTo(false)); + assertThat(queue.getDateRetired(), nullValue()); + assertThat(queue.getRetiredBy(), nullValue()); + assertThat(queue.getRetireReason(), nullValue()); + queueService.retireQueue(queue, "retireReason"); + assertThat(queue.getRetired(), equalTo(true)); + assertThat(queue.getDateRetired(), notNullValue()); + assertThat(queue.getRetiredBy(), equalTo(user)); + assertThat(queue.getRetireReason(), equalTo("retireReason")); } @Test public void shouldPurgeQueue() { - Queue queue = mock(Queue.class); - when(dao.get(QUEUE_UUID)).thenReturn(Optional.empty()); - + Queue queue = new Queue(); queueService.purgeQueue(queue); - assertThat(queueService.getQueueByUuid(QUEUE_UUID).isPresent(), is(false)); + verify(dao).delete(queueArgumentCaptor.capture()); + assertThat(queueArgumentCaptor.getValue(), equalTo(queue)); } @Test - public void shouldGetAllQueuesByLocation() { - Queue queue = mock(Queue.class); - when(dao.getAllQueuesByLocation(LOCATION_UUID)).thenReturn(Collections.singletonList(queue)); - - List queuesByLocation = queueService.getAllQueuesByLocation(LOCATION_UUID); - assertThat(queuesByLocation, notNullValue()); - assertThat(queuesByLocation, hasSize(1)); + public void shouldGetAllQueuesByCriteria() { + Concept concept1 = new Concept(); + Concept concept2 = new Concept(); + Location location1 = new Location(); + Location location2 = new Location(); + List services = Arrays.asList(concept1, concept2); + List locations = Arrays.asList(location1, location2); + QueueSearchCriteria criteria = new QueueSearchCriteria(); + criteria.setServices(services); + criteria.setLocations(locations); + criteria.setIncludeRetired(true); + queueService.getQueues(criteria); + verify(dao).getQueues(queueSearchCriteriaArgumentCaptor.capture()); + QueueSearchCriteria daoCriteria = queueSearchCriteriaArgumentCaptor.getValue(); + assertThat(daoCriteria.getServices(), contains(concept1, concept2)); + assertThat(daoCriteria.getLocations(), contains(location1, location2)); + assertThat(daoCriteria.isIncludeRetired(), equalTo(true)); } } diff --git a/api/src/test/java/org/openmrs/module/queue/api/RoomProviderMapServiceTest.java b/api/src/test/java/org/openmrs/module/queue/api/RoomProviderMapServiceTest.java index bc855c8..1851824 100644 --- a/api/src/test/java/org/openmrs/module/queue/api/RoomProviderMapServiceTest.java +++ b/api/src/test/java/org/openmrs/module/queue/api/RoomProviderMapServiceTest.java @@ -10,26 +10,30 @@ package org.openmrs.module.queue.api; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.Collections; -import java.util.List; import java.util.Optional; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.junit.MockitoJUnitRunner; -import org.openmrs.Provider; +import org.openmrs.User; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; import org.openmrs.module.queue.api.dao.RoomProviderMapDao; import org.openmrs.module.queue.api.impl.RoomProviderMapServiceImpl; -import org.openmrs.module.queue.model.QueueRoom; +import org.openmrs.module.queue.api.search.RoomProviderMapSearchCriteria; import org.openmrs.module.queue.model.RoomProviderMap; @RunWith(MockitoJUnitRunner.class) @@ -46,6 +50,9 @@ public class RoomProviderMapServiceTest { @Mock private RoomProviderMapDao dao; + @Captor + ArgumentCaptor roomProviderMapSearchCriteriaArgumentCaptor; + @Before public void setupMocks() { MockitoAnnotations.openMocks(this); @@ -70,18 +77,28 @@ public void shouldCreateNewRoomProviderMap() { when(roomProviderMap.getUuid()).thenReturn(ROOM_PROVIDER_MAP_UUID); when(dao.createOrUpdate(roomProviderMap)).thenReturn(roomProviderMap); - RoomProviderMap result = roomProviderMapService.createRoomProviderMap(roomProviderMap); + RoomProviderMap result = roomProviderMapService.saveRoomProviderMap(roomProviderMap); assertThat(result, notNullValue()); assertThat(result.getUuid(), is(ROOM_PROVIDER_MAP_UUID)); } @Test public void shouldVoidRoomProviderMap() { - when(dao.get(ROOM_PROVIDER_MAP_UUID)).thenReturn(Optional.empty()); - - roomProviderMapService.voidRoomProviderMap(ROOM_PROVIDER_MAP_UUID, "API Call"); - - assertThat(roomProviderMapService.getRoomProviderMapByUuid(ROOM_PROVIDER_MAP_UUID).isPresent(), is(false)); + User user = new User(); + UserContext userContext = mock(UserContext.class); + when(userContext.getAuthenticatedUser()).thenReturn(user); + Context.setUserContext(userContext); + RoomProviderMap roomProviderMap = new RoomProviderMap(); + when(dao.createOrUpdate(roomProviderMap)).thenReturn(roomProviderMap); + assertThat(roomProviderMap.getVoided(), equalTo(false)); + assertThat(roomProviderMap.getDateVoided(), nullValue()); + assertThat(roomProviderMap.getVoidedBy(), nullValue()); + assertThat(roomProviderMap.getVoidReason(), nullValue()); + roomProviderMapService.voidRoomProviderMap(roomProviderMap, "voidReason"); + assertThat(roomProviderMap.getVoided(), equalTo(true)); + assertThat(roomProviderMap.getDateVoided(), notNullValue()); + assertThat(roomProviderMap.getVoidedBy(), equalTo(user)); + assertThat(roomProviderMap.getVoidReason(), equalTo("voidReason")); } @Test @@ -94,26 +111,11 @@ public void shouldPurgeRoomProviderMap() { } @Test - public void shouldGetAllRoomProviderMapByProvider() { - RoomProviderMap roomProviderMap = mock(RoomProviderMap.class); - Provider provider = new Provider(); - provider.setUuid(PROVIDER_UUID); - when(dao.getRoomProvider(provider, null)).thenReturn(Collections.singletonList(roomProviderMap)); - - List result = roomProviderMapService.getRoomProvider(provider, null); - assertThat(result, notNullValue()); - assertThat(result, hasSize(1)); - } - - @Test - public void shouldGetAllRoomProviderMapByQueueRoom() { - QueueRoom queueRoom = new QueueRoom(); - queueRoom.setUuid(QUEUE_ROOM_UUID); - RoomProviderMap roomProviderMap = mock(RoomProviderMap.class); - when(dao.getRoomProvider(null, queueRoom)).thenReturn(Collections.singletonList(roomProviderMap)); - - List result = roomProviderMapService.getRoomProvider(null, queueRoom); - assertThat(result, notNullValue()); - assertThat(result, hasSize(1)); + public void shouldGetRoomProviderMapsByCriteria() { + RoomProviderMapSearchCriteria criteria = new RoomProviderMapSearchCriteria(); + roomProviderMapService.getRoomProviderMaps(criteria); + verify(dao).getRoomProviderMaps(roomProviderMapSearchCriteriaArgumentCaptor.capture()); + RoomProviderMapSearchCriteria daoCriteria = roomProviderMapSearchCriteriaArgumentCaptor.getValue(); + assertThat(daoCriteria, equalTo(criteria)); } } diff --git a/api/src/test/java/org/openmrs/module/queue/api/VisitQueueEntryServiceTest.java b/api/src/test/java/org/openmrs/module/queue/api/VisitQueueEntryServiceTest.java deleted file mode 100644 index 7a07896..0000000 --- a/api/src/test/java/org/openmrs/module/queue/api/VisitQueueEntryServiceTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.api; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.Optional; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.junit.MockitoJUnitRunner; -import org.openmrs.Visit; -import org.openmrs.module.queue.api.dao.VisitQueueEntryDao; -import org.openmrs.module.queue.api.impl.VisitQueueEntryServiceImpl; -import org.openmrs.module.queue.model.QueueEntry; -import org.openmrs.module.queue.model.VisitQueueEntry; - -@RunWith(MockitoJUnitRunner.class) -public class VisitQueueEntryServiceTest { - - private static final String VISIT_QUEUE_ENTRY_UUID = "j8f0bb90-86f4-4d9c-8b6c-3713d748ef74"; - - private VisitQueueEntryServiceImpl visitQueueEntryService; - - @Mock - private VisitQueueEntryDao dao; - - @Before - public void setupMocks() { - MockitoAnnotations.openMocks(this); - visitQueueEntryService = new VisitQueueEntryServiceImpl(); - visitQueueEntryService.setDao(dao); - } - - @Test - public void shouldGetVisitQueueEntryByUuid() { - VisitQueueEntry visitQueueEntry = mock(VisitQueueEntry.class); - when(visitQueueEntry.getUuid()).thenReturn(VISIT_QUEUE_ENTRY_UUID); - when(dao.get(VISIT_QUEUE_ENTRY_UUID)).thenReturn(Optional.of(visitQueueEntry)); - - Optional result = visitQueueEntryService.getVisitQueueEntryByUuid(VISIT_QUEUE_ENTRY_UUID); - assertThat(result.isPresent(), is(true)); - result.ifPresent(q -> assertThat(q.getUuid(), is(VISIT_QUEUE_ENTRY_UUID))); - } - - @Test - public void shouldCreateNewRecordForVisitQueueEntry() { - VisitQueueEntry visitQueueEntry = mock(VisitQueueEntry.class); - Visit visit = mock(Visit.class); - QueueEntry queueEntry = mock(QueueEntry.class); - - when(visitQueueEntry.getQueueEntry()).thenReturn(queueEntry); - when(visitQueueEntry.getVisit()).thenReturn(visit); - when(dao.createOrUpdate(visitQueueEntry)).thenReturn(visitQueueEntry); - - VisitQueueEntry result = this.dao.createOrUpdate(visitQueueEntry); - assertThat(result, notNullValue()); - assertThat(result.getVisit(), is(visit)); - assertThat(result.getQueueEntry(), is(queueEntry)); - - } - - @Test - public void shouldVoidVisitQueueEntryRecord() { - when(dao.get(VISIT_QUEUE_ENTRY_UUID)).thenReturn(Optional.empty()); - - visitQueueEntryService.voidVisitQueueEntry(VISIT_QUEUE_ENTRY_UUID, "voidReason"); - - assertThat(visitQueueEntryService.getVisitQueueEntryByUuid(VISIT_QUEUE_ENTRY_UUID).isPresent(), is(false)); - } - -} diff --git a/api/src/test/java/org/openmrs/module/queue/api/dao/QueueDaoTest.java b/api/src/test/java/org/openmrs/module/queue/api/dao/QueueDaoTest.java index a67101f..a626d22 100644 --- a/api/src/test/java/org/openmrs/module/queue/api/dao/QueueDaoTest.java +++ b/api/src/test/java/org/openmrs/module/queue/api/dao/QueueDaoTest.java @@ -16,13 +16,18 @@ import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Optional; import org.junit.Before; import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.Location; import org.openmrs.api.context.Context; import org.openmrs.module.queue.SpringTestConfiguration; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.QueueSearchCriteria; import org.openmrs.module.queue.model.Queue; import org.openmrs.test.BaseModuleContextSensitiveTest; import org.springframework.beans.factory.annotation.Autowired; @@ -49,27 +54,26 @@ public class QueueDaoTest extends BaseModuleContextSensitiveTest { private static final String NEW_QUEUE_LOCATION_UUID = "d0938432-1691-11df-97a5-7038c098"; - private static final String LOCATION_UUID = "d0938432-1691-11df-97a5-7038c098"; - private static final String CONCEPT_UUID = "67b910bd-298c-4ecf-a632-661ae2f446op"; - private static final String QUEUE_UUID_WAIT_TIME = "5ob7fe43-2813-4kbc-80dc-2e5d30252bb3"; - - private static final String CONCEPT_UUID_WAIT_TIME = "56b910bd-298c-4ecf-a632-661ae2f7865y"; - @Autowired @Qualifier("queueDao") - private QueueDao dao; + private QueueDao dao; + + @Autowired + private QueueServicesWrapper services; + + private QueueSearchCriteria criteria; @Before public void setup() { QUEUE_INITIAL_DATASET_XML.forEach(this::executeDataSet); + criteria = new QueueSearchCriteria(); } @Test public void shouldGetQueueByUuid() { Optional queue = dao.get(QUEUE_UUID); - assertThat(queue, notNullValue()); assertThat(queue.isPresent(), is(true)); queue.ifPresent(queue1 -> assertThat(queue1.getUuid(), is(QUEUE_UUID))); @@ -139,37 +143,65 @@ public void shouldFindAllQueuesIncludingRetired() { @Test public void shouldDeleteQueueByUuid() { dao.delete(QUEUE_UUID); - Optional result = dao.get(QUEUE_UUID); - //verify delete operation assertThat(result.isPresent(), is(false)); } @Test public void shouldDeleteQueueByEntity() { dao.get(QUEUE_UUID).ifPresent((queue) -> dao.delete(queue)); - Optional result = dao.get(QUEUE_UUID); - //verify delete operation assertThat(result.isPresent(), is(false)); } @Test - public void shouldFindQueuesByLocation() { - List queuesByLocation = dao.getAllQueuesByLocation(LOCATION_UUID); - - assertThat(queuesByLocation, notNullValue()); - assertThat(queuesByLocation, hasSize(3)); - queuesByLocation.forEach(queue -> assertThat(queue.getLocation().getUuid(), is(LOCATION_UUID))); + public void shouldGetQueuesByLocation() { + Location location1 = services.getLocationService().getLocation(1); + Location location3 = services.getLocationService().getLocation(3); + assertResults(criteria, 1, 3, 4); + criteria.setLocations(Collections.emptyList()); + assertResults(criteria); + criteria.setLocations(Collections.singletonList(location1)); + assertResults(criteria, 1, 4); + criteria.setLocations(Collections.singletonList(location3)); + assertResults(criteria, 3); + criteria.setLocations(Arrays.asList(location1, location3)); + assertResults(criteria, 1, 3, 4); } @Test - public void shouldFindAllQueuesIncludingRetiredByLocation() { - List queuesByLocation = dao.getAllQueuesByLocation(LOCATION_UUID, true); - - assertThat(queuesByLocation, notNullValue()); - assertThat(queuesByLocation, hasSize(4)); - queuesByLocation.forEach(queue -> assertThat(queue.getLocation().getUuid(), is(LOCATION_UUID))); + public void shouldGetQueuesByService() { + Concept concept1 = services.getConceptService().getConcept(2001); + Concept concept2 = services.getConceptService().getConcept(2002); + assertResults(criteria, 1, 3, 4); + criteria.setServices(Collections.emptyList()); + assertResults(criteria); + criteria.setServices(Collections.singletonList(concept1)); + assertResults(criteria, 1); + criteria.setServices(Collections.singletonList(concept2)); + assertResults(criteria, 3, 4); + criteria.setServices(Arrays.asList(concept1, concept2)); + assertResults(criteria, 1, 3, 4); } + @Test + public void shouldGetQueuesByIncludeRetired() { + assertResults(criteria, 1, 3, 4); + criteria.setIncludeRetired(true); + assertResults(criteria, 1, 2, 3, 4); + } + + /** + * Utility method that tests criteria against both DAO methods to getQueueEntries and + * getCountOfQueueEntries + */ + private void assertResults(QueueSearchCriteria criteria, Integer... queueIds) { + List queues = dao.getQueues(criteria); + assertThat(queues, hasSize(queueIds.length)); + for (Integer queueId : queueIds) { + Queue expected = dao.get(queueId).orElse(null); + assertThat(expected, notNullValue()); + assertThat(queues.contains(expected), is(true)); + } + } } diff --git a/api/src/test/java/org/openmrs/module/queue/api/dao/QueueEntryDaoTest.java b/api/src/test/java/org/openmrs/module/queue/api/dao/QueueEntryDaoTest.java index 557a071..bbbdbb9 100644 --- a/api/src/test/java/org/openmrs/module/queue/api/dao/QueueEntryDaoTest.java +++ b/api/src/test/java/org/openmrs/module/queue/api/dao/QueueEntryDaoTest.java @@ -18,6 +18,7 @@ import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Optional; @@ -27,12 +28,15 @@ import org.openmrs.Concept; import org.openmrs.Location; import org.openmrs.Patient; -import org.openmrs.api.ConceptNameType; +import org.openmrs.Provider; +import org.openmrs.Visit; import org.openmrs.api.context.Context; import org.openmrs.module.queue.SpringTestConfiguration; -import org.openmrs.module.queue.api.QueueEntryService; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.QueueEntrySearchCriteria; import org.openmrs.module.queue.model.Queue; import org.openmrs.module.queue.model.QueueEntry; +import org.openmrs.module.queue.utils.QueueUtils; import org.openmrs.test.BaseModuleContextSensitiveTest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -58,27 +62,25 @@ public class QueueEntryDaoTest extends BaseModuleContextSensitiveTest { private static final List QUEUE_INITIAL_DATASET_XML = Arrays.asList( "org/openmrs/module/queue/api/dao/QueueDaoTest_locationInitialDataset.xml", "org/openmrs/module/queue/api/dao/QueueEntryDaoTest_conceptsInitialDataset.xml", - "org/openmrs/module/queue/api/dao/QueueDaoTest_initialDataset.xml", "org/openmrs/module/queue/api/dao/QueueEntryDaoTest_patientInitialDataset.xml", - "org/openmrs/module/queue/api/dao/QueueEntryDaoTest_initialDataset.xml", "org/openmrs/module/queue/api/dao/VisitQueueEntryDaoTest_visitInitialDataset.xml", - "org/openmrs/module/queue/api/dao/visitQueueEntryDaoTest_visitQueueNumberInitialDataset.xml"); - - private static final String QUEUE_ENTRY_STATUS = "Waiting for service"; - - private static final String BAD_QUEUE_ENTRY_STATUS = "Bad Waiting for service"; + "org/openmrs/module/queue/api/dao/QueueDaoTest_initialDataset.xml", + "org/openmrs/module/queue/api/dao/QueueEntryDaoTest_initialDataset.xml"); @Autowired @Qualifier("queueEntryDao") private QueueEntryDao dao; @Autowired - @Qualifier("queueDao") - private QueueDao queueDao; + private QueueServicesWrapper services; + + private QueueEntrySearchCriteria criteria; @Before public void setup() { QUEUE_INITIAL_DATASET_XML.forEach(this::executeDataSet); + criteria = new QueueEntrySearchCriteria(); + criteria.setIsEnded(null); } @Test @@ -99,7 +101,7 @@ public void shouldReturnNullForRetiredQueueEntry() { @Test public void shouldCreateNewQueueEntry() { //Verify queue created - Optional optionalQueue = queueDao.get(QUEUE_UUID); + Optional optionalQueue = services.getQueueService().getQueueByUuid(QUEUE_UUID); assertThat(optionalQueue.isPresent(), is(true)); QueueEntry queueEntry = new QueueEntry(); @@ -152,31 +154,27 @@ public void shouldUpdateQueueEntry() { public void shouldFindAllQueueEntries() { Collection queues = dao.findAll(); assertThat(queues.isEmpty(), is(false)); - assertThat(queues, hasSize(2)); + assertThat(queues, hasSize(4)); } @Test public void shouldFindAllQueueEntriesIncludingRetired() { Collection queues = dao.findAll(true); assertThat(queues.isEmpty(), is(false)); - assertThat(queues, hasSize(3)); + assertThat(queues, hasSize(5)); } @Test public void shouldDeleteQueueEntryByUuid() { dao.delete(QUEUE_ENTRY_UUID); - Optional result = dao.get(QUEUE_ENTRY_UUID); - //verify delete operation assertThat(result.isPresent(), is(false)); } @Test public void shouldDeleteQueueEntryByEntity() { dao.get(QUEUE_ENTRY_UUID).ifPresent((queueEntry) -> dao.delete(queueEntry)); - Optional result = dao.get(QUEUE_ENTRY_UUID); - //verify delete operation assertThat(result.isPresent(), is(false)); } @@ -202,58 +200,264 @@ void verifyQueueEntryConceptPriorityProperty(QueueEntry queueEntry) { } @Test - public void shouldSearchQueueEntriesByStatus() { - Collection queueEntries = dao.SearchQueueEntriesByConceptStatus(QUEUE_ENTRY_STATUS, - ConceptNameType.FULLY_SPECIFIED, false, false); - - assertThat(queueEntries.isEmpty(), is(false)); - assertThat(queueEntries, hasSize(1)); - queueEntries.forEach(queueEntry -> { - assertThat(queueEntry.getStatus(), notNullValue()); - assertThat(queueEntry.getStatus().getName().getName(), is(QUEUE_ENTRY_STATUS)); - }); + public void shouldSearchAndCountQueueEntriesByQueue() { + Queue queue1 = services.getQueueService().getQueueById(1).orElse(null); + Queue queue2 = services.getQueueService().getQueueById(2).orElse(null); + Queue queue3 = services.getQueueService().getQueueById(3).orElse(null); + assertNumberOfResults(criteria, 4); + criteria.setQueues(Collections.emptyList()); + assertNumberOfResults(criteria, 0); + criteria.setQueues(Collections.singletonList(queue1)); + assertResults(criteria, 1); + criteria.setQueues(Collections.singletonList(queue2)); + assertResults(criteria, 2); + criteria.setQueues(Collections.singletonList(queue3)); + assertResults(criteria, 3, 4); + criteria.setQueues(Arrays.asList(queue2, queue3)); + assertResults(criteria, 2, 3, 4); + criteria.setIncludedVoided(true); + assertResults(criteria, 2, 3, 4, 10); } @Test - public void shouldSearchQueueEntriesByStatusIncludingVoidedQueueEntries() { - Collection queueEntries = dao.SearchQueueEntriesByConceptStatus(QUEUE_ENTRY_STATUS, - ConceptNameType.FULLY_SPECIFIED, false, true); - - assertThat(queueEntries.isEmpty(), is(false)); - assertThat(queueEntries, hasSize(2)); - queueEntries.forEach(queueEntry -> { - assertThat(queueEntry.getStatus(), notNullValue()); - assertThat(queueEntry.getStatus().getName().getName(), is(QUEUE_ENTRY_STATUS)); - }); + public void shouldSearchAndCountQueueEntriesByQueueLocation() { + Location location1 = services.getLocationService().getLocation(1); + Location location3 = services.getLocationService().getLocation(3); + assertNumberOfResults(criteria, 4); + criteria.setLocations(Collections.emptyList()); + assertNumberOfResults(criteria, 0); + criteria.setLocations(Collections.singletonList(location1)); + assertResults(criteria, 1, 2); + criteria.setLocations(Collections.singletonList(location3)); + assertResults(criteria, 3, 4); + criteria.setLocations(Arrays.asList(location1, location3)); + assertResults(criteria, 1, 2, 3, 4); + criteria.setIncludedVoided(true); + assertResults(criteria, 1, 2, 3, 4, 10); } @Test - public void shouldCountQueueEntriesByStatus() { - Long queueEntriesCountByStatusCount = dao.getQueueEntriesCountByConceptStatus(QUEUE_ENTRY_STATUS, - ConceptNameType.FULLY_SPECIFIED, false); - - assertThat(queueEntriesCountByStatusCount, notNullValue()); - assertThat(queueEntriesCountByStatusCount, is(1L)); + public void shouldSearchAndCountQueueEntriesByQueueService() { + Concept service1 = services.getConceptService().getConcept(2001); + Concept service2 = services.getConceptService().getConcept(2002); + assertNumberOfResults(criteria, 4); + criteria.setServices(Collections.emptyList()); + assertNumberOfResults(criteria, 0); + criteria.setServices(Collections.singletonList(service1)); + assertResults(criteria, 1, 2); + criteria.setServices(Collections.singletonList(service2)); + assertResults(criteria, 3, 4); + criteria.setServices(Arrays.asList(service1, service2)); + assertResults(criteria, 1, 2, 3, 4); + criteria.setIncludedVoided(true); + assertResults(criteria, 1, 2, 3, 4, 10); } @Test - public void shouldZeroCountQueueEntriesByBadStatus() { - Long queueEntriesCountByStatusCount = dao.getQueueEntriesCountByConceptStatus(BAD_QUEUE_ENTRY_STATUS, - ConceptNameType.FULLY_SPECIFIED, false); - - assertThat(queueEntriesCountByStatusCount, notNullValue()); - assertThat(queueEntriesCountByStatusCount, is(0L)); + public void shouldSearchAndCountQueueEntriesByPatient() { + Patient patient1 = services.getPatientService().getPatient(100); + Patient patient2 = services.getPatientService().getPatient(2); + assertNumberOfResults(criteria, 4); + criteria.setPatient(patient1); + assertResults(criteria, 1, 2, 3); + criteria.setPatient(patient2); + assertResults(criteria, 4); } @Test - public void shouldGenerateVisitQueueNumber() { - QueueEntry queueEntry = Context.getService(QueueEntryService.class) - .getQueueEntryByUuid("7ub8fe43-2813-4kbc-80dc-2e5d30252cc5").get(); - Location location = Context.getLocationService().getLocationByUuid("d0938432-1691-11df-97a5-7038c098"); - - String queueNumber = dao.generateVisitQueueNumber(location, queueEntry.getQueue()); - - assertThat(queueNumber, notNullValue()); - assertThat(queueNumber, equalTo("CON-001")); + public void shouldSearchAndCountQueueEntriesByVisit() { + Visit visit1 = services.getVisitService().getVisit(101); + Visit visit2 = services.getVisitService().getVisit(102); + assertNumberOfResults(criteria, 4); + criteria.setVisit(visit1); + assertResults(criteria, 1, 2); + criteria.setVisit(visit2); + assertResults(criteria, 3); + criteria.setVisit(null); + criteria.setHasVisit(true); + assertResults(criteria, 1, 2, 3); + criteria.setHasVisit(false); + assertResults(criteria, 4); + } + + @Test + public void shouldSearchAndCountQueueEntriesByPriority() { + Concept priority1 = services.getConceptService().getConcept(1001); + Concept priority2 = services.getConceptService().getConcept(1002); + Concept nonPriority = services.getConceptService().getConcept(3001); + assertNumberOfResults(criteria, 4); + criteria.setPriorities(Collections.emptyList()); + assertNumberOfResults(criteria, 0); + criteria.setPriorities(Collections.singletonList(nonPriority)); + assertNumberOfResults(criteria, 0); + criteria.setPriorities(Collections.singletonList(priority1)); + assertResults(criteria, 1, 3, 4); + criteria.setPriorities(Collections.singletonList(priority2)); + assertResults(criteria, 2); + criteria.setPriorities(Arrays.asList(priority1, priority2)); + assertResults(criteria, 1, 2, 3, 4); + criteria.setIncludedVoided(true); + assertResults(criteria, 1, 2, 3, 4, 10); + } + + @Test + public void shouldSearchAndCountQueueEntriesByStatus() { + Concept status1 = services.getConceptService().getConcept(3001); + Concept status2 = services.getConceptService().getConcept(3002); + Concept nonStatus = services.getConceptService().getConcept(1001); + assertNumberOfResults(criteria, 4); + criteria.setStatuses(Collections.emptyList()); + assertNumberOfResults(criteria, 0); + criteria.setStatuses(Collections.singletonList(nonStatus)); + assertNumberOfResults(criteria, 0); + criteria.setStatuses(Collections.singletonList(status1)); + assertResults(criteria, 1); + criteria.setStatuses(Collections.singletonList(status2)); + assertResults(criteria, 2, 3, 4); + criteria.setStatuses(Arrays.asList(status1, status2)); + assertResults(criteria, 1, 2, 3, 4); + criteria.setIncludedVoided(true); + assertResults(criteria, 1, 2, 3, 4, 10); + } + + @Test + public void shouldSearchAndCountQueueEntriesByLocationWaitingFor() { + Location location1 = services.getLocationService().getLocation(1); + Location location3 = services.getLocationService().getLocation(3); + assertNumberOfResults(criteria, 4); + criteria.setLocationsWaitingFor(Collections.emptyList()); + assertResults(criteria, 3); // Empty list = entries with null value + criteria.setLocationsWaitingFor(Collections.singletonList(location1)); + assertResults(criteria, 4); + criteria.setLocationsWaitingFor(Collections.singletonList(location3)); + assertResults(criteria, 1, 2); + criteria.setLocationsWaitingFor(Arrays.asList(location1, location3)); + assertResults(criteria, 1, 2, 4); + } + + @Test + public void shouldSearchAndCountQueueEntriesByProviderWaitingFor() { + Provider provider1 = services.getProviderService().getProvider(1); + assertNumberOfResults(criteria, 4); + criteria.setProvidersWaitingFor(Collections.emptyList()); + assertResults(criteria, 2, 4); // Empty list = entries with null value + criteria.setProvidersWaitingFor(Collections.singletonList(provider1)); + assertResults(criteria, 1, 3); + } + + @Test + public void shouldSearchAndCountQueueEntriesByQueueComingFrom() { + Queue queue1 = services.getQueueService().getQueueById(1).orElse(null); + assertNumberOfResults(criteria, 4); + criteria.setQueuesComingFrom(Collections.emptyList()); + assertResults(criteria, 1, 3, 4); + criteria.setQueuesComingFrom(Collections.singletonList(queue1)); + assertResults(criteria, 2); + } + + @Test + // 2022-02-02 16:40:56.0, 2022-02-02 18:40:56.0, 2022-02-03 16:40:56.0, 2022-03-02 16:40:56.0 + public void shouldSearchAndCountQueueEntriesStartedOnOrAfterDate() { + assertNumberOfResults(criteria, 4); + criteria.setStartedOnOrAfter(date("2022-02-02 16:40:56")); + assertResults(criteria, 1, 2, 3, 4); + criteria.setStartedOnOrAfter(date("2022-02-02 16:40:57")); + assertResults(criteria, 2, 3, 4); + criteria.setStartedOnOrAfter(date("2022-02-02 18:40:56")); + assertResults(criteria, 2, 3, 4); + criteria.setStartedOnOrAfter(date("2022-02-02 18:40:57")); + assertResults(criteria, 3, 4); + criteria.setStartedOnOrAfter(date("2022-02-03 16:40:56")); + assertResults(criteria, 3, 4); + criteria.setStartedOnOrAfter(date("2022-02-03 16:40:57")); + assertResults(criteria, 4); + criteria.setStartedOnOrAfter(date("2022-03-02 16:40:56")); + assertResults(criteria, 4); + criteria.setStartedOnOrAfter(date("2022-03-02 16:40:57")); + assertNumberOfResults(criteria, 0); + } + + @Test + // 2022-02-02 16:40:56.0, 2022-02-02 18:40:56.0, 2022-02-03 16:40:56.0, 2022-03-02 16:40:56.0 + public void shouldSearchAndCountQueueEntriesStartedOnOrBeforeDate() { + assertNumberOfResults(criteria, 4); + criteria.setStartedOnOrBefore(date("2022-02-02 16:40:55")); + assertNumberOfResults(criteria, 0); + criteria.setStartedOnOrBefore(date("2022-02-02 16:40:56")); + assertResults(criteria, 1); + criteria.setStartedOnOrBefore(date("2022-02-02 18:40:56")); + assertResults(criteria, 1, 2); + criteria.setStartedOnOrBefore(date("2022-02-03 16:40:56")); + assertResults(criteria, 1, 2, 3); + criteria.setStartedOnOrBefore(date("2022-03-02 16:40:56")); + assertResults(criteria, 1, 2, 3, 4); + } + + @Test + // 2022-02-02 18:40:56.0, 2022-02-02 18:41:56.0 + public void shouldSearchAndCountQueueEntriesEndedOnOrBeforeDate() { + assertNumberOfResults(criteria, 4); + criteria.setEndedOnOrBefore(date("2022-02-02 18:40:55")); + assertNumberOfResults(criteria, 0); + criteria.setEndedOnOrBefore(date("2022-02-02 18:40:56")); + assertResults(criteria, 1); + criteria.setEndedOnOrBefore(date("2022-02-02 18:41:56")); + assertResults(criteria, 1, 4); + criteria.setEndedOnOrBefore(null); + criteria.setIsEnded(true); + assertResults(criteria, 1, 4); + criteria.setIsEnded(false); + assertResults(criteria, 2, 3); + } + + @Test + // 2022-02-02 18:40:56.0, 2022-02-02 18:41:56.0 + public void shouldSearchAndCountQueueEntriesEndedOnOrAfterDate() { + assertNumberOfResults(criteria, 4); + criteria.setEndedOnOrAfter(date("2022-02-02 18:41:57")); + assertNumberOfResults(criteria, 0); + criteria.setEndedOnOrAfter(date("2022-02-02 18:41:56")); + assertResults(criteria, 4); + criteria.setEndedOnOrAfter(date("2022-02-02 18:40:56")); + assertResults(criteria, 1, 4); + criteria.setEndedOnOrAfter(null); + criteria.setIsEnded(true); + assertResults(criteria, 1, 4); + criteria.setIsEnded(false); + assertResults(criteria, 2, 3); + } + + /** + * Utility method that tests criteria against both DAO methods to getQueueEntries and + * getCountOfQueueEntries + */ + private void assertNumberOfResults(QueueEntrySearchCriteria criteria, int expectedNumber) { + List queueEntries = dao.getQueueEntries(criteria); + assertThat(queueEntries, hasSize(expectedNumber)); + Long numResults = dao.getCountOfQueueEntries(criteria); + assertThat(numResults.intValue(), equalTo(expectedNumber)); + } + + /** + * Utility method that tests criteria against both DAO methods to getQueueEntries and + * getCountOfQueueEntries + */ + private void assertResults(QueueEntrySearchCriteria criteria, Integer... queueEntryIds) { + List queueEntries = dao.getQueueEntries(criteria); + assertThat(queueEntries, hasSize(queueEntryIds.length)); + for (Integer queueEntryId : queueEntryIds) { + QueueEntry expected = dao.get(queueEntryId).orElse(null); + assertThat(expected, notNullValue()); + assertThat(queueEntries.contains(expected), is(true)); + } + Long numResults = dao.getCountOfQueueEntries(criteria); + assertThat(numResults.intValue(), equalTo(queueEntryIds.length)); + } + + /** + * @return the date for the given string value + */ + private Date date(String dateVal) { + return QueueUtils.parseDate(dateVal); } } diff --git a/api/src/test/java/org/openmrs/module/queue/api/dao/QueueRoomDaoTest.java b/api/src/test/java/org/openmrs/module/queue/api/dao/QueueRoomDaoTest.java index a043cce..801d4ee 100644 --- a/api/src/test/java/org/openmrs/module/queue/api/dao/QueueRoomDaoTest.java +++ b/api/src/test/java/org/openmrs/module/queue/api/dao/QueueRoomDaoTest.java @@ -10,20 +10,23 @@ package org.openmrs.module.queue.api.dao; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Optional; import org.junit.Before; import org.junit.Test; import org.openmrs.Location; -import org.openmrs.api.context.Context; import org.openmrs.module.queue.SpringTestConfiguration; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.QueueRoomSearchCriteria; import org.openmrs.module.queue.model.Queue; import org.openmrs.module.queue.model.QueueRoom; import org.openmrs.test.BaseModuleContextSensitiveTest; @@ -57,8 +60,7 @@ public class QueueRoomDaoTest extends BaseModuleContextSensitiveTest { private QueueRoomDao dao; @Autowired - @Qualifier("queueDao") - private QueueDao queueDao; + private QueueServicesWrapper services; @Before public void setup() { @@ -94,7 +96,7 @@ public void shouldCreateNewQueueRoom() { QueueRoom queueRoom = new QueueRoom(); queueRoom.setUuid(NEW_QUEUE_ROOM_UUID); queueRoom.setName(NEW_QUEUE_ROOM_NAME); - queueRoom.setQueue(queueDao.get(QUEUE_UUID).get()); + queueRoom.setQueue(services.getQueueService().getQueueByUuid(QUEUE_UUID).get()); QueueRoom result = dao.createOrUpdate(queueRoom); assertThat(result, notNullValue()); @@ -130,41 +132,37 @@ public void shouldUpdateQueueRoom() { @Test public void shouldFindQueueRoomByLocation() { - Location location = Context.getLocationService().getLocationByUuid(LOCATION_UUID); - - List roomsByLocation = dao.getQueueRoomsByServiceAndLocation(null, location); - + QueueRoomSearchCriteria criteria = new QueueRoomSearchCriteria(); + Location location = services.getLocationService().getLocationByUuid(LOCATION_UUID); + criteria.setLocations(Collections.singletonList(location)); + List roomsByLocation = dao.getQueueRooms(criteria); assertThat(roomsByLocation, notNullValue()); assertThat(roomsByLocation, hasSize(2)); - roomsByLocation.forEach(room -> assertThat(room.getQueue().getLocation().getUuid(), is(LOCATION_UUID))); + roomsByLocation.forEach(room -> assertThat(room.getQueue().getLocation(), equalTo(location))); } @Test public void shouldFindQueueRoomByQueue() { - Queue queue = queueDao.get(QUEUE_UUID).get(); - - List roomsByQueue = dao.getQueueRoomsByServiceAndLocation(queue, null); - + QueueRoomSearchCriteria criteria = new QueueRoomSearchCriteria(); + Queue queue = services.getQueueService().getQueueByUuid(QUEUE_UUID).get(); + criteria.setQueues(Collections.singletonList(queue)); + List roomsByQueue = dao.getQueueRooms(criteria); assertThat(roomsByQueue, notNullValue()); assertThat(roomsByQueue, hasSize(2)); - roomsByQueue.forEach(room -> assertThat(room.getQueue().getUuid(), is(QUEUE_UUID))); + roomsByQueue.forEach(room -> assertThat(room.getQueue(), equalTo(queue))); } @Test public void shouldDeleteQueueRoomByUuid() { dao.delete(QUEUE_ROOM_UUID); - Optional result = dao.get(QUEUE_ROOM_UUID); - //verify delete operation assertThat(result.isPresent(), is(false)); } @Test public void shouldDeleteQueueRoomByEntity() { dao.get(QUEUE_ROOM_UUID).ifPresent((queue) -> dao.delete(queue)); - Optional result = dao.get(QUEUE_ROOM_UUID); - //verify delete operation assertThat(result.isPresent(), is(false)); } diff --git a/api/src/test/java/org/openmrs/module/queue/api/dao/RoomProviderMapDaoTest.java b/api/src/test/java/org/openmrs/module/queue/api/dao/RoomProviderMapDaoTest.java index 190fb53..85a34db 100644 --- a/api/src/test/java/org/openmrs/module/queue/api/dao/RoomProviderMapDaoTest.java +++ b/api/src/test/java/org/openmrs/module/queue/api/dao/RoomProviderMapDaoTest.java @@ -16,6 +16,7 @@ import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Optional; @@ -24,6 +25,8 @@ import org.openmrs.Provider; import org.openmrs.api.context.Context; import org.openmrs.module.queue.SpringTestConfiguration; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.RoomProviderMapSearchCriteria; import org.openmrs.module.queue.model.QueueRoom; import org.openmrs.module.queue.model.RoomProviderMap; import org.openmrs.test.BaseModuleContextSensitiveTest; @@ -58,8 +61,7 @@ public class RoomProviderMapDaoTest extends BaseModuleContextSensitiveTest { private RoomProviderMapDao dao; @Autowired - @Qualifier("queueRoomDao") - private QueueRoomDao queueRoomDao; + private QueueServicesWrapper services; @Before public void setup() { @@ -92,7 +94,7 @@ public void shouldReturnNullForRetiredRoomProviderMap() { @Test public void shouldCreateNewRoomProviderMap() { - QueueRoom queueRoom = queueRoomDao.get(QUEUE_ROOM_UUID).get(); + QueueRoom queueRoom = services.getQueueRoomService().getQueueRoomByUuid(QUEUE_ROOM_UUID).orElse(null); Provider provider = Context.getProviderService().getProviderByUuid(PROVIDER_UUID); RoomProviderMap providerRoom = new RoomProviderMap(); @@ -167,10 +169,10 @@ public void shouldFindAllQueueRoomProviderMapsIncludingRetired() { @Test public void shouldFindByQueueRoom() { - Optional queueRoom = queueRoomDao.get(QUEUE_ROOM_UUID); - - List result = dao.getRoomProvider(null, queueRoom.get()); - + QueueRoom queueRoom = services.getQueueRoomService().getQueueRoomByUuid(QUEUE_ROOM_UUID).orElse(null); + RoomProviderMapSearchCriteria criteria = new RoomProviderMapSearchCriteria(); + criteria.setQueueRooms(Collections.singletonList(queueRoom)); + List result = dao.getRoomProviderMaps(criteria); assertThat(result, notNullValue()); assertThat(result, hasSize(1)); result.forEach(room -> assertThat(room.getQueueRoom().getUuid(), is(QUEUE_ROOM_UUID))); @@ -178,10 +180,10 @@ public void shouldFindByQueueRoom() { @Test public void shouldFindByProvider() { - Provider provider = Context.getProviderService().getProviderByUuid(PROVIDER_UUID); - - List result = dao.getRoomProvider(provider, null); - + Provider provider = services.getProviderService().getProviderByUuid(PROVIDER_UUID); + RoomProviderMapSearchCriteria criteria = new RoomProviderMapSearchCriteria(); + criteria.setProviders(Collections.singletonList(provider)); + List result = dao.getRoomProviderMaps(criteria); assertThat(result, notNullValue()); assertThat(result, hasSize(1)); result.forEach(room -> assertThat(room.getProvider().getUuid(), is(PROVIDER_UUID))); diff --git a/api/src/test/java/org/openmrs/module/queue/api/dao/VisitQueueEntryDaoTest.java b/api/src/test/java/org/openmrs/module/queue/api/dao/VisitQueueEntryDaoTest.java deleted file mode 100644 index db4a46b..0000000 --- a/api/src/test/java/org/openmrs/module/queue/api/dao/VisitQueueEntryDaoTest.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.api.dao; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.Optional; - -import lombok.extern.slf4j.Slf4j; -import org.junit.Before; -import org.junit.Test; -import org.openmrs.Visit; -import org.openmrs.api.ConceptNameType; -import org.openmrs.api.context.Context; -import org.openmrs.module.queue.SpringTestConfiguration; -import org.openmrs.module.queue.api.QueueEntryService; -import org.openmrs.module.queue.model.QueueEntry; -import org.openmrs.module.queue.model.VisitQueueEntry; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.openmrs.test.SkipBaseSetup; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.test.context.ContextConfiguration; - -@Slf4j -@ContextConfiguration(classes = SpringTestConfiguration.class, inheritLocations = false) -public class VisitQueueEntryDaoTest extends BaseModuleContextSensitiveTest { - - private static final String VISIT_QUEUE_ENTRY_UUID = "5eb8fe43-2813-4kbc-80dc-2e5d30252cc3"; - - private static final String NEW_VISIT_QUEUE_ENTRY_UUID = "7eb6fe43-2813-4kbc-80dc-2e5d30252kk9"; - - private static final String VOIDED_VISIT_QUEUE_ENTRY_UUID = "4eb8fe43-2813-4kbc-80dc-2e5d30252cc6"; - - private static final String QUEUE_ENTRY_UUID = "4eb8fe43-2813-4kbc-80dc-2e5d30252cc6"; - - private static final String VISIT_UUID = "j848b0c0-1ade-11e1-9c71-00248140a6eb"; - - private static final String WAITING_FOR_STATUS = "Waiting for service"; - - private static final String IN_SERVICE_STATUS = "In service"; - - private static final String TRIAGE_SERVICE = "Triage"; - - private static final String CONSULTATION_SERVICE = "Consultation"; - - private static final String LOCATION_UUID = "d0938432-1691-11df-97a5-7038c098"; - - @Autowired - @Qualifier("visitQueueEntryDao") - private VisitQueueEntryDao dao; - - //the order of the list is important! - private static final List VISIT_QUEUE_ENTRY_INITIAL_DATASET_XML = Arrays.asList( - "org/openmrs/module/queue/api/dao/QueueDaoTest_locationInitialDataset.xml", - "org/openmrs/module/queue/api/dao/QueueEntryDaoTest_conceptsInitialDataset.xml", - "org/openmrs/module/queue/api/dao/QueueDaoTest_initialDataset.xml", - "org/openmrs/module/queue/api/dao/QueueEntryDaoTest_patientInitialDataset.xml", - "org/openmrs/module/queue/api/dao/QueueEntryDaoTest_initialDataset.xml", - "org/openmrs/module/queue/api/dao/VisitQueueEntryDaoTest_visitInitialDataset.xml", - "org/openmrs/module/queue/api/dao/visitQueueEntryDaoTest_initialDataset.xml"); - - @Before - @SkipBaseSetup - public void setup() { - VISIT_QUEUE_ENTRY_INITIAL_DATASET_XML.forEach(this::executeDataSet); - } - - @Test - public void shouldGetVisitQueueEntryByUuid() { - Optional result = dao.get(VISIT_QUEUE_ENTRY_UUID); - - assertThat(result, notNullValue()); - assertThat(result.isPresent(), is(true)); - assertThat(result.get().getUuid(), is(VISIT_QUEUE_ENTRY_UUID)); - } - - @Test - public void shouldReturnNullForVoidedVisitQueueEntry() { - Optional visitQueueEntry = dao.get(VOIDED_VISIT_QUEUE_ENTRY_UUID); - assertThat(visitQueueEntry.isPresent(), is(false)); - } - - @Test - public void shouldCreateNewVisitQueryEntryRecord() { - VisitQueueEntry visitQueueEntry = new VisitQueueEntry(); - visitQueueEntry.setUuid(NEW_VISIT_QUEUE_ENTRY_UUID); - Optional queueEntryOptional = Context.getService(QueueEntryService.class) - .getQueueEntryByUuid(QUEUE_ENTRY_UUID); - assertThat(queueEntryOptional.isPresent(), is(true)); - queueEntryOptional.ifPresent(visitQueueEntry::setQueueEntry); - - Visit visit = Context.getVisitService().getVisitByUuid(VISIT_UUID); - assertThat(visit, notNullValue()); - visitQueueEntry.setVisit(visit); - visitQueueEntry.setDateCreated(new Date()); - - VisitQueueEntry result = dao.createOrUpdate(visitQueueEntry); - assertThat(result, notNullValue()); - assertThat(result.getUuid(), is(NEW_VISIT_QUEUE_ENTRY_UUID)); - assertThat(result.getQueueEntry(), notNullValue()); - assertThat(result.getQueueEntry().getUuid(), is(QUEUE_ENTRY_UUID)); - } - - @Test - public void shouldUpdateAnExistingVisitQueueEntryRecord() { - Optional existingVisitQueueEntry = dao.get(VISIT_QUEUE_ENTRY_UUID); - assertThat(existingVisitQueueEntry.isPresent(), is(true)); - - //Update the existing visit_queue_entry record - existingVisitQueueEntry.ifPresent(visitQueueEntry -> { - visitQueueEntry.setVoided(true); - visitQueueEntry.setDateVoided(new Date()); - visitQueueEntry.setVoidReason("Testing update operation"); - dao.createOrUpdate(visitQueueEntry); - }); - - //Get the updated visit_queue_entry - Optional updatedVisitQueueEntry = dao.get(VISIT_QUEUE_ENTRY_UUID); - //If false - update was successful - assertThat(updatedVisitQueueEntry.isPresent(), is(false)); - //Get the voided visit queue entry record - Optional alreadyVoidedVisitQueueEntryRecord = dao.get(existingVisitQueueEntry.get().getId()); - assertThat(alreadyVoidedVisitQueueEntryRecord.isPresent(), is(true)); - assertThat(alreadyVoidedVisitQueueEntryRecord.get().getVoided(), is(true)); - assertThat(alreadyVoidedVisitQueueEntryRecord.get().getVoidReason(), is("Testing update operation")); - } - - @Test - public void shouldFindAllVisitQueueEntries() { - Collection visitQueueEntries = dao.findAll(); - assertThat(visitQueueEntries.isEmpty(), is(false)); - assertThat(visitQueueEntries, hasSize(2)); - } - - @Test - public void shouldFindAllVisitQueueEntriesIncludingRetired() { - Collection visitQueueEntries = dao.findAll(true); - assertThat(visitQueueEntries.isEmpty(), is(false)); - assertThat(visitQueueEntries, hasSize(3)); - } - - @Test - public void shouldDeleteVisitQueueEntryByUuid() { - dao.delete(VISIT_QUEUE_ENTRY_UUID); - - Optional result = dao.get(VISIT_QUEUE_ENTRY_UUID); - //verify delete operation - assertThat(result.isPresent(), is(false)); - } - - @Test - public void shouldDeleteVisitQueueEntryByEntity() { - dao.get(VISIT_QUEUE_ENTRY_UUID).ifPresent((queueEntry) -> dao.delete(queueEntry)); - - Optional result = dao.get(VISIT_QUEUE_ENTRY_UUID); - //verify delete operation - assertThat(result.isPresent(), is(false)); - } - - @Test - public void shouldFindVisitQueueEntriesByWaitingForStatusAndService() { - Collection result = dao.findVisitQueueEntriesByConceptStatusAndConceptService(WAITING_FOR_STATUS, - TRIAGE_SERVICE, ConceptNameType.FULLY_SPECIFIED, false, null, null); - - assertThat(result, notNullValue()); - assertThat(result, hasSize(1)); - } - - @Test - public void shouldFindVisitQueueEntriesByInServiceStatusAndService() { - Collection result = dao.findVisitQueueEntriesByConceptStatusAndConceptService(IN_SERVICE_STATUS, - CONSULTATION_SERVICE, ConceptNameType.FULLY_SPECIFIED, false, null, null); - - assertThat(result, notNullValue()); - assertThat(result, hasSize(1)); - } - - @Test - public void shouldFilterVisitQueueEntriesByInServiceStatus() { - Collection result = dao.findVisitQueueEntriesByConceptStatusAndConceptService(IN_SERVICE_STATUS, - null, ConceptNameType.FULLY_SPECIFIED, false, null, null); - - assertThat(result, notNullValue()); - assertThat(result, hasSize(1)); - } - - @Test - public void shouldFilterVisitQueueEntriesByConsultationService() { - Collection result = dao.findVisitQueueEntriesByConceptStatusAndConceptService(null, - CONSULTATION_SERVICE, ConceptNameType.FULLY_SPECIFIED, false, null, null); - - assertThat(result, notNullValue()); - assertThat(result, hasSize(1)); - } - - @Test - public void shouldFilterVisitQueueEntriesByLocation() { - Collection result = dao.findVisitQueueEntriesByConceptStatusAndConceptService(null, null, null, - false, LOCATION_UUID, null); - - assertThat(result, notNullValue()); - assertThat(result, hasSize(2)); - } - - @Test - public void shouldNotFilterVisitQueueEntriesByServiceAndStatusIfBothAreNull() { - Collection result = dao.findVisitQueueEntriesByConceptStatusAndConceptService(null, null, - ConceptNameType.FULLY_SPECIFIED, false, null, null); - - assertThat(result, notNullValue()); - assertThat(result, hasSize(2)); - } - - @Test - public void shouldGetCountOfVisitQueueEntriesByInServiceStatus() { - Long result = dao.getVisitQueueEntriesCountByLocationStatusAndService(IN_SERVICE_STATUS, null, - ConceptNameType.FULLY_SPECIFIED, false, null); - - assertThat(result, notNullValue()); - assertThat(result, is(1L)); - } - - @Test - public void shouldGetCountOfVisitQueueEntriesByConsultationService() { - Long result = dao.getVisitQueueEntriesCountByLocationStatusAndService(null, CONSULTATION_SERVICE, - ConceptNameType.FULLY_SPECIFIED, false, null); - - assertThat(result, notNullValue()); - assertThat(result, is(1L)); - } - - @Test - public void shouldGetCountOfVisitQueueEntriesByLocation() { - Long result = dao.getVisitQueueEntriesCountByLocationStatusAndService(null, null, null, false, LOCATION_UUID); - - assertThat(result, notNullValue()); - assertThat(result, is(2L)); - } - - @Test - public void shouldGetCountOfVisitQueueEntriesByServiceAndStatus() { - Long result = dao.getVisitQueueEntriesCountByLocationStatusAndService(WAITING_FOR_STATUS, CONSULTATION_SERVICE, - ConceptNameType.FULLY_SPECIFIED, false, null); - - assertThat(result, notNullValue()); - assertThat(result, is(0L)); - } -} diff --git a/api/src/test/java/org/openmrs/module/queue/tasks/AutoCloseVisitQueueEntryTaskTest.java b/api/src/test/java/org/openmrs/module/queue/tasks/AutoCloseVisitQueueEntryTaskTest.java index 58a650d..22aeb28 100644 --- a/api/src/test/java/org/openmrs/module/queue/tasks/AutoCloseVisitQueueEntryTaskTest.java +++ b/api/src/test/java/org/openmrs/module/queue/tasks/AutoCloseVisitQueueEntryTaskTest.java @@ -16,7 +16,6 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Collection; import java.util.Date; import java.util.List; import java.util.stream.Collectors; @@ -24,17 +23,16 @@ import org.junit.Test; import org.openmrs.Visit; import org.openmrs.module.queue.model.QueueEntry; -import org.openmrs.module.queue.model.VisitQueueEntry; public class AutoCloseVisitQueueEntryTaskTest { - final List queueEntries = new ArrayList<>(); + final List queueEntries = new ArrayList<>(); class TestAutoCloseVisitEntryTask extends AutoCloseVisitQueueEntryTask { @Override - protected Collection getActiveVisitQueueEntries() { - return queueEntries.stream().filter(e -> e.getQueueEntry().getEndedAt() == null).collect(Collectors.toList()); + protected List getActiveVisitQueueEntries() { + return queueEntries.stream().filter(e -> e.getEndedAt() == null).collect(Collectors.toList()); } @Override @@ -50,19 +48,15 @@ public void shouldAutoCloseVisitQueueEntriesIfVisitIsClosed() throws Exception { visit1.setStartDatetime(getDate("2020-01-01 10:00")); QueueEntry queueEntry1 = new QueueEntry(); queueEntry1.setStartedAt(getDate("2020-01-01 10:10")); - VisitQueueEntry visitQueueEntry1 = new VisitQueueEntry(); - visitQueueEntry1.setVisit(visit1); - visitQueueEntry1.setQueueEntry(queueEntry1); - queueEntries.add(visitQueueEntry1); + queueEntry1.setVisit(visit1); + queueEntries.add(queueEntry1); Visit visit2 = new Visit(); visit2.setStartDatetime(getDate("2021-01-01 10:00")); QueueEntry queueEntry2 = new QueueEntry(); queueEntry2.setStartedAt(getDate("2021-01-01 10:20")); - VisitQueueEntry visitQueueEntry2 = new VisitQueueEntry(); - visitQueueEntry2.setVisit(visit2); - visitQueueEntry2.setQueueEntry(queueEntry2); - queueEntries.add(visitQueueEntry2); + queueEntry2.setVisit(visit2); + queueEntries.add(queueEntry2); TestAutoCloseVisitEntryTask task = new TestAutoCloseVisitEntryTask(); task.run(); diff --git a/api/src/test/java/org/openmrs/module/queue/validators/VisitQueueEntryValidatorTest.java b/api/src/test/java/org/openmrs/module/queue/validators/VisitQueueEntryValidatorTest.java deleted file mode 100644 index 97f0d5a..0000000 --- a/api/src/test/java/org/openmrs/module/queue/validators/VisitQueueEntryValidatorTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.validators; - -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import org.junit.Before; -import org.junit.Test; -import org.openmrs.Concept; -import org.openmrs.api.context.Context; -import org.openmrs.module.queue.SpringTestConfiguration; -import org.openmrs.module.queue.api.QueueEntryService; -import org.openmrs.module.queue.model.QueueEntry; -import org.openmrs.module.queue.utils.QueueValidationUtils; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; - -@ContextConfiguration(classes = { SpringTestConfiguration.class }, inheritLocations = false) -public class VisitQueueEntryValidatorTest extends BaseModuleContextSensitiveTest { - - private static final String VALID_CONCEPT_STATUS_UUID = "4eb8fe43-2813-4kbc-80dc-2e5d30252cc6"; - - private static final String INVALID_STATUS_CONCEPT_UUID = "67b910bd-298c-4ecf-a632-661ae2f446op"; - - //the order of the list is important! - private static final List VISIT_QUEUE_ENTRY_INITIAL_DATASET_XML = Arrays.asList( - "org/openmrs/module/queue/api/dao/QueueDaoTest_locationInitialDataset.xml", - "org/openmrs/module/queue/api/dao/QueueEntryDaoTest_conceptsInitialDataset.xml", - "org/openmrs/module/queue/api/dao/QueueDaoTest_initialDataset.xml", - "org/openmrs/module/queue/api/dao/QueueEntryDaoTest_patientInitialDataset.xml", - "org/openmrs/module/queue/api/dao/QueueEntryDaoTest_initialDataset.xml", - "org/openmrs/module/queue/api/dao/VisitQueueEntryDaoTest_visitInitialDataset.xml", - "org/openmrs/module/queue/api/dao/visitQueueEntryDaoTest_initialDataset.xml", - "org/openmrs/module/queue/validators/QueueEntryValidatorTest_globalPropertyInitialDataset.xml"); - - @Autowired - private VisitQueueEntryValidator validator; - - @Before - public void setup() { - VISIT_QUEUE_ENTRY_INITIAL_DATASET_XML.forEach(this::executeDataSet); - } - - @Test - public void validatorNotNull() { - assertNotNull(validator); - } - - @Test - public void shouldReturnTrueForValidStatusConcept() { - Optional queueEntry = Context.getService(QueueEntryService.class) - .getQueueEntryByUuid(VALID_CONCEPT_STATUS_UUID); - assertTrue(queueEntry.isPresent()); - QueueValidationUtils.isValidStatus(queueEntry.get().getStatus()); - } - - @Test - public void shouldReturnFalseForInvalidStatusConcept() { - Concept concept = Context.getConceptService().getConceptByUuid(INVALID_STATUS_CONCEPT_UUID); - assertThat(concept, notNullValue()); - assertFalse(QueueValidationUtils.isValidStatus(concept)); - } -} diff --git a/api/src/test/resources/org/openmrs/module/queue/api/dao/QueueDaoTest_initialDataset.xml b/api/src/test/resources/org/openmrs/module/queue/api/dao/QueueDaoTest_initialDataset.xml index c6f13bb..f505140 100644 --- a/api/src/test/resources/org/openmrs/module/queue/api/dao/QueueDaoTest_initialDataset.xml +++ b/api/src/test/resources/org/openmrs/module/queue/api/dao/QueueDaoTest_initialDataset.xml @@ -12,7 +12,7 @@ - - - + + diff --git a/api/src/test/resources/org/openmrs/module/queue/api/dao/QueueEntryDaoTest_initialDataset.xml b/api/src/test/resources/org/openmrs/module/queue/api/dao/QueueEntryDaoTest_initialDataset.xml index 5d8845c..58781ed 100644 --- a/api/src/test/resources/org/openmrs/module/queue/api/dao/QueueEntryDaoTest_initialDataset.xml +++ b/api/src/test/resources/org/openmrs/module/queue/api/dao/QueueEntryDaoTest_initialDataset.xml @@ -9,12 +9,108 @@ graphic logo is a trademark of OpenMRS Inc. --> - - + + + + + + + + - - diff --git a/api/src/test/resources/org/openmrs/module/queue/api/dao/visitQueueEntryDaoTest_initialDataset.xml b/api/src/test/resources/org/openmrs/module/queue/api/dao/visitQueueEntryDaoTest_initialDataset.xml deleted file mode 100644 index efa2084..0000000 --- a/api/src/test/resources/org/openmrs/module/queue/api/dao/visitQueueEntryDaoTest_initialDataset.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - diff --git a/api/src/test/resources/org/openmrs/module/queue/api/dao/visitQueueEntryDaoTest_visitQueueNumberInitialDataset.xml b/api/src/test/resources/org/openmrs/module/queue/api/dao/visitQueueEntryDaoTest_visitQueueNumberInitialDataset.xml deleted file mode 100644 index f0d706f..0000000 --- a/api/src/test/resources/org/openmrs/module/queue/api/dao/visitQueueEntryDaoTest_visitQueueNumberInitialDataset.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - diff --git a/omod/src/main/java/org/openmrs/module/queue/web/Legacy1xRestController.java b/omod/src/main/java/org/openmrs/module/queue/web/Legacy1xRestController.java new file mode 100644 index 0000000..da2180e --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/queue/web/Legacy1xRestController.java @@ -0,0 +1,252 @@ +/* + * 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. + */ +package org.openmrs.module.queue.web; + +import static org.openmrs.module.queue.web.QueueEntryMetricRestController.AVERAGE_WAIT_TIME; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.web.bind.annotation.RequestMethod.GET; +import static org.springframework.web.bind.annotation.RequestMethod.POST; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.NotNull; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.commons.lang3.StringUtils; +import org.codehaus.jackson.node.ObjectNode; +import org.openmrs.Location; +import org.openmrs.Visit; +import org.openmrs.VisitAttributeType; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.digitalSignage.QueueTicketAssignments; +import org.openmrs.module.queue.model.Queue; +import org.openmrs.module.queue.web.resources.QueueEntryResource; +import org.openmrs.module.queue.web.resources.QueueRoomResource; +import org.openmrs.module.queue.web.resources.RoomProviderMapResource; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +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.api.Converter; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * REST controller that exposes REST endpoints that are compatible with version 1.x of this module + */ +@Controller +@Slf4j +public class Legacy1xRestController extends BaseRestController { + + @Autowired + QueueServicesWrapper services; + + @Autowired + private QueueEntryMetricRestController queueEntryMetricRestController; + + private final QueueEntryResource queueEntryResource; + + private final QueueRoomResource queueRoomResource; + + private final RoomProviderMapResource roomProviderMapResource; + + public Legacy1xRestController() { + queueEntryResource = new QueueEntryResource(); + queueRoomResource = new QueueRoomResource(); + roomProviderMapResource = new RoomProviderMapResource(); + } + + @RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/visit-queue-entry", method = GET) + @ResponseBody + @SuppressWarnings("unchecked") + public Object getVisitQueueEntries(HttpServletRequest request, HttpServletResponse response) throws Exception { + SimpleObject result = new SimpleObject(); + List visitQueueEntries = new ArrayList<>(); + result.add("results", visitQueueEntries); + RequestContext requestContext = RestUtil.getRequestContext(request, response, Representation.REF); + Map searchResult = queueEntryResource.search(requestContext); + List> queueEntries = (List>) PropertyUtils.getProperty(searchResult, + "results"); + for (Map queueEntry : queueEntries) { + SimpleObject visitQueueEntry = new SimpleObject(); + visitQueueEntry.add("visit", queueEntry.get("visit")); + visitQueueEntry.add("queueEntry", queueEntry); + visitQueueEntries.add(visitQueueEntry); + } + return result; + } + + @RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/visit-queue-entry", method = POST) + @ResponseBody + public Object postVisitQueueEntry(HttpServletRequest request, HttpServletResponse response, + @RequestBody SimpleObject post) { + RequestContext requestContext = RestUtil.getRequestContext(request, response); + SimpleObject queueEntry = new SimpleObject(); + Map postedQueueEntry = post.get("queueEntry"); + for (String key : postedQueueEntry.keySet()) { + queueEntry.add(key, postedQueueEntry.get(key)); + } + queueEntry.add("visit", post.get("visit")); + Object created = queueEntryResource.create(queueEntry, requestContext); + return RestUtil.created(response, created); + } + + @RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/queueroom", method = GET) + @ResponseBody + public Object getQueueRooms(HttpServletRequest request, HttpServletResponse response) { + RequestContext requestContext = RestUtil.getRequestContext(request, response, Representation.REF); + return queueRoomResource.search(requestContext); + } + + @RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/roomprovidermap", method = GET) + @ResponseBody + public Object getRoomProviderMaps(HttpServletRequest request, HttpServletResponse response) { + RequestContext requestContext = RestUtil.getRequestContext(request, response, Representation.REF); + return roomProviderMapResource.search(requestContext); + } + + @RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/roomprovidermap", method = POST) + @ResponseBody + public Object postRoomProviderMap(HttpServletRequest request, HttpServletResponse response, + @RequestBody SimpleObject post) { + RequestContext requestContext = RestUtil.getRequestContext(request, response); + Object created = roomProviderMapResource.create(post, requestContext); + return RestUtil.created(response, created); + } + + @RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/roomprovidermap/{uuid}", method = POST) + @ResponseBody + public Object updateRoomProviderMap(@PathVariable("uuid") String uuid, @RequestBody SimpleObject post, + HttpServletRequest request, HttpServletResponse response) throws ResponseException { + RequestContext context = RestUtil.getRequestContext(request, response); + if (post.get("deleted") != null && "false".equals(post.get("deleted")) && post.size() == 1) { + return RestUtil.updated(response, roomProviderMapResource.undelete(uuid, context)); + } + return RestUtil.updated(response, roomProviderMapResource.update(uuid, post, context)); + } + + @RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/queue-entry-metrics", method = { GET, POST }) + @ResponseBody + public Object getQueueEntryMetrics(HttpServletRequest request) { + return queueEntryMetricRestController.handleRequest(request); + } + + @RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/queue-metrics", method = GET) + @ResponseBody + public Object getQueueMetrics(HttpServletRequest request) { + SimpleObject results = (SimpleObject) getQueueEntryMetrics(request); + String queueUuid = request.getParameter("queue"); + String queueName = (StringUtils.isNotBlank(queueUuid) ? services.getQueue(queueUuid).getName() : ""); + return new GenericSingleObjectResult(Arrays.asList(new PropValue("queue", queueName), + new PropValue("averageWaitTime", results.get(AVERAGE_WAIT_TIME)))); + } + + @RequestMapping(method = POST, value = "/rest/" + RestConstants.VERSION_1 + "/queueutil/assignticket") + @ResponseBody + public Object assignTicketToServicePoint(HttpServletRequest request) throws Exception { + String requestBody = QueueTicketAssignments.fetchRequestBody(request.getReader()); + if (requestBody != null) { + ObjectMapper mapper = new ObjectMapper(); + JsonNode actualObj = mapper.readTree(requestBody); + String servicePointName = actualObj.get("servicePointName").textValue(); + String ticketNumber = actualObj.get("ticketNumber").textValue(); + String status = actualObj.get("status").textValue(); + + if (servicePointName.isEmpty() || ticketNumber.isEmpty() || status.isEmpty()) { + return new ResponseEntity("One of the required fields is empty", new HttpHeaders(), BAD_REQUEST); + } + + QueueTicketAssignments.updateTicketAssignment(servicePointName, ticketNumber, status); + return new ResponseEntity("Ticket successfully assigned!", new HttpHeaders(), HttpStatus.OK); + } + return new ResponseEntity("The request could not be interpreted", new HttpHeaders(), BAD_REQUEST); + } + + @RequestMapping(method = GET, value = "/rest/" + RestConstants.VERSION_1 + "/queueutil/active-tickets") + public Object getActiveTickets() { + ObjectNode ticketAssignments = QueueTicketAssignments.getActiveTicketAssignments(); + return new ResponseEntity(ticketAssignments, new HttpHeaders(), HttpStatus.OK); + } + + @RequestMapping(method = { GET, POST }, value = "/rest/" + RestConstants.VERSION_1 + "/queue-entry-number") + public Object generateQueueEntryNumber(HttpServletRequest request) { + String serviceType = ""; + String visitQueueNumber = ""; + String vatUuid = request.getParameter("visitAttributeType"); + if (StringUtils.isNotEmpty(vatUuid)) { + VisitAttributeType vat = services.getVisitService().getVisitAttributeTypeByUuid(vatUuid); + if (vat != null) { + Location l = services.getLocation(request.getParameter("location")); + Visit v = services.getVisit(request.getParameter("visit")); + Queue q = services.getQueue(request.getParameter("queue")); + serviceType = q.getName(); + visitQueueNumber = services.getQueueEntryService().generateVisitQueueNumber(l, q, v, vat); + } + } + return new GenericSingleObjectResult(Arrays.asList(new PropValue("serviceType", serviceType), + new PropValue("visitQueueNumber", visitQueueNumber))); + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class GenericSingleObjectResult implements PageableResult { + + private List propValues; + + @Override + public SimpleObject toSimpleObject(Converter converter) throws ResponseException { + SimpleObject ret = new SimpleObject(); + this.propValues.forEach(propValue -> ret.add(propValue.getProperty(), propValue.getValue())); + return ret; + } + + public void add(@NotNull String property, @NotNull Object value) { + if (propValues == null) { + this.propValues = new ArrayList<>(); + } + this.propValues.add(new PropValue(property, value)); + } + } + + @Data + @AllArgsConstructor + public static class PropValue implements Serializable { + + private static final long serialVersionUID = 45L; + + private String property; + + private Object value; + } +} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/PatientQueueRestController.java b/omod/src/main/java/org/openmrs/module/queue/web/PatientQueueRestController.java deleted file mode 100644 index 7d3ff34..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/PatientQueueRestController.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web; - -import javax.servlet.http.HttpServletRequest; - -import java.io.IOException; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.openmrs.module.queue.api.digitalSignage.QueueTicketAssignments; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -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.ResponseBody; - -/** - * The main controller that exposes additional end points for order entry - */ -@Controller -@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/queueutil") -public class PatientQueueRestController extends BaseRestController { - - @RequestMapping(method = RequestMethod.POST, value = "/assignticket") - @ResponseBody - public Object assignTicketToServicePoint(HttpServletRequest request) { - String requestBody = null; - try { - - requestBody = QueueTicketAssignments.fetchRequestBody(request.getReader()); - - } - catch (IOException e) { - e.printStackTrace(); - String msg = e.getMessage(); - - return "Error extracting request body" + msg; - } - - if (requestBody != null) { - - ObjectMapper mapper = new ObjectMapper(); - JsonNode actualObj = null; - try { - actualObj = mapper.readTree(requestBody); - } - catch (IOException e) { - throw new RuntimeException(e); - } - - String servicePointName = actualObj.get("servicePointName").textValue(); - String ticketNumber = actualObj.get("ticketNumber").textValue(); - String status = actualObj.get("status").textValue(); - - QueueTicketAssignments.updateTicketAssignment(servicePointName, ticketNumber, status); - - if (servicePointName.isEmpty() || ticketNumber.isEmpty() || status.isEmpty()) { - return new ResponseEntity("One of the required fields is empty", new HttpHeaders(), - HttpStatus.BAD_REQUEST); - } - - return new ResponseEntity("Ticket successfully assigned!", new HttpHeaders(), HttpStatus.OK); - } - return new ResponseEntity("The request could not be interpreted!", new HttpHeaders(), - HttpStatus.BAD_REQUEST); - } - - @RequestMapping(method = RequestMethod.GET, value = "/active-tickets") - public Object getActiveTickets() { - return new ResponseEntity(QueueTicketAssignments.getActiveTicketAssignments(), new HttpHeaders(), - HttpStatus.OK); - } - - /** - * @see BaseRestController#getNamespace() - */ - - @Override - public String getNamespace() { - return "v1/queueutil"; - } -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/QueueEntryMetricRestController.java b/omod/src/main/java/org/openmrs/module/queue/web/QueueEntryMetricRestController.java new file mode 100644 index 0000000..7267b2d --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/queue/web/QueueEntryMetricRestController.java @@ -0,0 +1,89 @@ +/* + * 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. + */ +package org.openmrs.module.queue.web; + +import javax.servlet.http.HttpServletRequest; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.QueueEntrySearchCriteria; +import org.openmrs.module.queue.model.QueueEntry; +import org.openmrs.module.queue.utils.QueueUtils; +import org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +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.ResponseBody; + +/** + * The main controller that exposes additional end points for order entry + */ +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/queue-entry-metric") +public class QueueEntryMetricRestController extends BaseRestController { + + public static final String METRIC = "metric"; + + public static final String COUNT = "count"; + + public static final String AVERAGE_WAIT_TIME = "averageWaitTime"; + + private final QueueEntrySearchCriteriaParser searchCriteriaParser; + + private final QueueServicesWrapper services; + + @Autowired + public QueueEntryMetricRestController(QueueEntrySearchCriteriaParser searchCriteriaParser, + QueueServicesWrapper services) { + this.searchCriteriaParser = searchCriteriaParser; + this.services = services; + } + + @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }) + @ResponseBody + @SuppressWarnings("unchecked") + public Object handleRequest(HttpServletRequest request) { + Map parameters = request.getParameterMap(); + SimpleObject ret = new SimpleObject(); + + String[] metricArray = parameters.get(METRIC); + List metrics = (metricArray == null ? new ArrayList<>() : Arrays.asList(metricArray)); + + QueueEntrySearchCriteria criteria = searchCriteriaParser.constructFromRequest(parameters); + + // If we only want count, then use the ore efficient service to get counts + if (metrics.size() == 1 && metrics.get(0).equals(COUNT)) { + ret.add(COUNT, services.getQueueEntryService().getCountOfQueueEntries(criteria).intValue()); + } else { + List queueEntries = services.getQueueEntryService().getQueueEntries(criteria); + if (metrics.isEmpty() || metrics.contains(COUNT)) { + ret.add(COUNT, queueEntries.size()); + } + if (metrics.isEmpty() || metrics.contains(AVERAGE_WAIT_TIME)) { + ret.add(AVERAGE_WAIT_TIME, QueueUtils.computeAverageWaitTimeInMinutes(queueEntries)); + } + } + + return ret; + } + + @Override + public String getNamespace() { + return "v1/queue-entry-metric"; + } +} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntryCountSubResource.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntryCountSubResource.java deleted file mode 100644 index 1263ccf..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntryCountSubResource.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources; - -import java.util.Arrays; - -import org.openmrs.module.queue.model.Queue; -import org.openmrs.module.queue.model.QueueEntry; -import org.openmrs.module.queue.web.resources.custom.response.GenericSingleObjectResult; -import org.openmrs.module.queue.web.resources.custom.response.PropValue; -import org.openmrs.module.queue.web.resources.custom.response.QueueEntryCount; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; -import org.openmrs.module.webservices.rest.web.annotation.SubResource; -import org.openmrs.module.webservices.rest.web.representation.Representation; -import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingSubResource; -import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; - -/** - * Probably, this sub-resource is unnecessary, the idea is; with a searchHandler - - * QueueCountSearchHandler, I can achieve the following URL formats; /ws/rest/v1/queue//count - * - returns the count of queue entries for the specified resource - * /ws/rest/v1/queue//count?status=Waiting for Service Queue Count - * /ws/rest/v1/queue//count?status=With Service /ws/rest/v1/queue//count?status=Waiting - * For Service&v=custom:(count) -returns only the count. - */ -@SuppressWarnings("unused") -@SubResource(parent = QueueResource.class, path = "count", supportedClass = QueueEntryCount.class, supportedOpenmrsVersions = { - "2.3 - 9.*" }, order = 12) -public class QueueEntryCountSubResource extends DelegatingSubResource { - - @Override - public Queue getParent(QueueEntryCount queueEntryCount) { - return queueEntryCount.getQueue(); - } - - @Override - public void setParent(QueueEntryCount queueEntryCount, Queue queue) { - queueEntryCount.setQueue(queue); - } - - @Override - public PageableResult doGetAll(Queue queue, RequestContext requestContext) throws ResponseException { - return new GenericSingleObjectResult(Arrays.asList(new PropValue("queueName", queue.getName()), - new PropValue("queueEntriesCount", queue.getActiveQueueEntries().size()))); - } - - @Override - public QueueEntryCount getByUniqueId(String s) { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - protected void delete(QueueEntryCount queueEntryCount, String s, RequestContext requestContext) - throws ResponseException { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - public QueueEntryCount newDelegate() { - return new QueueEntryCount(); - } - - @Override - public QueueEntryCount save(QueueEntryCount queueEntryCount) { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - public void purge(QueueEntryCount queueEntryCount, RequestContext requestContext) throws ResponseException { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - public DelegatingResourceDescription getRepresentationDescription(Representation representation) { - return null; - } - - @PropertyGetter("display") - public String getDisplay(QueueEntry queueEntry) { - //Display queue name - return queueEntry.getQueue().getName(); - } - - @Override - public String getResourceVersion() { - return "2.3"; - } -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntryMetricsResource.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntryMetricsResource.java deleted file mode 100644 index 3562f8b..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntryMetricsResource.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources; - -import java.util.Arrays; - -import org.openmrs.api.context.Context; -import org.openmrs.module.queue.api.VisitQueueEntryService; -import org.openmrs.module.queue.web.resources.custom.response.GenericSingleObjectResult; -import org.openmrs.module.queue.web.resources.custom.response.PropValue; -import org.openmrs.module.queue.web.resources.custom.response.QueueEntryMetric; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.annotation.Resource; -import org.openmrs.module.webservices.rest.web.representation.Representation; -import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; -import org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult; -import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; - -/** - * Sort of a placeholder resource - */ -@SuppressWarnings("unused") -@Resource(name = RestConstants.VERSION_1 - + "/queue-entry-metrics", supportedClass = QueueEntryMetric.class, supportedOpenmrsVersions = { "2.3 - 9.*" }) -public class QueueEntryMetricsResource extends DelegatingCrudResource { - - @Override - public SimpleObject getByUniqueId(String uuid) { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - protected void delete(SimpleObject queueEntryMetric, String s, RequestContext requestContext) throws ResponseException { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - public SimpleObject newDelegate() { - return new SimpleObject(); - } - - @Override - public SimpleObject save(SimpleObject queueEntryMetric) { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - public void purge(SimpleObject simpleObject, RequestContext requestContext) throws ResponseException { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - public DelegatingResourceDescription getRepresentationDescription(Representation representation) { - return null; - } - - @Override - protected PageableResult doSearch(RequestContext requestContext) { - String status = requestContext.getParameter("status"); - String service = requestContext.getParameter("service"); - String locationUuid = requestContext.getParameter("location"); - - if (service != null && status != null && locationUuid != null) { - Long patientsCount = Context.getService(VisitQueueEntryService.class) - .getVisitQueueEntriesCountByLocationStatusAndService(status, service, locationUuid); - - return new GenericSingleObjectResult( - Arrays.asList(new PropValue("metric", status + " " + service), new PropValue("count", patientsCount))); - } else if (service != null && !service.isEmpty()) { - Long count = Context.getService(VisitQueueEntryService.class).getVisitQueueEntriesCountByService(service); - return new GenericSingleObjectResult( - Arrays.asList(new PropValue("metric", service), new PropValue("count", count))); - - } else if (status != null && !status.isEmpty()) { - Long count = Context.getService(VisitQueueEntryService.class).getVisitQueueEntriesCountByStatus(status); - return new GenericSingleObjectResult( - Arrays.asList(new PropValue("metric", status), new PropValue("count", count))); - - } else if (locationUuid != null && !locationUuid.isEmpty()) { - Long count = Context.getService(VisitQueueEntryService.class).getVisitQueueEntriesCountByLocation(locationUuid); - return new GenericSingleObjectResult( - Arrays.asList(new PropValue("metric", locationUuid), new PropValue("count", count))); - } - - return new EmptySearchResult(); - } -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntryNumberResource.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntryNumberResource.java deleted file mode 100644 index 9b967bf..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntryNumberResource.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources; - -import java.util.Arrays; -import java.util.Optional; - -import org.openmrs.Location; -import org.openmrs.Visit; -import org.openmrs.VisitAttributeType; -import org.openmrs.api.context.Context; -import org.openmrs.module.queue.api.QueueEntryService; -import org.openmrs.module.queue.api.QueueService; -import org.openmrs.module.queue.model.Queue; -import org.openmrs.module.queue.web.resources.custom.response.GenericSingleObjectResult; -import org.openmrs.module.queue.web.resources.custom.response.PropValue; -import org.openmrs.module.queue.web.resources.custom.response.QueueEntryNumber; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.annotation.Resource; -import org.openmrs.module.webservices.rest.web.representation.Representation; -import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; -import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; - -@Resource(name = RestConstants.VERSION_1 - + "/queue-entry-number", supportedClass = QueueEntryNumber.class, supportedOpenmrsVersions = { "2.3 - 9.*" }) -public class QueueEntryNumberResource extends DelegatingCrudResource { - - @Override - public SimpleObject getByUniqueId(String uuid) { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - protected void delete(SimpleObject simpleObject, String s, RequestContext requestContext) throws ResponseException { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - public SimpleObject newDelegate() { - return new SimpleObject(); - } - - @Override - public SimpleObject save(SimpleObject simpleObject) { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - public void purge(SimpleObject simpleObject, RequestContext requestContext) throws ResponseException { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - public DelegatingResourceDescription getRepresentationDescription(Representation representation) { - return null; - } - - @Override - protected PageableResult doSearch(RequestContext requestContext) { - Location location = requestContext.getParameter("location") != null - ? Context.getLocationService().getLocationByUuid(requestContext.getParameter("location")) - : null; - Visit visit = requestContext.getParameter("visit") != null - ? Context.getVisitService().getVisitByUuid(requestContext.getParameter("visit")) - : null; - VisitAttributeType visitAttributeType = requestContext.getParameter("visitAttributeType") != null - ? Context.getVisitService().getVisitAttributeTypeByUuid(requestContext.getParameter("visitAttributeType")) - : null; - Optional queueOptional = Context.getService(QueueService.class) - .getQueueByUuid(requestContext.getParameter("queue")); - Queue queue = null; - if (queueOptional.isPresent()) { - queue = queueOptional.get(); - } - String visitQueueNumber = Context.getService(QueueEntryService.class).generateVisitQueueNumber(location, queue, - visit, visitAttributeType); - - return new GenericSingleObjectResult(Arrays.asList(new PropValue("serviceType", queue.getName()), - new PropValue("visitQueueNumber", visitQueueNumber))); - - } -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntryResource.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntryResource.java new file mode 100644 index 0000000..1661bfe --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntryResource.java @@ -0,0 +1,215 @@ +/* + * 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. + */ +package org.openmrs.module.queue.web.resources; + +import javax.validation.constraints.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import lombok.extern.slf4j.Slf4j; +import org.openmrs.PersonName; +import org.openmrs.api.context.Context; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.QueueEntrySearchCriteria; +import org.openmrs.module.queue.model.QueueEntry; +import org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; +import org.openmrs.module.webservices.rest.web.annotation.Resource; +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.RefRepresentation; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.module.webservices.rest.web.response.ObjectNotFoundException; +import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; +import org.openmrs.module.webservices.rest.web.response.ResponseException; + +/** + * REST resource for Queue Entries + */ +@Slf4j +@SuppressWarnings("unused") +@Resource(name = RestConstants.VERSION_1 + "/queue-entry", supportedClass = QueueEntry.class, supportedOpenmrsVersions = { + "2.3 - 9.*" }) +public class QueueEntryResource extends DelegatingCrudResource { + + private final QueueServicesWrapper services; + + private final QueueEntrySearchCriteriaParser searchCriteriaParser; + + public QueueEntryResource() { + services = Context.getRegisteredComponents(QueueServicesWrapper.class).get(0); + searchCriteriaParser = Context.getRegisteredComponents(QueueEntrySearchCriteriaParser.class).get(0); + } + + public QueueEntryResource(QueueServicesWrapper services, QueueEntrySearchCriteriaParser searchCriteriaParser) { + this.services = services; + this.searchCriteriaParser = searchCriteriaParser; + } + + @Override + public QueueEntry getByUniqueId(@NotNull String uuid) { + Optional queueEntryOptional = services.getQueueEntryService().getQueueEntryByUuid(uuid); + if (!queueEntryOptional.isPresent()) { + throw new ObjectNotFoundException("Could not find visit queue entry with uuid " + uuid); + } + return queueEntryOptional.get(); + } + + @Override + protected void delete(QueueEntry qe, String reason, RequestContext requestContext) throws ResponseException { + services.getQueueEntryService().voidQueueEntry(qe, reason); + } + + @Override + public QueueEntry newDelegate() { + return new QueueEntry(); + } + + @Override + public QueueEntry save(QueueEntry queueEntry) { + return services.getQueueEntryService().saveQueueEntry(queueEntry); + } + + @Override + public void purge(QueueEntry queueEntry, RequestContext requestContext) throws ResponseException { + services.getQueueEntryService().purgeQueueEntry(queueEntry); + } + + @Override + protected PageableResult doGetAll(RequestContext requestContext) throws ResponseException { + QueueEntrySearchCriteria criteria = new QueueEntrySearchCriteria(); + List activeEntries = services.getQueueEntryService().getQueueEntries(criteria); + return new NeedsPaging<>(new ArrayList<>(activeEntries), requestContext); + } + + @Override + @SuppressWarnings("unchecked") + protected PageableResult doSearch(RequestContext requestContext) { + Map parameters = requestContext.getRequest().getParameterMap(); + QueueEntrySearchCriteria criteria = searchCriteriaParser.constructFromRequest(parameters); + List queueEntries = services.getQueueEntryService().getQueueEntries(criteria); + return new NeedsPaging<>(queueEntries, requestContext); + } + + @Override + public DelegatingResourceDescription getCreatableProperties() throws ResourceDoesNotSupportOperationException { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("queue"); + description.addProperty("status"); + description.addProperty("priority"); + description.addProperty("priorityComment"); + description.addProperty("patient"); + description.addProperty("visit"); + description.addProperty("sortWeight"); + description.addProperty("startedAt"); + description.addProperty("locationWaitingFor"); + description.addProperty("queueComingFrom"); + description.addProperty("providerWaitingFor"); + return description; + } + + @Override + public DelegatingResourceDescription getUpdatableProperties() throws ResourceDoesNotSupportOperationException { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("status"); + description.addProperty("priorityComment"); + description.addProperty("sortWeight"); + description.addProperty("endedAt"); + return description; + } + + @Override + public DelegatingResourceDescription getRepresentationDescription(Representation representation) { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + if (representation instanceof RefRepresentation) { + addSharedResourceDescriptionProperties(description); + description.addProperty("uuid"); + description.addProperty("display"); + description.addProperty("queue", Representation.REF); + description.addProperty("status", Representation.REF); + description.addProperty("patient", Representation.REF); + description.addProperty("visit", Representation.REF); + description.addProperty("priority", Representation.REF); + description.addProperty("priorityComment"); + description.addProperty("sortWeight"); + description.addProperty("startedAt"); + description.addProperty("endedAt"); + description.addProperty("locationWaitingFor", Representation.REF); + description.addProperty("queueComingFrom", Representation.REF); + description.addProperty("providerWaitingFor", Representation.REF); + description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); + } else if (representation instanceof DefaultRepresentation) { + addSharedResourceDescriptionProperties(description); + description.addProperty("uuid"); + description.addProperty("display"); + description.addProperty("queue", Representation.DEFAULT); + description.addProperty("status", Representation.DEFAULT); + description.addProperty("patient", Representation.DEFAULT); + description.addProperty("visit", Representation.DEFAULT); + description.addProperty("priority", Representation.DEFAULT); + description.addProperty("priorityComment"); + description.addProperty("sortWeight"); + description.addProperty("startedAt"); + description.addProperty("endedAt"); + description.addProperty("locationWaitingFor", Representation.DEFAULT); + description.addProperty("queueComingFrom", Representation.DEFAULT); + description.addProperty("providerWaitingFor", Representation.DEFAULT); + description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); + } else if (representation instanceof FullRepresentation) { + addSharedResourceDescriptionProperties(description); + description.addProperty("uuid"); + description.addProperty("display"); + description.addProperty("queue", Representation.FULL); + description.addProperty("status", Representation.FULL); + description.addProperty("patient", Representation.FULL); + description.addProperty("visit", Representation.FULL); + description.addProperty("priority", Representation.FULL); + description.addProperty("priorityComment"); + description.addProperty("sortWeight"); + description.addProperty("startedAt"); + description.addProperty("endedAt"); + description.addProperty("locationWaitingFor", Representation.FULL); + description.addProperty("queueComingFrom", Representation.FULL); + description.addProperty("providerWaitingFor", Representation.FULL); + description.addProperty("voided"); + description.addProperty("voidReason"); + description.addProperty("auditInfo"); + } else if (representation instanceof CustomRepresentation) { + description = null; + } + return description; + } + + private void addSharedResourceDescriptionProperties(DelegatingResourceDescription resourceDescription) { + resourceDescription.addSelfLink(); + resourceDescription.addProperty("uuid"); + } + + @PropertyGetter("display") + public String getDisplay(QueueEntry queueEntry) { + PersonName personName = queueEntry.getPatient().getPersonName(); + return (personName == null ? queueEntry.getPatient().toString() : personName.getFullName()); + } + + @Override + public String getResourceVersion() { + return "2.3"; + } +} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntrySubResource.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntrySubResource.java index 885fbd4..5faa922 100644 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntrySubResource.java +++ b/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueEntrySubResource.java @@ -16,7 +16,7 @@ import java.util.Optional; import org.openmrs.api.context.Context; -import org.openmrs.module.queue.api.QueueEntryService; +import org.openmrs.module.queue.api.QueueServicesWrapper; import org.openmrs.module.queue.model.Queue; import org.openmrs.module.queue.model.QueueEntry; import org.openmrs.module.webservices.rest.web.RequestContext; @@ -41,6 +41,16 @@ "2.3 - 9.*" }, order = 10) public class QueueEntrySubResource extends DelegatingSubResource { + private final QueueServicesWrapper services; + + public QueueEntrySubResource() { + this.services = Context.getRegisteredComponents(QueueServicesWrapper.class).get(0); + } + + public QueueEntrySubResource(QueueServicesWrapper services) { + this.services = services; + } + @Override public Queue getParent(QueueEntry queueEntry) { return queueEntry.getQueue(); @@ -59,7 +69,7 @@ public PageableResult doGetAll(Queue queue, RequestContext requestContext) throw @Override public QueueEntry getByUniqueId(@NotNull String uuid) { - Optional queueEntryOptional = Context.getService(QueueEntryService.class).getQueueEntryByUuid(uuid); + Optional queueEntryOptional = services.getQueueEntryService().getQueueEntryByUuid(uuid); if (!queueEntryOptional.isPresent()) { throw new ObjectNotFoundException("Could not find queue entry with UUID " + uuid); } @@ -68,7 +78,7 @@ public QueueEntry getByUniqueId(@NotNull String uuid) { @Override protected void delete(QueueEntry queueEntry, String voidReason, RequestContext requestContext) throws ResponseException { - Context.getService(QueueEntryService.class).voidQueueEntry(queueEntry.getUuid(), voidReason); + services.getQueueEntryService().voidQueueEntry(queueEntry, voidReason); } @Override @@ -78,12 +88,12 @@ public QueueEntry newDelegate() { @Override public QueueEntry save(QueueEntry queueEntry) { - return Context.getService(QueueEntryService.class).createQueueEntry(queueEntry); + return services.getQueueEntryService().saveQueueEntry(queueEntry); } @Override public void purge(QueueEntry queueEntry, RequestContext requestContext) throws ResponseException { - Context.getService(QueueEntryService.class).purgeQueueEntry(queueEntry); + services.getQueueEntryService().purgeQueueEntry(queueEntry); } @Override @@ -115,9 +125,9 @@ public DelegatingResourceDescription getRepresentationDescription(Representation DelegatingResourceDescription resourceDescription = new DelegatingResourceDescription(); if (representation instanceof RefRepresentation) { this.addSharedResourceDescriptionProperties(resourceDescription); - resourceDescription.addProperty("queue", Representation.REF); resourceDescription.addProperty("status", Representation.REF); resourceDescription.addProperty("patient", Representation.REF); + resourceDescription.addProperty("patient", Representation.REF); resourceDescription.addProperty("priority", Representation.REF); resourceDescription.addProperty("locationWaitingFor", Representation.REF); resourceDescription.addProperty("queueComingFrom", Representation.REF); @@ -125,9 +135,9 @@ public DelegatingResourceDescription getRepresentationDescription(Representation resourceDescription.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); } else if (representation instanceof DefaultRepresentation) { this.addSharedResourceDescriptionProperties(resourceDescription); - resourceDescription.addProperty("queue", Representation.DEFAULT); resourceDescription.addProperty("status", Representation.DEFAULT); resourceDescription.addProperty("patient", Representation.DEFAULT); + resourceDescription.addProperty("visit", Representation.DEFAULT); resourceDescription.addProperty("priority", Representation.DEFAULT); resourceDescription.addProperty("locationWaitingFor", Representation.DEFAULT); resourceDescription.addProperty("queueComingFrom", Representation.DEFAULT); @@ -138,9 +148,9 @@ public DelegatingResourceDescription getRepresentationDescription(Representation resourceDescription.addProperty("voided"); resourceDescription.addProperty("voidReason"); resourceDescription.addProperty("auditInfo"); - resourceDescription.addProperty("queue", Representation.FULL); resourceDescription.addProperty("status", Representation.FULL); resourceDescription.addProperty("patient", Representation.FULL); + resourceDescription.addProperty("visit", Representation.FULL); resourceDescription.addProperty("priority", Representation.FULL); resourceDescription.addProperty("locationWaitingFor", Representation.FULL); resourceDescription.addProperty("queueComingFrom", Representation.FULL); diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueMetricsResource.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueMetricsResource.java deleted file mode 100644 index 17a5f2e..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueMetricsResource.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources; - -import java.util.Arrays; -import java.util.Optional; - -import org.openmrs.Concept; -import org.openmrs.api.context.Context; -import org.openmrs.module.queue.api.QueueService; -import org.openmrs.module.queue.model.Queue; -import org.openmrs.module.queue.web.resources.custom.response.GenericSingleObjectResult; -import org.openmrs.module.queue.web.resources.custom.response.PropValue; -import org.openmrs.module.queue.web.resources.custom.response.QueueMetric; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.annotation.Resource; -import org.openmrs.module.webservices.rest.web.representation.Representation; -import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; -import org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult; -import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; - -@Resource(name = RestConstants.VERSION_1 + "/queue-metrics", supportedClass = QueueMetric.class, supportedOpenmrsVersions = { - "2.3 - 9.*" }) -public class QueueMetricsResource extends DelegatingCrudResource { - - @Override - public SimpleObject getByUniqueId(String s) { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - protected void delete(SimpleObject simpleObject, String s, RequestContext requestContext) throws ResponseException { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - public SimpleObject newDelegate() { - return new SimpleObject(); - } - - @Override - public SimpleObject save(SimpleObject simpleObject) { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - protected PageableResult doSearch(RequestContext requestContext) { - String queueUuid = requestContext.getParameter("queue"); - if (!queueUuid.isEmpty()) { - - Optional queueOptional = Context.getService(QueueService.class).getQueueByUuid(queueUuid); - Concept status = requestContext.getParameter("status") != null - ? Context.getConceptService().getConceptByUuid(requestContext.getParameter("status")) - : null; - if (queueOptional.isPresent()) { - Double averageWaitTime = Context.getService(QueueService.class).getQueueAverageWaitTime(queueOptional.get(), - status); - return new GenericSingleObjectResult(Arrays.asList( - new PropValue("queue", Context.getService(QueueService.class).getQueueByUuid(queueUuid).get().getName()), - new PropValue("averageWaitTime", averageWaitTime))); - } - - } - - return new EmptySearchResult(); - } - - @Override - public void purge(SimpleObject simpleObject, RequestContext requestContext) throws ResponseException { - throw new ResourceDoesNotSupportOperationException(); - } - - @Override - public DelegatingResourceDescription getRepresentationDescription(Representation representation) { - return null; - } -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueResource.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueResource.java index e3c08f7..54fb03d 100644 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueResource.java +++ b/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueResource.java @@ -13,12 +13,14 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; -import org.openmrs.Location; import org.openmrs.api.context.Context; -import org.openmrs.module.queue.api.QueueService; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.QueueSearchCriteria; import org.openmrs.module.queue.model.Queue; +import org.openmrs.module.queue.web.resources.parser.QueueSearchCriteriaParser; import org.openmrs.module.webservices.rest.web.RequestContext; import org.openmrs.module.webservices.rest.web.RestConstants; import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; @@ -41,21 +43,28 @@ "2.3 - 9.*" }) public class QueueResource extends DelegatingCrudResource { - private final QueueService queueService; + private final QueueServicesWrapper services; + + private final QueueSearchCriteriaParser searchCriteriaParser; public QueueResource() { - this.queueService = Context.getService(QueueService.class); + this.services = Context.getRegisteredComponents(QueueServicesWrapper.class).get(0); + this.searchCriteriaParser = Context.getRegisteredComponents(QueueSearchCriteriaParser.class).get(0); + } + + public QueueResource(QueueServicesWrapper services, QueueSearchCriteriaParser searchCriteriaParser) { + this.services = services; + this.searchCriteriaParser = searchCriteriaParser; } @Override public NeedsPaging doGetAll(RequestContext requestContext) throws ResponseException { - return new NeedsPaging(new ArrayList(Context.getService(QueueService.class).getAllQueues()), - requestContext); + return new NeedsPaging<>(new ArrayList<>(services.getQueueService().getAllQueues()), requestContext); } @Override public Queue getByUniqueId(@NotNull String uuid) { - Optional optionalQueue = queueService.getQueueByUuid(uuid); + Optional optionalQueue = services.getQueueService().getQueueByUuid(uuid); if (!optionalQueue.isPresent()) { throw new ObjectNotFoundException("Could not find queue with UUID " + uuid); } @@ -64,10 +73,11 @@ public Queue getByUniqueId(@NotNull String uuid) { @Override protected void delete(Queue queue, String retireReason, RequestContext requestContext) throws ResponseException { - if (!this.queueService.getQueueByUuid(queue.getUuid()).isPresent()) { + Optional optionalQueue = services.getQueueService().getQueueByUuid(queue.getUuid()); + if (!optionalQueue.isPresent()) { throw new ObjectNotFoundException("Could not find queue with uuid " + queue.getUuid()); } - this.queueService.voidQueue(queue.getUuid(), retireReason); + services.getQueueService().retireQueue(queue, retireReason); } @Override @@ -77,12 +87,12 @@ public Queue newDelegate() { @Override public Queue save(Queue queue) { - return this.queueService.createQueue(queue); + return services.getQueueService().saveQueue(queue); } @Override public void purge(Queue queue, RequestContext requestContext) throws ResponseException { - this.queueService.purgeQueue(queue); + services.getQueueService().purgeQueue(queue); } @Override @@ -133,14 +143,12 @@ public DelegatingResourceDescription getUpdatableProperties() throws ResourceDoe } @Override + @SuppressWarnings("unchecked") protected PageableResult doSearch(RequestContext requestContext) { - String locationUuid = requestContext.getParameter("location"); - Location location = Context.getLocationService().getLocationByUuid(locationUuid); - if (location == null) { - throw new ObjectNotFoundException("could not find location with uuid " + locationUuid); - } - List queuesByLocation = queueService.getAllQueuesByLocation(locationUuid); - return new NeedsPaging<>(queuesByLocation, requestContext); + Map parameters = requestContext.getRequest().getParameterMap(); + QueueSearchCriteria criteria = searchCriteriaParser.constructFromRequest(parameters); + List queueEntries = services.getQueueService().getQueues(criteria); + return new NeedsPaging<>(queueEntries, requestContext); } @PropertyGetter("display") @@ -150,7 +158,6 @@ public String getDisplay(Queue queue) { @Override public String getResourceVersion() { - //What determines the resource version? is it the target platform version or just 1.8 return "2.3"; } } diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueRoomResource.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueRoomResource.java index 0f24952..744b06e 100644 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueRoomResource.java +++ b/omod/src/main/java/org/openmrs/module/queue/web/resources/QueueRoomResource.java @@ -9,14 +9,16 @@ */ package org.openmrs.module.queue.web.resources; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.Optional; -import org.openmrs.Location; import org.openmrs.api.context.Context; -import org.openmrs.module.queue.api.QueueRoomService; -import org.openmrs.module.queue.api.QueueService; -import org.openmrs.module.queue.model.Queue; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.QueueRoomSearchCriteria; import org.openmrs.module.queue.model.QueueRoom; +import org.openmrs.module.queue.web.resources.parser.QueueRoomSearchCriteriaParser; import org.openmrs.module.webservices.rest.web.RequestContext; import org.openmrs.module.webservices.rest.web.RestConstants; import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; @@ -34,19 +36,33 @@ import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; import org.openmrs.module.webservices.rest.web.response.ResponseException; -@Resource(name = RestConstants.VERSION_1 + "/queueroom", supportedClass = QueueRoom.class, supportedOpenmrsVersions = { +@SuppressWarnings("unused") +@Resource(name = RestConstants.VERSION_1 + "/queue-room", supportedClass = QueueRoom.class, supportedOpenmrsVersions = { "2.3 - 9.*" }) public class QueueRoomResource extends DelegatingCrudResource { - private final QueueRoomService queueRoomService; + private final QueueServicesWrapper services; + + private final QueueRoomSearchCriteriaParser searchCriteriaParser; public QueueRoomResource() { - this.queueRoomService = Context.getService(QueueRoomService.class); + this.services = Context.getRegisteredComponents(QueueServicesWrapper.class).get(0); + this.searchCriteriaParser = Context.getRegisteredComponents(QueueRoomSearchCriteriaParser.class).get(0); + } + + public QueueRoomResource(QueueServicesWrapper services, QueueRoomSearchCriteriaParser searchCriteriaParser) { + this.services = services; + this.searchCriteriaParser = searchCriteriaParser; + } + + @Override + public NeedsPaging doGetAll(RequestContext requestContext) throws ResponseException { + return new NeedsPaging<>(new ArrayList<>(services.getQueueRoomService().getAllQueueRooms()), requestContext); } @Override public QueueRoom getByUniqueId(String uuid) { - Optional optionalQueueRoom = queueRoomService.getQueueRoomByUuid(uuid); + Optional optionalQueueRoom = services.getQueueRoomService().getQueueRoomByUuid(uuid); if (!optionalQueueRoom.isPresent()) { throw new ObjectNotFoundException("Could not find queueRoom with UUID " + uuid); } @@ -55,10 +71,7 @@ public QueueRoom getByUniqueId(String uuid) { @Override protected void delete(QueueRoom queueRoom, String retireReason, RequestContext requestContext) throws ResponseException { - if (!this.queueRoomService.getQueueRoomByUuid(queueRoom.getUuid()).isPresent()) { - throw new ObjectNotFoundException("Could not find queue room with uuid " + queueRoom.getUuid()); - } - this.queueRoomService.voidQueueRoom(queueRoom.getUuid(), retireReason); + services.getQueueRoomService().retireQueueRoom(queueRoom, retireReason); } @Override @@ -68,23 +81,21 @@ public QueueRoom newDelegate() { @Override public QueueRoom save(QueueRoom queueRoom) { - return queueRoomService.createQueueRoom(queueRoom); + return services.getQueueRoomService().saveQueueRoom(queueRoom); } @Override public void purge(QueueRoom queueRoom, RequestContext requestContext) throws ResponseException { - this.queueRoomService.purgeQueueRoom(queueRoom); + services.getQueueRoomService().purgeQueueRoom(queueRoom); } @Override - protected PageableResult doSearch(RequestContext context) { - Queue queue = context.getParameter("queue") != null - ? Context.getService(QueueService.class).getQueueByUuid(context.getParameter("queue")).get() - : null; - Location location = context.getParameter("location") != null - ? Context.getLocationService().getLocationByUuid(context.getParameter("location")) - : null; - return new NeedsPaging<>(queueRoomService.getQueueRoomsByServiceAndLocation(queue, location), context); + @SuppressWarnings("unchecked") + protected PageableResult doSearch(RequestContext requestContext) { + Map parameters = requestContext.getRequest().getParameterMap(); + QueueRoomSearchCriteria criteria = searchCriteriaParser.constructFromRequest(parameters); + List queueRooms = services.getQueueRoomService().getQueueRooms(criteria); + return new NeedsPaging<>(queueRooms, requestContext); } @Override diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/RoomProviderMapResource.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/RoomProviderMapResource.java index 1823748..9bbeac3 100644 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/RoomProviderMapResource.java +++ b/omod/src/main/java/org/openmrs/module/queue/web/resources/RoomProviderMapResource.java @@ -9,14 +9,16 @@ */ package org.openmrs.module.queue.web.resources; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.Optional; -import org.openmrs.Provider; import org.openmrs.api.context.Context; -import org.openmrs.module.queue.api.QueueRoomService; -import org.openmrs.module.queue.api.RoomProviderMapService; -import org.openmrs.module.queue.model.QueueRoom; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.RoomProviderMapSearchCriteria; import org.openmrs.module.queue.model.RoomProviderMap; +import org.openmrs.module.queue.web.resources.parser.RoomProviderMapSearchCriteriaParser; import org.openmrs.module.webservices.rest.web.RequestContext; import org.openmrs.module.webservices.rest.web.RestConstants; import org.openmrs.module.webservices.rest.web.annotation.Resource; @@ -33,32 +35,42 @@ import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; import org.openmrs.module.webservices.rest.web.response.ResponseException; +@SuppressWarnings("unused") @Resource(name = RestConstants.VERSION_1 - + "/roomprovidermap", supportedClass = RoomProviderMap.class, supportedOpenmrsVersions = { "2.3 - 9.*" }) + + "/queue-room-provider", supportedClass = RoomProviderMap.class, supportedOpenmrsVersions = { "2.3 - 9.*" }) public class RoomProviderMapResource extends DelegatingCrudResource { - private final RoomProviderMapService roomProviderMapService; + private final QueueServicesWrapper services; + + private final RoomProviderMapSearchCriteriaParser searchCriteriaParser; public RoomProviderMapResource() { - this.roomProviderMapService = Context.getService(RoomProviderMapService.class); + this.services = Context.getRegisteredComponents(QueueServicesWrapper.class).get(0); + this.searchCriteriaParser = Context.getRegisteredComponents(RoomProviderMapSearchCriteriaParser.class).get(0); + } + + public RoomProviderMapResource(QueueServicesWrapper services, RoomProviderMapSearchCriteriaParser parser) { + this.services = services; + this.searchCriteriaParser = parser; + } + + @Override + public NeedsPaging doGetAll(RequestContext ctx) throws ResponseException { + return new NeedsPaging<>(new ArrayList<>(services.getRoomProviderMapService().getAllRoomProviderMaps()), ctx); } @Override public RoomProviderMap getByUniqueId(String uuid) { - Optional optionalQueueRoom = roomProviderMapService.getRoomProviderMapByUuid(uuid); - if (!optionalQueueRoom.isPresent()) { + Optional optional = services.getRoomProviderMapService().getRoomProviderMapByUuid(uuid); + if (!optional.isPresent()) { throw new ObjectNotFoundException("Could not find roomProviderMap with UUID " + uuid); } - return optionalQueueRoom.get(); + return optional.get(); } @Override - protected void delete(RoomProviderMap roomProviderMap, String voidReason, RequestContext requestContext) - throws ResponseException { - if (!this.roomProviderMapService.getRoomProviderMapByUuid(roomProviderMap.getUuid()).isPresent()) { - throw new ObjectNotFoundException("Could not find provider's room with uuid " + roomProviderMap.getUuid()); - } - this.roomProviderMapService.voidRoomProviderMap(roomProviderMap.getUuid(), voidReason); + protected void delete(RoomProviderMap rpm, String voidReason, RequestContext context) throws ResponseException { + services.getRoomProviderMapService().voidRoomProviderMap(rpm, voidReason); } @Override @@ -68,23 +80,21 @@ public RoomProviderMap newDelegate() { @Override public RoomProviderMap save(RoomProviderMap roomProviderMap) { - return roomProviderMapService.createRoomProviderMap(roomProviderMap); + return services.getRoomProviderMapService().saveRoomProviderMap(roomProviderMap); } @Override public void purge(RoomProviderMap roomProviderMap, RequestContext requestContext) throws ResponseException { - this.roomProviderMapService.purgeRoomProviderMap(roomProviderMap); + services.getRoomProviderMapService().purgeRoomProviderMap(roomProviderMap); } @Override - protected PageableResult doSearch(RequestContext context) { - Provider provider = context.getParameter("provider") != null - ? Context.getProviderService().getProviderByUuid(context.getParameter("provider")) - : null; - QueueRoom queueRoom = context.getParameter("queueRoom") != null - ? Context.getService(QueueRoomService.class).getQueueRoomByUuid(context.getParameter("queueRoom")).get() - : null; - return new NeedsPaging<>(roomProviderMapService.getRoomProvider(provider, queueRoom), context); + @SuppressWarnings("unchecked") + protected PageableResult doSearch(RequestContext requestContext) { + Map parameters = requestContext.getRequest().getParameterMap(); + RoomProviderMapSearchCriteria criteria = searchCriteriaParser.constructFromRequest(parameters); + List rpms = services.getRoomProviderMapService().getRoomProviderMaps(criteria); + return new NeedsPaging<>(rpms, requestContext); } @Override diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/VisitQueueEntryResource.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/VisitQueueEntryResource.java deleted file mode 100644 index b3711da..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/VisitQueueEntryResource.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources; - -import javax.validation.constraints.NotNull; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Optional; - -import lombok.extern.slf4j.Slf4j; -import org.openmrs.api.context.Context; -import org.openmrs.module.queue.api.VisitQueueEntryService; -import org.openmrs.module.queue.model.VisitQueueEntry; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.annotation.Resource; -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.RefRepresentation; -import org.openmrs.module.webservices.rest.web.representation.Representation; -import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; -import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; -import org.openmrs.module.webservices.rest.web.response.ObjectNotFoundException; -import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; - -/** - * By convention, resource names should use exclusively lowercase letters. Similarly, dashes (-) are - * conventionally used in place of underscores (_). - */ -@Slf4j -@SuppressWarnings("unused") -@Resource(name = RestConstants.VERSION_1 - + "/visit-queue-entry", supportedClass = VisitQueueEntry.class, supportedOpenmrsVersions = { "2.3 - 9.*" }) -public class VisitQueueEntryResource extends DelegatingCrudResource { - - private final VisitQueueEntryService visitQueueEntryService; - - public VisitQueueEntryResource() { - this.visitQueueEntryService = Context.getService(VisitQueueEntryService.class); - } - - @Override - public VisitQueueEntry getByUniqueId(@NotNull String uuid) { - Optional visitQueueEntryOptional = this.visitQueueEntryService.getVisitQueueEntryByUuid(uuid); - if (!visitQueueEntryOptional.isPresent()) { - throw new ObjectNotFoundException("Could not find visit queue entry with uuid " + uuid); - } - return visitQueueEntryOptional.get(); - } - - @Override - protected void delete(VisitQueueEntry visitQueueEntry, String voidReason, RequestContext requestContext) - throws ResponseException { - this.visitQueueEntryService.voidVisitQueueEntry(visitQueueEntry.getUuid(), voidReason); - } - - @Override - public VisitQueueEntry newDelegate() { - return new VisitQueueEntry(); - } - - @Override - public VisitQueueEntry save(VisitQueueEntry visitQueueEntry) { - return this.visitQueueEntryService.createVisitQueueEntry(visitQueueEntry); - } - - @Override - public void purge(VisitQueueEntry visitQueueEntry, RequestContext requestContext) throws ResponseException { - this.visitQueueEntryService.purgeQueueEntry(visitQueueEntry); - } - - @Override - protected PageableResult doGetAll(RequestContext requestContext) throws ResponseException { - return new NeedsPaging<>(new ArrayList<>(this.visitQueueEntryService.getActiveVisitQueueEntries()), requestContext); - } - - @Override - protected PageableResult doSearch(RequestContext requestContext) { - String status = requestContext.getParameter("status"); - String service = requestContext.getParameter("service"); - String location = requestContext.getParameter("location"); - String patient = requestContext.getParameter("patient"); - //Both status,location,patient & service are nullable - Collection visitQueueEntries = this.visitQueueEntryService.findVisitQueueEntries(status, service, - location, patient); - return new NeedsPaging<>(new ArrayList<>(visitQueueEntries), requestContext); - } - - @Override - public DelegatingResourceDescription getCreatableProperties() throws ResourceDoesNotSupportOperationException { - DelegatingResourceDescription resourceDescription = new DelegatingResourceDescription(); - resourceDescription.addProperty("visit"); - resourceDescription.addProperty("queueEntry"); - return resourceDescription; - } - - @Override - public DelegatingResourceDescription getRepresentationDescription(Representation representation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - if (representation instanceof RefRepresentation) { - this.addSharedResourceDescriptionProperties(description); - description.addProperty("visit", Representation.REF); - description.addProperty("queueEntry", Representation.REF); - description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); - } else if (representation instanceof DefaultRepresentation) { - this.addSharedResourceDescriptionProperties(description); - description.addProperty("visit", Representation.DEFAULT); - description.addProperty("queueEntry", Representation.DEFAULT); - description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); - } else if (representation instanceof FullRepresentation) { - this.addSharedResourceDescriptionProperties(description); - description.addProperty("visit", Representation.FULL); - description.addProperty("queueEntry", Representation.FULL); - description.addProperty("auditInfo"); - } else if (representation instanceof CustomRepresentation) { - description = null; - } - return description; - } - - private void addSharedResourceDescriptionProperties(DelegatingResourceDescription resourceDescription) { - resourceDescription.addSelfLink(); - resourceDescription.addProperty("uuid"); - } - - @Override - public String getResourceVersion() { - return "2.3"; - } -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/GenericSingleObjectResult.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/GenericSingleObjectResult.java deleted file mode 100644 index 65fed37..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/GenericSingleObjectResult.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources.custom.response; - -import javax.validation.constraints.NotNull; - -import java.util.ArrayList; -import java.util.List; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.resource.api.Converter; -import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; -import org.openmrs.module.webservices.rest.web.response.ResponseException; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class GenericSingleObjectResult implements PageableResult { - - private List propValues; - - @Override - public SimpleObject toSimpleObject(Converter converter) throws ResponseException { - SimpleObject ret = new SimpleObject(); - this.propValues.forEach(propValue -> ret.add(propValue.getProperty(), propValue.getValue())); - return ret; - } - - public void add(@NotNull String property, @NotNull Object value) { - if (propValues == null) { - this.propValues = new ArrayList<>(); - } - this.propValues.add(new PropValue(property, value)); - } -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/PropValue.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/PropValue.java deleted file mode 100644 index c825cb2..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/PropValue.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources.custom.response; - -import java.io.Serializable; - -import lombok.AllArgsConstructor; -import lombok.Data; - -/** - * Wrapper data class for property & value - */ -@Data -@AllArgsConstructor -public class PropValue implements Serializable { - - private static final long serialVersionUID = 45L; - - private String property; - - private Object value; -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/QueueEntryCount.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/QueueEntryCount.java deleted file mode 100644 index 09949ed..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/QueueEntryCount.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources.custom.response; - -import java.io.Serializable; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.openmrs.module.queue.model.Queue; - -//Superfluous class. -//For some reason, rest gets confused with multiple subResources -@Data -@NoArgsConstructor -@AllArgsConstructor -public class QueueEntryCount implements Serializable { - - private static final long serialVersionUID = 45L; - - private Queue queue; -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/QueueEntryMetric.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/QueueEntryMetric.java deleted file mode 100644 index 25a553b..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/QueueEntryMetric.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources.custom.response; - -import java.io.Serializable; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@AllArgsConstructor -@NoArgsConstructor -public class QueueEntryMetric implements Serializable { - - private static final long serialVersionUID = 45345L; - - private String metric; - - private int count; - -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/QueueEntryNumber.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/QueueEntryNumber.java deleted file mode 100644 index 2851367..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/QueueEntryNumber.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources.custom.response; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@AllArgsConstructor -@NoArgsConstructor -public class QueueEntryNumber { - - private static final long serialVersionUID = 45345L; - - private String serviceType; - - private int visitQueueNumber; -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/QueueMetric.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/QueueMetric.java deleted file mode 100644 index 70ebb34..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/custom/response/QueueMetric.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources.custom.response; - -import java.io.Serializable; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@AllArgsConstructor -@NoArgsConstructor -public class QueueMetric implements Serializable { - - private static final long serialVersionUID = 45345L; - - private String metric; - - private int averageWaitTime; -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/parser/QueueEntrySearchCriteriaParser.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/parser/QueueEntrySearchCriteriaParser.java new file mode 100644 index 0000000..c65dff8 --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/queue/web/resources/parser/QueueEntrySearchCriteriaParser.java @@ -0,0 +1,184 @@ +/* + * 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. + */ +package org.openmrs.module.queue.web.resources.parser; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; +import org.openmrs.Location; +import org.openmrs.Provider; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.QueueEntrySearchCriteria; +import org.openmrs.module.queue.utils.QueueUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Utility class for static methods useful within the Queue module + */ +@Slf4j +@Component +public class QueueEntrySearchCriteriaParser { + + public static final String SEARCH_PARAM_QUEUE = "queue"; + + public static final String SEARCH_PARAM_LOCATION = "location"; + + public static final String SEARCH_PARAM_SERVICE = "service"; + + public static final String SEARCH_PARAM_PATIENT = "patient"; + + public static final String SEARCH_PARAM_VISIT = "visit"; + + public static final String SEARCH_PARAM_HAS_VISIT = "hasVisit"; + + public static final String SEARCH_PARAM_PRIORITY = "priority"; + + public static final String SEARCH_PARAM_STATUS = "status"; + + public static final String SEARCH_PARAM_LOCATION_WAITING_FOR = "locationWaitingFor"; + + public static final String SEARCH_PARAM_PROVIDER_WAITING_FOR = "providerWaitingFor"; + + public static final String SEARCH_PARAM_QUEUE_COMING_FROM = "queueComingFrom"; + + public static final String SEARCH_PARAM_STARTED_ON_OR_AFTER = "startedOnOrAfter"; + + public static final String SEARCH_PARAM_STARTED_ON_OR_BEFORE = "startedOnOrBefore"; + + public static final String SEARCH_PARAM_IS_ENDED = "isEnded"; + + public static final String SEARCH_PARAM_ENDED_ON_OR_AFTER = "endedOnOrAfter"; + + public static final String SEARCH_PARAM_ENDED_ON_OR_BEFORE = "endedOnOrBefore"; + + public static final String SEARCH_PARAM_INCLUDE_VOIDED = "includedVoided"; + + public static final List SEARCH_PARAMETERS = Arrays.asList(SEARCH_PARAM_QUEUE, SEARCH_PARAM_LOCATION, + SEARCH_PARAM_SERVICE, SEARCH_PARAM_PATIENT, SEARCH_PARAM_VISIT, SEARCH_PARAM_HAS_VISIT, SEARCH_PARAM_PRIORITY, + SEARCH_PARAM_STATUS, SEARCH_PARAM_LOCATION_WAITING_FOR, SEARCH_PARAM_PROVIDER_WAITING_FOR, + SEARCH_PARAM_QUEUE_COMING_FROM, SEARCH_PARAM_STARTED_ON_OR_AFTER, SEARCH_PARAM_STARTED_ON_OR_BEFORE, + SEARCH_PARAM_IS_ENDED, SEARCH_PARAM_ENDED_ON_OR_AFTER, SEARCH_PARAM_ENDED_ON_OR_BEFORE, SEARCH_PARAM_INCLUDE_VOIDED); + + private final QueueServicesWrapper services; + + @Autowired + public QueueEntrySearchCriteriaParser(QueueServicesWrapper services) { + this.services = services; + } + + /** + * @param parameterMap a Map from parameter name to array of parameter values + * @return true if the parameterMap contains at least one search parameter as a key + */ + public boolean hasSearchParameter(Map parameterMap) { + for (String parameterName : parameterMap.keySet()) { + if (SEARCH_PARAMETERS.contains(parameterName)) { + return true; + } + } + return false; + } + + /** + * @param parameterMap a Map from parameter name to array of parameter values + * @return QueueEntrySearchCriteria that is configured based on the parameters in the request + */ + public QueueEntrySearchCriteria constructFromRequest(Map parameterMap) { + QueueEntrySearchCriteria criteria = new QueueEntrySearchCriteria(); + if (parameterMap == null) { + return criteria; + } + for (String parameterName : parameterMap.keySet()) { + switch (parameterName) { + case SEARCH_PARAM_QUEUE: { + criteria.setQueues(services.getQueues(parameterMap.get(SEARCH_PARAM_QUEUE))); + break; + } + case SEARCH_PARAM_LOCATION: { + criteria.setLocations(services.getLocations(parameterMap.get(SEARCH_PARAM_LOCATION))); + break; + } + case SEARCH_PARAM_SERVICE: { + criteria.setServices(services.getConcepts(parameterMap.get(SEARCH_PARAM_SERVICE))); + break; + } + case SEARCH_PARAM_PATIENT: { + criteria.setPatient(services.getPatient(parameterMap.get(SEARCH_PARAM_PATIENT)[0])); + break; + } + case SEARCH_PARAM_VISIT: { + criteria.setVisit(services.getVisit(parameterMap.get(SEARCH_PARAM_VISIT)[0])); + break; + } + case SEARCH_PARAM_HAS_VISIT: { + criteria.setHasVisit(Boolean.parseBoolean(parameterMap.get(SEARCH_PARAM_HAS_VISIT)[0])); + break; + } + case SEARCH_PARAM_PRIORITY: { + criteria.setPriorities(services.getConcepts(parameterMap.get(SEARCH_PARAM_PRIORITY))); + break; + } + case SEARCH_PARAM_STATUS: { + criteria.setStatuses(services.getConcepts(parameterMap.get(SEARCH_PARAM_STATUS))); + break; + } + case SEARCH_PARAM_LOCATION_WAITING_FOR: { + List l = services.getLocations(parameterMap.get(SEARCH_PARAM_LOCATION_WAITING_FOR)); + criteria.setLocationsWaitingFor(l); + break; + } + case SEARCH_PARAM_PROVIDER_WAITING_FOR: { + List l = services.getProviders(parameterMap.get(SEARCH_PARAM_PROVIDER_WAITING_FOR)); + criteria.setProvidersWaitingFor(l); + break; + } + case SEARCH_PARAM_QUEUE_COMING_FROM: { + criteria.setQueuesComingFrom(services.getQueues(parameterMap.get(SEARCH_PARAM_QUEUE_COMING_FROM))); + break; + } + case SEARCH_PARAM_STARTED_ON_OR_AFTER: { + String date = parameterMap.get(SEARCH_PARAM_STARTED_ON_OR_AFTER)[0]; + criteria.setStartedOnOrAfter(QueueUtils.parseDate(date)); + break; + } + case SEARCH_PARAM_STARTED_ON_OR_BEFORE: { + String date = parameterMap.get(SEARCH_PARAM_STARTED_ON_OR_BEFORE)[0]; + criteria.setStartedOnOrBefore(QueueUtils.parseDate(date)); + break; + } + case SEARCH_PARAM_ENDED_ON_OR_AFTER: { + String date = parameterMap.get(SEARCH_PARAM_ENDED_ON_OR_AFTER)[0]; + criteria.setEndedOnOrAfter(QueueUtils.parseDate(date)); + break; + } + case SEARCH_PARAM_ENDED_ON_OR_BEFORE: { + String date = parameterMap.get(SEARCH_PARAM_ENDED_ON_OR_BEFORE)[0]; + criteria.setEndedOnOrBefore(QueueUtils.parseDate(date)); + break; + } + case SEARCH_PARAM_IS_ENDED: { + criteria.setIsEnded(Boolean.parseBoolean(parameterMap.get(SEARCH_PARAM_IS_ENDED)[0])); + break; + } + case SEARCH_PARAM_INCLUDE_VOIDED: { + criteria.setIncludedVoided(Boolean.parseBoolean(parameterMap.get(SEARCH_PARAM_INCLUDE_VOIDED)[0])); + break; + } + default: { + log.debug("Unhandled search parameter found: " + parameterName); + } + } + } + return criteria; + } +} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/parser/QueueRoomSearchCriteriaParser.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/parser/QueueRoomSearchCriteriaParser.java new file mode 100644 index 0000000..62205e9 --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/queue/web/resources/parser/QueueRoomSearchCriteriaParser.java @@ -0,0 +1,88 @@ +/* + * 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. + */ +package org.openmrs.module.queue.web.resources.parser; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.QueueRoomSearchCriteria; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Utility class for static methods useful within the Queue module + */ +@Slf4j +@Component +public class QueueRoomSearchCriteriaParser { + + public static final String SEARCH_PARAM_QUEUE = "queue"; + + public static final String SEARCH_PARAM_LOCATION = "location"; + + public static final String SEARCH_PARAM_SERVICE = "service"; + + public static final List SEARCH_PARAMETERS = Arrays.asList(SEARCH_PARAM_QUEUE, SEARCH_PARAM_LOCATION, + SEARCH_PARAM_SERVICE); + + private final QueueServicesWrapper services; + + @Autowired + public QueueRoomSearchCriteriaParser(QueueServicesWrapper services) { + this.services = services; + } + + /** + * @param parameterMap a Map from parameter name to array of parameter values + * @return true if the parameterMap contains at least one search parameter as a key + */ + public boolean hasSearchParameter(Map parameterMap) { + for (String parameterName : parameterMap.keySet()) { + if (SEARCH_PARAMETERS.contains(parameterName)) { + return true; + } + } + return false; + } + + /** + * @param parameterMap a Map from parameter name to array of parameter values + * @return QueueRoomSearchCriteria that is configured based on the parameters in the request + */ + public QueueRoomSearchCriteria constructFromRequest(Map parameterMap) { + QueueRoomSearchCriteria criteria = new QueueRoomSearchCriteria(); + if (parameterMap == null) { + return criteria; + } + for (String parameterName : parameterMap.keySet()) { + switch (parameterName) { + case SEARCH_PARAM_QUEUE: { + criteria.setQueues(services.getQueues(parameterMap.get(SEARCH_PARAM_QUEUE))); + break; + } + case SEARCH_PARAM_LOCATION: { + criteria.setLocations(services.getLocations(parameterMap.get(SEARCH_PARAM_LOCATION))); + break; + } + case SEARCH_PARAM_SERVICE: { + criteria.setServices(services.getConcepts(parameterMap.get(SEARCH_PARAM_SERVICE))); + break; + } + default: { + log.debug("Unhandled search parameter found: " + parameterName); + } + } + } + return criteria; + } +} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/parser/QueueSearchCriteriaParser.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/parser/QueueSearchCriteriaParser.java new file mode 100644 index 0000000..c62da1d --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/queue/web/resources/parser/QueueSearchCriteriaParser.java @@ -0,0 +1,81 @@ +/* + * 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. + */ +package org.openmrs.module.queue.web.resources.parser; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.QueueSearchCriteria; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Utility class for static methods useful within the Queue module + */ +@Slf4j +@Component +public class QueueSearchCriteriaParser { + + public static final String SEARCH_PARAM_LOCATION = "location"; + + public static final String SEARCH_PARAM_SERVICE = "service"; + + public static final List SEARCH_PARAMETERS = Arrays.asList(SEARCH_PARAM_LOCATION, SEARCH_PARAM_SERVICE); + + private final QueueServicesWrapper services; + + @Autowired + public QueueSearchCriteriaParser(QueueServicesWrapper services) { + this.services = services; + } + + /** + * @param parameterMap a Map from parameter name to array of parameter values + * @return true if the parameterMap contains at least one search parameter as a key + */ + public boolean hasSearchParameter(Map parameterMap) { + for (String parameterName : parameterMap.keySet()) { + if (SEARCH_PARAMETERS.contains(parameterName)) { + return true; + } + } + return false; + } + + /** + * @param parameterMap a Map from parameter name to array of parameter values + * @return QueueSearchCriteria that is configured based on the parameters in the request + */ + public QueueSearchCriteria constructFromRequest(Map parameterMap) { + QueueSearchCriteria criteria = new QueueSearchCriteria(); + if (parameterMap == null) { + return criteria; + } + for (String parameterName : parameterMap.keySet()) { + switch (parameterName) { + case SEARCH_PARAM_LOCATION: { + criteria.setLocations(services.getLocations(parameterMap.get(SEARCH_PARAM_LOCATION))); + break; + } + case SEARCH_PARAM_SERVICE: { + criteria.setServices(services.getConcepts(parameterMap.get(SEARCH_PARAM_SERVICE))); + break; + } + default: { + log.debug("Unhandled search parameter found: " + parameterName); + } + } + } + return criteria; + } +} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/parser/RoomProviderMapSearchCriteriaParser.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/parser/RoomProviderMapSearchCriteriaParser.java new file mode 100644 index 0000000..23eee6c --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/queue/web/resources/parser/RoomProviderMapSearchCriteriaParser.java @@ -0,0 +1,81 @@ +/* + * 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. + */ +package org.openmrs.module.queue.web.resources.parser; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.RoomProviderMapSearchCriteria; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Utility class for static methods useful within the Queue module + */ +@Slf4j +@Component +public class RoomProviderMapSearchCriteriaParser { + + public static final String SEARCH_PARAM_QUEUE_ROOMS = "queueRoom"; + + public static final String SEARCH_PARAM_PROVIDER = "provider"; + + public static final List SEARCH_PARAMETERS = Arrays.asList(SEARCH_PARAM_QUEUE_ROOMS, SEARCH_PARAM_PROVIDER); + + private final QueueServicesWrapper services; + + @Autowired + public RoomProviderMapSearchCriteriaParser(QueueServicesWrapper services) { + this.services = services; + } + + /** + * @param parameterMap a Map from parameter name to array of parameter values + * @return true if the parameterMap contains at least one search parameter as a key + */ + public boolean hasSearchParameter(Map parameterMap) { + for (String parameterName : parameterMap.keySet()) { + if (SEARCH_PARAMETERS.contains(parameterName)) { + return true; + } + } + return false; + } + + /** + * @param parameterMap a Map from parameter name to array of parameter values + * @return QueueEntrySearchCriteria that is configured based on the parameters in the request + */ + public RoomProviderMapSearchCriteria constructFromRequest(Map parameterMap) { + RoomProviderMapSearchCriteria criteria = new RoomProviderMapSearchCriteria(); + if (parameterMap == null) { + return criteria; + } + for (String parameterName : parameterMap.keySet()) { + switch (parameterName) { + case SEARCH_PARAM_QUEUE_ROOMS: { + criteria.setQueueRooms(services.getQueueRooms(parameterMap.get(SEARCH_PARAM_QUEUE_ROOMS))); + break; + } + case SEARCH_PARAM_PROVIDER: { + criteria.setProviders(services.getProviders(parameterMap.get(SEARCH_PARAM_PROVIDER))); + break; + } + default: { + log.debug("Unhandled search parameter found: " + parameterName); + } + } + } + return criteria; + } +} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/search/handlers/InActiveQueueEntrySearchHandler.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/search/handlers/InActiveQueueEntrySearchHandler.java deleted file mode 100644 index e3c3d88..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/search/handlers/InActiveQueueEntrySearchHandler.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources.search.handlers; - -import java.util.ArrayList; -import java.util.Collections; - -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.openmrs.api.context.Context; -import org.openmrs.module.queue.api.VisitQueueEntryService; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; -import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; -import org.openmrs.module.webservices.rest.web.resource.api.SearchHandler; -import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; -import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.springframework.stereotype.Component; - -@Slf4j -@Component -public class InActiveQueueEntrySearchHandler implements SearchHandler { - - private final static SearchConfig SEARCH_CONFIG = new SearchConfig("default", - RestConstants.VERSION_1 + "/visit-queue-entry", Collections.singletonList("2.3 - 9.*"), - new SearchQuery.Builder("Allows you to include/exclude inactive queue entries") - .withOptionalParameters("includeInactive").build()); - - @Override - public SearchConfig getSearchConfig() { - return SEARCH_CONFIG; - } - - @Override - public PageableResult search(RequestContext requestContext) throws ResponseException { - VisitQueueEntryService visitQueueEntryService = Context.getService(VisitQueueEntryService.class); - String includeInactive = requestContext.getParameter("includeInactive"); - - if (!StringUtils.isBlank(includeInactive)) { - try { - boolean includeInactiveQueueEntries = Boolean.parseBoolean(includeInactive); - if (includeInactiveQueueEntries) { - return new NeedsPaging<>(new ArrayList<>(visitQueueEntryService.findAllVisitQueueEntries()), - requestContext); - } else { - return new NeedsPaging<>(new ArrayList<>(visitQueueEntryService.getActiveVisitQueueEntries()), - requestContext); - } - } - catch (Exception exception) { - log.error("Unable to parse string {} " + includeInactive, exception.getMessage(), exception); - } - } - return new NeedsPaging<>(new ArrayList<>(visitQueueEntryService.getActiveVisitQueueEntries()), requestContext); - } -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/search/handlers/QueueCountSearchHandler.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/search/handlers/QueueCountSearchHandler.java deleted file mode 100644 index 7b77d1c..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/search/handlers/QueueCountSearchHandler.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources.search.handlers; - -import java.util.Arrays; -import java.util.Collections; - -import org.apache.commons.lang3.StringUtils; -import org.openmrs.api.context.Context; -import org.openmrs.module.queue.api.QueueEntryService; -import org.openmrs.module.queue.web.resources.custom.response.GenericSingleObjectResult; -import org.openmrs.module.queue.web.resources.custom.response.PropValue; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; -import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; -import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; -import org.openmrs.module.webservices.rest.web.resource.api.SubResourceSearchHandler; -import org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.springframework.stereotype.Component; - -@Component -public class QueueCountSearchHandler implements SubResourceSearchHandler { - - private final static SearchConfig SEARCH_CONFIG = new SearchConfig("default", RestConstants.VERSION_1 + "/queue/count", - Collections.singletonList("2.3 - 9.*"), - new SearchQuery.Builder("Allows you to find queue entries by status").withOptionalParameters("status").build()); - - @Override - public PageableResult search(String parentUuid, RequestContext requestContext) throws ResponseException { - String queueEntryStatus = requestContext.getParameter("status"); - - if (StringUtils.isBlank(queueEntryStatus) || StringUtils.isBlank(parentUuid)) { - return new EmptySearchResult(); - } - Long queueCount = Context.getService(QueueEntryService.class).getQueueEntriesCountByStatus(queueEntryStatus); - - //Customize results response - return new GenericSingleObjectResult( - Arrays.asList(new PropValue("count", queueCount), new PropValue("queueEntryStatus", queueEntryStatus))); - } - - @Override - public SearchConfig getSearchConfig() { - return SEARCH_CONFIG; - } - - @Override - public PageableResult search(RequestContext requestContext) throws ResponseException { - throw new UnsupportedOperationException("Cannot search for queue entries without parent queue"); - } -} diff --git a/omod/src/main/java/org/openmrs/module/queue/web/resources/search/handlers/QueueEntrySearchHandler.java b/omod/src/main/java/org/openmrs/module/queue/web/resources/search/handlers/QueueEntrySearchHandler.java deleted file mode 100644 index bb9cbb3..0000000 --- a/omod/src/main/java/org/openmrs/module/queue/web/resources/search/handlers/QueueEntrySearchHandler.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources.search.handlers; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; - -import org.apache.commons.lang3.StringUtils; -import org.openmrs.api.context.Context; -import org.openmrs.module.queue.api.QueueEntryService; -import org.openmrs.module.queue.model.QueueEntry; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; -import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; -import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; -import org.openmrs.module.webservices.rest.web.resource.api.SubResourceSearchHandler; -import org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult; -import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.springframework.stereotype.Component; - -@Component -public class QueueEntrySearchHandler implements SubResourceSearchHandler { - - private final static SearchConfig SEARCH_CONFIG = new SearchConfig("default", RestConstants.VERSION_1 + "/queue/entry", - Collections.singletonList("2.3 - 9.*"), - new SearchQuery.Builder("Allows you to find queue entries by status").withOptionalParameters("status").build()); - - @Override - public PageableResult search(String parentUuid, RequestContext requestContext) throws ResponseException { - String status = requestContext.getParameter("status"); - - if (StringUtils.isBlank(status) || StringUtils.isBlank(parentUuid)) { - return new EmptySearchResult(); - } - Collection queueEntries = Context.getService(QueueEntryService.class) - .searchQueueEntriesByConceptStatus(status, false); - return new NeedsPaging<>(new ArrayList<>(queueEntries), requestContext); - } - - @Override - public SearchConfig getSearchConfig() { - return SEARCH_CONFIG; - } - - @Override - public PageableResult search(RequestContext requestContext) throws ResponseException { - throw new UnsupportedOperationException("Cannot search for queue entries without parent queue"); - } -} diff --git a/omod/src/main/resources/config.xml b/omod/src/main/resources/config.xml index bd7b327..3977381 100644 --- a/omod/src/main/resources/config.xml +++ b/omod/src/main/resources/config.xml @@ -23,9 +23,6 @@ ${project.parent.groupId}.${project.parent.artifactId}.QueueModuleActivator - - - 2.3.0 @@ -36,22 +33,6 @@ org.openmrs.module.legacyui - - - - en - messages.properties - - - fr - messages_fr.properties - - - es - messages_es.properties - - - ${project.parent.artifactId}.statusConceptSetName Status diff --git a/omod/src/test/java/org/openmrs/module/queue/web/QueueEntryMetricRestControllerTest.java b/omod/src/test/java/org/openmrs/module/queue/web/QueueEntryMetricRestControllerTest.java new file mode 100644 index 0000000..951fae0 --- /dev/null +++ b/omod/src/test/java/org/openmrs/module/queue/web/QueueEntryMetricRestControllerTest.java @@ -0,0 +1,135 @@ +/* + * 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. + */ +package org.openmrs.module.queue.web; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.openmrs.module.queue.web.QueueEntryMetricRestController.COUNT; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_STATUS; +import static org.powermock.api.mockito.PowerMockito.mock; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import javax.servlet.http.HttpServletRequest; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.api.LocationService; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.module.queue.api.QueueEntryService; +import org.openmrs.module.queue.api.QueueRoomService; +import org.openmrs.module.queue.api.QueueService; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.RoomProviderMapService; +import org.openmrs.module.queue.api.search.QueueEntrySearchCriteria; +import org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.RestUtil; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ Context.class, RestUtil.class }) +public class QueueEntryMetricRestControllerTest { + + private QueueEntryMetricRestController controller; + + @Mock + private QueueService queueService; + + @Mock + private QueueEntryService queueEntryService; + + @Mock + private QueueRoomService queueRoomService; + + @Mock + private RoomProviderMapService roomProviderMapService; + + @Mock + private ConceptService conceptService; + + @Mock + private LocationService locationService; + + @Mock + private PatientService patientService; + + @Mock + private QueueServicesWrapper queueServicesWrapper; + + HttpServletRequest request; + + Map parameterMap; + + ArgumentCaptor queueEntryArgumentCaptor; + + @Before + public void prepareMocks() { + mockStatic(RestUtil.class); + mockStatic(Context.class); + when(queueServicesWrapper.getQueueService()).thenReturn(queueService); + when(queueServicesWrapper.getQueueEntryService()).thenReturn(queueEntryService); + when(queueServicesWrapper.getQueueRoomService()).thenReturn(queueRoomService); + when(queueServicesWrapper.getRoomProviderMapService()).thenReturn(roomProviderMapService); + when(queueServicesWrapper.getConceptService()).thenReturn(conceptService); + when(queueServicesWrapper.getLocationService()).thenReturn(locationService); + when(queueServicesWrapper.getPatientService()).thenReturn(patientService); + + //By pass authentication + when(Context.isAuthenticated()).thenReturn(true); + + QueueEntrySearchCriteriaParser searchCriteriaParser = new QueueEntrySearchCriteriaParser(queueServicesWrapper); + when(Context.getRegisteredComponents(QueueEntrySearchCriteriaParser.class)) + .thenReturn(Collections.singletonList(searchCriteriaParser)); + + when(Context.getRegisteredComponents(QueueServicesWrapper.class)) + .thenReturn(Collections.singletonList(queueServicesWrapper)); + + controller = new QueueEntryMetricRestController(searchCriteriaParser, queueServicesWrapper); + + request = mock(HttpServletRequest.class); + parameterMap = new HashMap<>(); + when(request.getParameterMap()).thenReturn(parameterMap); + queueEntryArgumentCaptor = ArgumentCaptor.forClass(QueueEntrySearchCriteria.class); + when(queueEntryService.getCountOfQueueEntries(any())).thenReturn(50L); + } + + @Test + public void shouldRetrieveCountOfQueueEntriesByStatus() { + List vals = Arrays.asList(new Concept(), new Concept()); + String[] refs = new String[] { "ref1", "ref2" }; + parameterMap.put(SEARCH_PARAM_STATUS, refs); + parameterMap.put(QueueEntryMetricRestController.METRIC, new String[] { COUNT }); + when(queueServicesWrapper.getConcepts(refs)).thenReturn(vals); + SimpleObject result = (SimpleObject) controller.handleRequest(request); + assertThat(result.get(COUNT), equalTo(50)); + verify(queueEntryService).getCountOfQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getStatuses(), hasSize(2)); + assertThat(criteria.getStatuses(), containsInAnyOrder(vals.get(0), vals.get(1))); + } +} diff --git a/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueEntryMetricsResourceTest.java b/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueEntryMetricsResourceTest.java deleted file mode 100644 index 4bd7e11..0000000 --- a/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueEntryMetricsResourceTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.when; -import static org.powermock.api.mockito.PowerMockito.mock; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.openmrs.api.context.Context; -import org.openmrs.module.queue.api.VisitQueueEntryService; -import org.openmrs.module.queue.web.resources.custom.response.GenericSingleObjectResult; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestUtil; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ Context.class, RestUtil.class }) -public class QueueEntryMetricsResourceTest { - - private static final String STATUS = "Waiting"; - - private static final String SERVICE = "triage"; - - private QueueEntryMetricsResource resource; - - @Mock - private VisitQueueEntryService visitQueueEntryService; - - @Before - public void prepareMocks() { - PowerMockito.mockStatic(RestUtil.class); - PowerMockito.mockStatic(Context.class); - - resource = new QueueEntryMetricsResource(); - //By pass authentication - when(Context.isAuthenticated()).thenReturn(true); - when(Context.getService(VisitQueueEntryService.class)).thenReturn(visitQueueEntryService); - } - - @Test - public void shouldReturnQueueEntryMetricsByStatus() { - RequestContext requestContext = mock(RequestContext.class); - - when(visitQueueEntryService.getVisitQueueEntriesCountByStatus(STATUS)).thenReturn(0L); - when(requestContext.getParameter("status")).thenReturn(STATUS); - - GenericSingleObjectResult result = (GenericSingleObjectResult) resource.doSearch(requestContext); - - assertThat(result, notNullValue()); - assertThat(result.getPropValues(), hasSize(2)); - assertTrue(result.getPropValues().stream().anyMatch((propValue -> propValue.getValue().equals(0L)))); - } - - @Test - public void shouldReturnQueueEntryMetricsByService() { - RequestContext requestContext = mock(RequestContext.class); - - when(visitQueueEntryService.getVisitQueueEntriesCountByStatus(SERVICE)).thenReturn(0L); - when(requestContext.getParameter("service")).thenReturn(SERVICE); - - GenericSingleObjectResult result = (GenericSingleObjectResult) resource.doSearch(requestContext); - - assertThat(result, notNullValue()); - assertThat(result.getPropValues(), hasSize(2)); - assertTrue(result.getPropValues().stream().anyMatch((propValue -> propValue.getValue().equals(0L)))); - } - -} diff --git a/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueEntryResourceTest.java b/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueEntryResourceTest.java index 61697b5..21f5cfc 100644 --- a/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueEntryResourceTest.java +++ b/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueEntryResourceTest.java @@ -10,58 +10,158 @@ package org.openmrs.module.queue.web.resources; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.Mockito.verify; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_ENDED_ON_OR_AFTER; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_ENDED_ON_OR_BEFORE; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_HAS_VISIT; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_INCLUDE_VOIDED; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_IS_ENDED; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_LOCATION; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_LOCATION_WAITING_FOR; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_PATIENT; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_PRIORITY; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_PROVIDER_WAITING_FOR; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_QUEUE; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_QUEUE_COMING_FROM; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_SERVICE; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_STARTED_ON_OR_AFTER; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_STARTED_ON_OR_BEFORE; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_STATUS; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_VISIT; import static org.powermock.api.mockito.PowerMockito.mock; +import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; +import javax.servlet.http.HttpServletRequest; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Optional; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.Location; +import org.openmrs.Patient; +import org.openmrs.Provider; +import org.openmrs.Visit; +import org.openmrs.api.ConceptService; +import org.openmrs.api.LocationService; +import org.openmrs.api.PatientService; import org.openmrs.api.context.Context; import org.openmrs.module.queue.api.QueueEntryService; +import org.openmrs.module.queue.api.QueueRoomService; +import org.openmrs.module.queue.api.QueueService; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.RoomProviderMapService; +import org.openmrs.module.queue.api.search.QueueEntrySearchCriteria; +import org.openmrs.module.queue.model.Queue; import org.openmrs.module.queue.model.QueueEntry; +import org.openmrs.module.queue.utils.QueueUtils; +import org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestUtil; 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.RefRepresentation; +import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) -public class QueueEntryResourceTest extends BaseQueueResourceTest { +@PrepareForTest({ Context.class, RestUtil.class }) +public class QueueEntryResourceTest extends BaseQueueResourceTest { private static final String QUEUE_ENTRY_UUID = "6hje567a-fca0-11e5-9e59-08002719a7"; + private QueueEntryResource resource; + + private QueueEntry queueEntry; + + @Mock + private QueueService queueService; + @Mock private QueueEntryService queueEntryService; - private QueueEntry queueEntry; + @Mock + private QueueRoomService queueRoomService; + + @Mock + private RoomProviderMapService roomProviderMapService; + + @Mock + private ConceptService conceptService; + + @Mock + private LocationService locationService; + + @Mock + private PatientService patientService; + + @Mock + private QueueServicesWrapper queueServicesWrapper; + + RequestContext requestContext; + + HttpServletRequest request; + + Map parameterMap; + + ArgumentCaptor queueEntryArgumentCaptor; @Before - public void setup() { - this.prepareMocks(); - queueEntry = mock(QueueEntry.class); + public void prepareMocks() { + mockStatic(RestUtil.class); + mockStatic(Context.class); + when(queueServicesWrapper.getQueueService()).thenReturn(queueService); + when(queueServicesWrapper.getQueueEntryService()).thenReturn(queueEntryService); + when(queueServicesWrapper.getQueueRoomService()).thenReturn(queueRoomService); + when(queueServicesWrapper.getRoomProviderMapService()).thenReturn(roomProviderMapService); + when(queueServicesWrapper.getConceptService()).thenReturn(conceptService); + when(queueServicesWrapper.getLocationService()).thenReturn(locationService); + when(queueServicesWrapper.getPatientService()).thenReturn(patientService); - when(queueEntry.getUuid()).thenReturn(QUEUE_ENTRY_UUID); - when(Context.getService(QueueEntryService.class)).thenReturn(queueEntryService); + //By pass authentication + when(Context.isAuthenticated()).thenReturn(true); - this.setResource(new QueueEntrySubResource()); - this.setObject(queueEntry); - } - - @Test - public void shouldGetQueueEntryService() { - assertThat(queueEntryService, notNullValue()); + when(Context.getRegisteredComponents(QueueServicesWrapper.class)) + .thenReturn(Collections.singletonList(queueServicesWrapper)); + + QueueEntrySearchCriteriaParser searchCriteriaParser = new QueueEntrySearchCriteriaParser(queueServicesWrapper); + when(Context.getRegisteredComponents(QueueEntrySearchCriteriaParser.class)) + .thenReturn(Collections.singletonList(searchCriteriaParser)); + + resource = new QueueEntryResource(); + setResource(resource); + queueEntry = new QueueEntry(); + queueEntry.setUuid(QUEUE_ENTRY_UUID); + setObject(queueEntry); + + requestContext = mock(RequestContext.class); + request = mock(HttpServletRequest.class); + when(requestContext.getRequest()).thenReturn(request); + parameterMap = new HashMap<>(); + when(request.getParameterMap()).thenReturn(parameterMap); + queueEntryArgumentCaptor = ArgumentCaptor.forClass(QueueEntrySearchCriteria.class); } @Test public void shouldReturnDefaultRepresentation() { - verifyDefaultRepresentation("uuid", "priority", "priorityComment", "sortWeight", "patient", "locationWaitingFor", - "providerWaitingFor", "startedAt", "endedAt", "display"); + verifyDefaultRepresentation("uuid", "queue", "status", "visit", "priority", "priorityComment", "sortWeight", + "patient", "locationWaitingFor", "providerWaitingFor", "startedAt", "endedAt", "display"); } @Test @@ -94,7 +194,6 @@ public void shouldNOTReturnNullForRefRepresentation() { @Test public void shouldGetResourceByUniqueUuid() { when(queueEntryService.getQueueEntryByUuid(QUEUE_ENTRY_UUID)).thenReturn(Optional.of(queueEntry)); - QueueEntry result = getResource().getByUniqueId(QUEUE_ENTRY_UUID); assertThat(result, notNullValue()); assertThat(result.getUuid(), is(QUEUE_ENTRY_UUID)); @@ -102,13 +201,234 @@ public void shouldGetResourceByUniqueUuid() { @Test public void shouldCreateNewResource() { - when(queueEntryService.createQueueEntry(getObject())).thenReturn(getObject()); - + when(queueEntryService.saveQueueEntry(getObject())).thenReturn(getObject()); QueueEntry newlyCreatedObject = getResource().save(getObject()); assertThat(newlyCreatedObject, notNullValue()); assertThat(newlyCreatedObject.getUuid(), is(QUEUE_ENTRY_UUID)); } + @Test + public void shouldSearchQueueEntriesByQueue() { + List vals = Arrays.asList(new Queue(), new Queue()); + String[] refs = new String[] { "ref1", "ref2" }; + parameterMap.put(SEARCH_PARAM_QUEUE, refs); + when(queueServicesWrapper.getQueues(refs)).thenReturn(vals); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getQueues(), hasSize(2)); + assertThat(criteria.getQueues(), containsInAnyOrder(vals.get(0), vals.get(1))); + } + + @Test + public void shouldSearchQueueEntriesByLocation() { + List vals = Arrays.asList(new Location(), new Location()); + String[] refs = new String[] { "ref1", "ref2" }; + parameterMap.put(SEARCH_PARAM_LOCATION, refs); + when(queueServicesWrapper.getLocations(refs)).thenReturn(vals); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getLocations(), hasSize(2)); + assertThat(criteria.getLocations(), containsInAnyOrder(vals.get(0), vals.get(1))); + } + + @Test + public void shouldSearchQueueEntriesByService() { + List vals = Arrays.asList(new Concept(), new Concept()); + String[] refs = new String[] { "ref1", "ref2" }; + parameterMap.put(SEARCH_PARAM_SERVICE, refs); + when(queueServicesWrapper.getConcepts(refs)).thenReturn(vals); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getServices(), hasSize(2)); + assertThat(criteria.getServices(), containsInAnyOrder(vals.get(0), vals.get(1))); + } + + @Test + public void shouldSearchQueueEntriesByPatient() { + Patient val = new Patient(); + String[] refs = new String[] { "ref1" }; + parameterMap.put(SEARCH_PARAM_PATIENT, refs); + when(queueServicesWrapper.getPatient(refs[0])).thenReturn(val); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getPatient(), notNullValue()); + } + + @Test + public void shouldSearchQueueEntriesByVisit() { + Visit val = new Visit(); + String[] refs = new String[] { "ref1" }; + parameterMap.put(SEARCH_PARAM_VISIT, refs); + when(queueServicesWrapper.getVisit(refs[0])).thenReturn(val); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getVisit(), notNullValue()); + } + + @Test + public void shouldSearchQueueEntriesByHasVisitTrue() { + parameterMap.put(SEARCH_PARAM_HAS_VISIT, new String[] { "true" }); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getHasVisit(), equalTo(true)); + } + + @Test + public void shouldSearchQueueEntriesByHasVisitFalse() { + parameterMap.put(SEARCH_PARAM_HAS_VISIT, new String[] { "false" }); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getHasVisit(), equalTo(false)); + } + + @Test + public void shouldSearchQueueEntriesByPriority() { + List vals = Arrays.asList(new Concept(), new Concept()); + String[] refs = new String[] { "ref1", "ref2" }; + parameterMap.put(SEARCH_PARAM_PRIORITY, refs); + when(queueServicesWrapper.getConcepts(refs)).thenReturn(vals); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getPriorities(), hasSize(2)); + assertThat(criteria.getPriorities(), containsInAnyOrder(vals.get(0), vals.get(1))); + } + + @Test + public void shouldSearchQueueEntriesByStatus() { + List vals = Arrays.asList(new Concept(), new Concept()); + String[] refs = new String[] { "ref1", "ref2" }; + parameterMap.put(SEARCH_PARAM_STATUS, refs); + when(queueServicesWrapper.getConcepts(refs)).thenReturn(vals); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getStatuses(), hasSize(2)); + assertThat(criteria.getStatuses(), containsInAnyOrder(vals.get(0), vals.get(1))); + } + + @Test + public void shouldSearchQueueEntriesByLocationWaitingFor() { + List vals = Arrays.asList(new Location(), new Location()); + String[] refs = new String[] { "ref1", "ref2" }; + parameterMap.put(SEARCH_PARAM_LOCATION_WAITING_FOR, refs); + when(queueServicesWrapper.getLocations(refs)).thenReturn(vals); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getLocationsWaitingFor(), hasSize(2)); + assertThat(criteria.getLocationsWaitingFor(), containsInAnyOrder(vals.get(0), vals.get(1))); + } + + @Test + public void shouldSearchQueueEntriesByProviderWaitingFor() { + List vals = Arrays.asList(new Provider(), new Provider()); + String[] refs = new String[] { "ref1", "ref2" }; + parameterMap.put(SEARCH_PARAM_PROVIDER_WAITING_FOR, refs); + when(queueServicesWrapper.getProviders(refs)).thenReturn(vals); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getProvidersWaitingFor(), hasSize(2)); + assertThat(criteria.getProvidersWaitingFor(), containsInAnyOrder(vals.get(0), vals.get(1))); + } + + @Test + public void shouldSearchQueueEntriesByQueueComingFrom() { + List vals = Arrays.asList(new Queue(), new Queue()); + String[] refs = new String[] { "ref1", "ref2" }; + parameterMap.put(SEARCH_PARAM_QUEUE_COMING_FROM, refs); + when(queueServicesWrapper.getQueues(refs)).thenReturn(vals); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getQueuesComingFrom(), hasSize(2)); + assertThat(criteria.getQueuesComingFrom(), containsInAnyOrder(vals.get(0), vals.get(1))); + } + + @Test + public void shouldSearchQueueEntriesByStartedOnOrAfter() { + String dateStr = "2023-09-10 11:12:13"; + parameterMap.put(SEARCH_PARAM_STARTED_ON_OR_AFTER, new String[] { dateStr }); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getStartedOnOrAfter(), equalTo(QueueUtils.parseDate(dateStr))); + } + + @Test + public void shouldSearchQueueEntriesByStartedOnOrBefore() { + String dateStr = "2023-09-10 11:12:13"; + parameterMap.put(SEARCH_PARAM_STARTED_ON_OR_BEFORE, new String[] { dateStr }); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getStartedOnOrBefore(), equalTo(QueueUtils.parseDate(dateStr))); + } + + @Test + public void shouldSearchQueueEntriesByEndedOnOrAfter() { + String dateStr = "2023-09-10 11:12:13"; + parameterMap.put(SEARCH_PARAM_ENDED_ON_OR_AFTER, new String[] { dateStr }); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getEndedOnOrAfter(), equalTo(QueueUtils.parseDate(dateStr))); + } + + @Test + public void shouldSearchQueueEntriesByEndedOnOrBefore() { + String dateStr = "2023-09-10 11:12:13"; + parameterMap.put(SEARCH_PARAM_ENDED_ON_OR_BEFORE, new String[] { dateStr }); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getEndedOnOrBefore(), equalTo(QueueUtils.parseDate(dateStr))); + } + + @Test + public void shouldSearchQueueEntriesByIsEndedTrue() { + parameterMap.put(SEARCH_PARAM_IS_ENDED, new String[] { "true" }); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getIsEnded(), equalTo(true)); + } + + @Test + public void shouldSearchQueueEntriesByIsEndedFalse() { + parameterMap.put(SEARCH_PARAM_IS_ENDED, new String[] { "false" }); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.getIsEnded(), equalTo(false)); + } + + @Test + public void shouldSearchQueueEntriesByIncludeVoidedTrue() { + parameterMap.put(SEARCH_PARAM_INCLUDE_VOIDED, new String[] { "true" }); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.isIncludedVoided(), equalTo(true)); + } + + @Test + public void shouldSearchQueueEntriesByIncludeVoidedFalse() { + parameterMap.put(SEARCH_PARAM_INCLUDE_VOIDED, new String[] { "false" }); + resource.doSearch(requestContext); + verify(queueEntryService).getQueueEntries(queueEntryArgumentCaptor.capture()); + QueueEntrySearchCriteria criteria = queueEntryArgumentCaptor.getValue(); + assertThat(criteria.isIncludedVoided(), equalTo(false)); + } + @Test public void shouldInstantiateNewDelegate() { assertThat(getResource().newDelegate(), notNullValue()); diff --git a/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueEntrySubResourceTest.java b/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueEntrySubResourceTest.java new file mode 100644 index 0000000..2e9b322 --- /dev/null +++ b/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueEntrySubResourceTest.java @@ -0,0 +1,153 @@ +/* + * 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. + */ +package org.openmrs.module.queue.web.resources; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.powermock.api.mockito.PowerMockito.mock; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.Collections; +import java.util.Optional; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.api.ConceptService; +import org.openmrs.api.LocationService; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.module.queue.api.QueueEntryService; +import org.openmrs.module.queue.api.QueueRoomService; +import org.openmrs.module.queue.api.QueueService; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.RoomProviderMapService; +import org.openmrs.module.queue.model.QueueEntry; +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.RefRepresentation; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +public class QueueEntrySubResourceTest extends BaseQueueResourceTest { + + private static final String QUEUE_ENTRY_UUID = "6hje567a-fca0-11e5-9e59-08002719a7"; + + @Mock + private QueueService queueService; + + @Mock + private QueueEntryService queueEntryService; + + @Mock + private QueueRoomService queueRoomService; + + @Mock + private RoomProviderMapService roomProviderMapService; + + @Mock + private ConceptService conceptService; + + @Mock + private LocationService locationService; + + @Mock + private PatientService patientService; + + @Mock + private QueueServicesWrapper queueServicesWrapper; + + private QueueEntry queueEntry; + + @Before + public void setup() { + this.prepareMocks(); + queueEntry = mock(QueueEntry.class); + when(queueServicesWrapper.getQueueService()).thenReturn(queueService); + when(queueServicesWrapper.getQueueEntryService()).thenReturn(queueEntryService); + when(queueServicesWrapper.getQueueRoomService()).thenReturn(queueRoomService); + when(queueServicesWrapper.getRoomProviderMapService()).thenReturn(roomProviderMapService); + when(queueServicesWrapper.getConceptService()).thenReturn(conceptService); + when(queueServicesWrapper.getLocationService()).thenReturn(locationService); + when(queueServicesWrapper.getPatientService()).thenReturn(patientService); + + when(queueEntry.getUuid()).thenReturn(QUEUE_ENTRY_UUID); + when(Context.getRegisteredComponents(QueueServicesWrapper.class)) + .thenReturn(Collections.singletonList(queueServicesWrapper)); + + this.setResource(new QueueEntrySubResource()); + this.setObject(queueEntry); + } + + @Test + public void shouldReturnDefaultRepresentation() { + verifyDefaultRepresentation("uuid", "status", "visit", "priority", "priorityComment", "sortWeight", "patient", + "locationWaitingFor", "providerWaitingFor", "startedAt", "endedAt", "display"); + } + + @Test + public void shouldReturnFullRepresentation() { + verifyFullRepresentation("status", "priority", "priorityComment", "sortWeight", "patient", "locationWaitingFor", + "providerWaitingFor", "startedAt", "endedAt", "display", "uuid", "display", "auditInfo"); + } + + @Test + public void shouldReturnNullForCustomRepresentation() { + CustomRepresentation customRepresentation = new CustomRepresentation("custom-representation"); + assertThat(getResource().getRepresentationDescription(customRepresentation), is(nullValue())); + } + + @Test + public void shouldNOTReturnNullForDefaultRepresentation() { + assertThat(getResource().getRepresentationDescription(new DefaultRepresentation()), is(notNullValue())); + } + + @Test + public void shouldNOTReturnNullForFullRepresentation() { + assertThat(getResource().getRepresentationDescription(new FullRepresentation()), is(notNullValue())); + } + + @Test + public void shouldNOTReturnNullForRefRepresentation() { + assertThat(getResource().getRepresentationDescription(new RefRepresentation()), is(notNullValue())); + } + + @Test + public void shouldGetResourceByUniqueUuid() { + when(queueEntryService.getQueueEntryByUuid(QUEUE_ENTRY_UUID)).thenReturn(Optional.of(queueEntry)); + + QueueEntry result = getResource().getByUniqueId(QUEUE_ENTRY_UUID); + assertThat(result, notNullValue()); + assertThat(result.getUuid(), is(QUEUE_ENTRY_UUID)); + } + + @Test + public void shouldCreateNewResource() { + when(queueEntryService.saveQueueEntry(getObject())).thenReturn(getObject()); + + QueueEntry newlyCreatedObject = getResource().save(getObject()); + assertThat(newlyCreatedObject, notNullValue()); + assertThat(newlyCreatedObject.getUuid(), is(QUEUE_ENTRY_UUID)); + } + + @Test + public void shouldInstantiateNewDelegate() { + assertThat(getResource().newDelegate(), notNullValue()); + } + + @Test + public void verifyResourceVersion() { + assertThat(getResource().getResourceVersion(), is("2.3")); + } +} diff --git a/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueResourceTest.java b/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueResourceTest.java index 2e58751..a8ef42f 100644 --- a/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueResourceTest.java +++ b/omod/src/test/java/org/openmrs/module/queue/web/resources/QueueResourceTest.java @@ -10,33 +10,46 @@ package org.openmrs.module.queue.web.resources; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +import static org.mockito.Mockito.verify; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_LOCATION; +import static org.openmrs.module.queue.web.resources.parser.QueueEntrySearchCriteriaParser.SEARCH_PARAM_SERVICE; import static org.powermock.api.mockito.PowerMockito.mock; import static org.powermock.api.mockito.PowerMockito.when; +import javax.servlet.http.HttpServletRequest; + +import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Optional; +import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; +import org.openmrs.Concept; import org.openmrs.Location; -import org.openmrs.api.LocationService; -import org.openmrs.api.context.Context; import org.openmrs.module.queue.api.QueueService; +import org.openmrs.module.queue.api.QueueServicesWrapper; +import org.openmrs.module.queue.api.search.QueueSearchCriteria; import org.openmrs.module.queue.model.Queue; +import org.openmrs.module.queue.web.resources.parser.QueueSearchCriteriaParser; import org.openmrs.module.webservices.rest.web.RequestContext; 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.RefRepresentation; -import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @@ -51,10 +64,20 @@ public class QueueResourceTest extends BaseQueueResourceTest parameterMap; + + ArgumentCaptor queueSearchCriteriaCaptor; @Before public void setup() { @@ -63,10 +86,19 @@ public void setup() { queue.setName(QUEUE_NAME); this.prepareMocks(); - when(Context.getService(QueueService.class)).thenReturn(queueService); + when(queueServicesWrapper.getQueueService()).thenReturn(queueService); - this.setResource(new QueueResource()); + QueueSearchCriteriaParser parser = new QueueSearchCriteriaParser(queueServicesWrapper); + resource = new QueueResource(queueServicesWrapper, parser); + this.setResource(resource); this.setObject(queue); + + requestContext = mock(RequestContext.class); + request = mock(HttpServletRequest.class); + when(requestContext.getRequest()).thenReturn(request); + parameterMap = new HashMap<>(); + when(request.getParameterMap()).thenReturn(parameterMap); + queueSearchCriteriaCaptor = ArgumentCaptor.forClass(QueueSearchCriteria.class); } @Test @@ -117,7 +149,7 @@ public void shouldGetResourceByUniqueUuid() { @Test public void shouldCreateNewResource() { - when(queueService.createQueue(getObject())).thenReturn(getObject()); + when(queueService.saveQueue(getObject())).thenReturn(getObject()); Queue newlyCreatedObject = getResource().save(getObject()); assertThat(newlyCreatedObject, notNullValue()); @@ -136,30 +168,34 @@ public void verifyResourceVersion() { } @Test - @SuppressWarnings("unchecked") - public void shouldFindQueuesByLocation() { - Queue queue = mock(Queue.class); - Location location = mock(Location.class); - RequestContext context = mock(RequestContext.class); - - when(Context.getLocationService()).thenReturn(locationService); - when(locationService.getLocationByUuid(LOCATION_UUID)).thenReturn(location); - when(queue.getLocation()).thenReturn(location); - when(location.getUuid()).thenReturn(LOCATION_UUID); - when(context.getParameter("location")).thenReturn(LOCATION_UUID); - when(queueService.getAllQueuesByLocation(LOCATION_UUID)).thenReturn(Collections.singletonList(queue)); - - NeedsPaging result = (NeedsPaging) getResource().doSearch(context); - - assertThat(result, notNullValue()); - assertThat(result.getTotalCount(), is(1L)); - result.getPageOfResults().forEach(q -> assertThat(q.getLocation().getUuid(), is(LOCATION_UUID))); + public void shouldSearchQueueEntriesByLocation() { + List vals = Arrays.asList(new Location(), new Location()); + String[] refs = new String[] { "ref1", "ref2" }; + parameterMap.put(SEARCH_PARAM_LOCATION, refs); + when(queueServicesWrapper.getLocations(refs)).thenReturn(vals); + resource.doSearch(requestContext); + verify(queueService).getQueues(queueSearchCriteriaCaptor.capture()); + QueueSearchCriteria criteria = queueSearchCriteriaCaptor.getValue(); + assertThat(criteria.getLocations(), Matchers.hasSize(2)); + assertThat(criteria.getLocations(), containsInAnyOrder(vals.get(0), vals.get(1))); + } + + @Test + public void shouldSearchQueueEntriesByService() { + List vals = Arrays.asList(new Concept(), new Concept()); + String[] refs = new String[] { "ref1", "ref2" }; + parameterMap.put(SEARCH_PARAM_SERVICE, refs); + when(queueServicesWrapper.getConcepts(refs)).thenReturn(vals); + resource.doSearch(requestContext); + verify(queueService).getQueues(queueSearchCriteriaCaptor.capture()); + QueueSearchCriteria criteria = queueSearchCriteriaCaptor.getValue(); + assertThat(criteria.getServices(), Matchers.hasSize(2)); + assertThat(criteria.getServices(), containsInAnyOrder(vals.get(0), vals.get(1))); } @Test public void shouldGetAllQueues() { Queue queueMock = mock(Queue.class); - when(queueService.getAllQueues()).thenReturn(Collections.singletonList(queueMock)); Collection result = queueService.getAllQueues(); assertThat(result, hasSize(1)); diff --git a/omod/src/test/java/org/openmrs/module/queue/web/resources/VisitQueueEntryResourceTest.java b/omod/src/test/java/org/openmrs/module/queue/web/resources/VisitQueueEntryResourceTest.java deleted file mode 100644 index f010778..0000000 --- a/omod/src/test/java/org/openmrs/module/queue/web/resources/VisitQueueEntryResourceTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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. - */ -package org.openmrs.module.queue.web.resources; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; -import static org.powermock.api.mockito.PowerMockito.mock; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.util.Collections; -import java.util.Optional; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.openmrs.api.context.Context; -import org.openmrs.module.queue.api.VisitQueueEntryService; -import org.openmrs.module.queue.model.VisitQueueEntry; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; -import org.powermock.modules.junit4.PowerMockRunner; - -@SuppressWarnings("unchecked") -@RunWith(PowerMockRunner.class) -public class VisitQueueEntryResourceTest extends BaseQueueResourceTest { - - private static final String VISIT_QUEUE_ENTRY_UUID = "6hje567a-fca0-11e5-9e59-08002719a7"; - - @Mock - private VisitQueueEntryService visitQueueEntryService; - - private VisitQueueEntry visitQueueEntry; - - @Before - public void setup() { - this.prepareMocks(); - visitQueueEntry = mock(VisitQueueEntry.class); - - when(visitQueueEntry.getUuid()).thenReturn(VISIT_QUEUE_ENTRY_UUID); - when(Context.getService(VisitQueueEntryService.class)).thenReturn(visitQueueEntryService); - - this.setResource(new VisitQueueEntryResource()); - this.setObject(visitQueueEntry); - } - - @Test - public void shouldGetQueueEntryService() { - assertThat(visitQueueEntryService, notNullValue()); - } - - @Test - public void shouldGetResourceByUniqueUuid() { - when(visitQueueEntryService.getVisitQueueEntryByUuid(VISIT_QUEUE_ENTRY_UUID)) - .thenReturn(Optional.of(visitQueueEntry)); - - VisitQueueEntry result = getResource().getByUniqueId(VISIT_QUEUE_ENTRY_UUID); - assertThat(result, notNullValue()); - assertThat(result.getUuid(), is(VISIT_QUEUE_ENTRY_UUID)); - } - - @Test - public void shouldCreateNewResource() { - when(visitQueueEntryService.createVisitQueueEntry(getObject())).thenReturn(getObject()); - - VisitQueueEntry newlyCreatedObject = getResource().save(getObject()); - assertThat(newlyCreatedObject, notNullValue()); - assertThat(newlyCreatedObject.getUuid(), is(VISIT_QUEUE_ENTRY_UUID)); - } - - @Test - public void shouldInstantiateNewDelegate() { - assertThat(getResource().newDelegate(), notNullValue()); - } - - @Test - public void shouldReturnAllVisitQueueEntriesFromDb() { - RequestContext requestContext = mock(RequestContext.class); - when(visitQueueEntryService.getActiveVisitQueueEntries()).thenReturn(Collections.singletonList(getObject())); - - NeedsPaging result = (NeedsPaging) getResource().doGetAll(requestContext); - - assertThat(result, notNullValue()); - assertThat(result.getTotalCount(), is(1L)); - } -}