Skip to content

Commit

Permalink
BAH-3860 | Enhancements in Appointments module (#153)
Browse files Browse the repository at this point in the history
* BAH-3350: Appointments: search endpoint stack traces when a patient has more than one identifier of the same time (#142)

* Ability to Filter on Appointments with multi-value support for search keys

Ability to Filter on Awaiting Appointments with multiple values for same keys

* Added test cases to increase branch coverage & set threshold to 0.60 (#152)

Added test cases to increase branch coverage & set threshold to 0.60 (#152)

* Kavitha|Awaiting appointments code refactor (#151)

* BAH-3479 | Backend changes for dateless appointments (#145)

* Kavitha, Umair | A-1204370983916597| add database column and api changes for priority (#104)

* add database column and api changes for priority

Co-authored-by: Umair Fayaz <omayrfayaz@gmail.com>

* add priority to appointment audit

Co-authored-by: Umair Fayaz <omayrfayaz@gmail.com>

* fixed test failure for priority

* add tests for code coverage

---------

Co-authored-by: Umair Fayaz <omayrfayaz@gmail.com>

* Kavitha | A-1204361352115416 | removed invalid priority and related tests (#106)

* removed invalid priority and related tests

* added testcase for invalid priority

* Backend migration to create dateless appointments (#105)

* allow dateless appointments if status is waitlist (#108)

* Kavitha, Umair | A-1204370983916597| add database column and api changes for priority (#104)

* add database column and api changes for priority

* add priority to appointment audit

* fixed test failure for priority

* add tests for code coverage

---------

Co-authored-by: Umair Fayaz <omayrfayaz@gmail.com>

* Kavitha | A-1204361352115416 | removed invalid priority and related tests (#106)

* removed invalid priority and related tests

* added testcase for invalid priority

* Backend migration to create dateless appointments (#105)

* allow dateless appointments if status is waitlist (#108)

* Add logic to filter DateLess Appointments

* add. appointment creation date in response (#109)

* Add tests to filter DateLess Appointments

* Update POM files

* Fix failing Tests for Search appointments

* Kavitha | add date check and tests for waitlist appointments

* Kavitha | removed Invalid priority

* Kavitha | added missed tests from master branch

* Kavitha | rename datelessAppointments to appointmentsWithoutDates

* Kavitha | add default null value to date columns in appt

* Kavitha | removed status check in appointment json

* Kavitha | removed sorting based on status

* Kavitha | removed unused imports

---------

Co-authored-by: Umair Fayaz <omayrfayaz@gmail.com>
Co-authored-by: Phanindra-tw <v.tadikonda@thoughtworks.com>
Co-authored-by: Arjun G <91885483+Arjun-Go@users.noreply.github.com>

* Kavitha | refactor search API for appointments without dates

* Kavitha|lowered test coverage ratio

* add specific imports

---------

Co-authored-by: Umair Fayaz <omayrfayaz@gmail.com>
Co-authored-by: Phanindra-tw <v.tadikonda@thoughtworks.com>
Co-authored-by: Arjun G <91885483+Arjun-Go@users.noreply.github.com>

* BAH-3860 | repeated imports in tests

* BAH-3860 | fix. tests in AppointmentMapper

---------

Co-authored-by: Mark Goodrich <mgoodrich@pih.org>
Co-authored-by: Umair Fayaz <59157924+umair-fayaz@users.noreply.github.com>
Co-authored-by: kalai-tw <104360355+kalai-tw@users.noreply.github.com>
Co-authored-by: kavitha-sundararajan <90255023+kavitha-sundararajan@users.noreply.github.com>
Co-authored-by: Umair Fayaz <omayrfayaz@gmail.com>
Co-authored-by: Phanindra-tw <v.tadikonda@thoughtworks.com>
  • Loading branch information
7 people authored Jun 4, 2024
1 parent 552a579 commit 5b5dd73
Show file tree
Hide file tree
Showing 14 changed files with 349 additions and 80 deletions.
2 changes: 1 addition & 1 deletion api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
<limit>
<counter>BRANCH</counter>
<value>COVEREDRATIO</value>
<minimum>0.35</minimum>
<minimum>0.60</minimum>
</limit>
</limits>
</rule>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package org.openmrs.module.appointments.dao;

import java.util.Date;


import org.openmrs.module.appointments.model.Appointment;
import org.openmrs.module.appointments.model.AppointmentSearchRequest;
import org.openmrs.module.appointments.model.AppointmentSearchRequestModel;
import org.openmrs.module.appointments.model.AppointmentServiceDefinition;
import org.openmrs.module.appointments.model.AppointmentServiceType;
import org.openmrs.module.appointments.model.AppointmentStatus;
import org.openmrs.module.appointments.model.AppointmentSearchRequest;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
Expand All @@ -19,6 +22,8 @@ public interface AppointmentDao {

List<Appointment> search(Appointment appointment);

List<Appointment> search(AppointmentSearchRequestModel searchQuery);

List<Appointment> getAllFutureAppointmentsForService(AppointmentServiceDefinition appointmentServiceDefinition);

List<Appointment> getAllFutureAppointmentsForServiceType(AppointmentServiceType appointmentServiceType);
Expand All @@ -33,5 +38,5 @@ public interface AppointmentDao {

List<Appointment> getAppointmentsForPatient(Integer patientId);

List<Appointment> getAppointmentsWithoutDates(Integer limit);
List<Appointment> getAppointmentsWithoutDates(AppointmentSearchRequestModel searchQuery, Integer limit);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@

import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Disjunction;
import org.hibernate.sql.JoinType;
import org.openmrs.module.appointments.dao.AppointmentDao;
import org.openmrs.module.appointments.model.Appointment;
import org.openmrs.module.appointments.model.AppointmentSearchRequest;
import org.openmrs.module.appointments.model.AppointmentSearchRequestModel;
import org.openmrs.module.appointments.model.AppointmentServiceDefinition;
import org.openmrs.module.appointments.model.AppointmentServiceType;
import org.openmrs.module.appointments.model.AppointmentStatus;
import org.openmrs.module.appointments.model.AppointmentServiceType;
import org.openmrs.module.appointments.model.AppointmentSearchRequest;
import org.openmrs.module.appointments.model.AppointmentPriority;
import org.openmrs.module.appointments.util.DateUtil;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -87,6 +90,13 @@ public List<Appointment> search(Appointment appointment) {
return criteria.list();
}

@Override
public List<Appointment> search(AppointmentSearchRequestModel searchQuery) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Appointment.class);
addSearchCriteria(criteria, searchQuery);
return criteria.list();
}

@Override
public List<Appointment> getAllFutureAppointmentsForService(AppointmentServiceDefinition appointmentServiceDefinition) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Appointment.class);
Expand Down Expand Up @@ -225,11 +235,9 @@ public List<Appointment> getAppointmentsForPatient(Integer patientId) {
}

@Override
public List<Appointment> getAppointmentsWithoutDates(Integer limit) {
public List<Appointment> getAppointmentsWithoutDates(AppointmentSearchRequestModel searchQuery, Integer limit) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Appointment.class);
criteria.createAlias("patient", "patient");
criteria.add(Restrictions.eq("patient.voided", false));
criteria.add(Restrictions.eq("patient.personVoided", false));
addSearchCriteria(criteria, searchQuery);
criteria.add(Restrictions.isNull("startDateTime"));
criteria.add(Restrictions.isNull("endDateTime"));
criteria.addOrder(Order.asc("dateCreated"));
Expand All @@ -238,4 +246,70 @@ public List<Appointment> getAppointmentsWithoutDates(Integer limit) {
}
return criteria.list();
}

private void addSearchCriteria(Criteria criteria, AppointmentSearchRequestModel searchQuery) {
criteria.createAlias("patient", "patient");
criteria.add(Restrictions.eq("patient.voided", false));
criteria.add(Restrictions.eq("patient.personVoided", false));
criteria.createAlias("service", "service");

if (searchQuery != null) {
if (searchQuery.getPatientUuids() != null && !searchQuery.getPatientUuids().isEmpty()) {
Disjunction disjunction = Restrictions.disjunction();
searchQuery.getPatientUuids().stream()
.map(patientUuid -> Restrictions.eq("patient.uuid", patientUuid))
.forEach(disjunction::add);
criteria.add(disjunction);
}

if (searchQuery.getServiceUuids() != null && !searchQuery.getServiceUuids().isEmpty()) {
Disjunction disjunction = Restrictions.disjunction();
searchQuery.getServiceUuids().stream()
.map(serviceUuid -> Restrictions.eq("service.uuid", serviceUuid))
.forEach(disjunction::add);
criteria.add(disjunction);
}

if (searchQuery.getServiceTypeUuids() != null && !searchQuery.getServiceTypeUuids().isEmpty()) {
criteria.createAlias("serviceType", "serviceType");
Disjunction disjunction = Restrictions.disjunction();
searchQuery.getServiceTypeUuids().stream()
.map(serviceTypeUuid -> Restrictions.eq("serviceType.uuid", serviceTypeUuid))
.forEach(disjunction::add);
criteria.add(disjunction);
}

if (searchQuery.getStatus() != null) {
criteria.add(Restrictions.eq("status", AppointmentStatus.valueOf(searchQuery.getStatus())));
}

if (searchQuery.getProviderUuids() != null && !searchQuery.getProviderUuids().isEmpty()) {
criteria.createAlias("providers", "providers");
criteria.createAlias("providers.provider", "provider");
Disjunction disjunction = Restrictions.disjunction();
searchQuery.getProviderUuids().stream()
.map(providerUuid -> Restrictions.eq("provider.uuid", providerUuid))
.forEach(disjunction::add);
criteria.add(disjunction);
}

if (searchQuery.getLocationUuids() != null && !searchQuery.getLocationUuids().isEmpty()) {
criteria.createAlias("location", "location");
Disjunction disjunction = Restrictions.disjunction();
searchQuery.getLocationUuids().stream()
.map(locationUuid -> Restrictions.eq("location.uuid", locationUuid))
.forEach(disjunction::add);
criteria.add(disjunction);
}

if (searchQuery.getPriorities() != null && !searchQuery.getPriorities().isEmpty()) {
Disjunction disjunction = Restrictions.disjunction();
searchQuery.getPriorities().stream()
.map(priority -> Restrictions.eq("priority", AppointmentPriority.valueOf(priority)))
.forEach(disjunction::add);
criteria.add(disjunction);
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.openmrs.module.appointments.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.List;

@JsonIgnoreProperties
public class AppointmentSearchRequestModel {
private List<String> providerUuids;
private List<String> serviceUuids;
private List<String> serviceTypeUuids;
private List<String> locationUuids;
private List<String> patientUuids;
private String status;
private List<String> priorities;
private String appointmentKind;
private Boolean withoutDates = false;

public List<String> getProviderUuids() {
return providerUuids;
}

public void setProviderUuids(List<String> providerUuids) {
this.providerUuids = providerUuids;
}

public List<String> getServiceUuids() {
return serviceUuids;
}

public void setServiceUuids(List<String> serviceUuids) {
this.serviceUuids = serviceUuids;
}

public List<String> getServiceTypeUuids() {
return serviceTypeUuids;
}

public void setServiceTypeUuids(List<String> serviceTypeUuids) {
this.serviceTypeUuids = serviceTypeUuids;
}

public List<String> getLocationUuids() {
return locationUuids;
}

public void setLocationUuids(List<String> locationUuids) {
this.locationUuids = locationUuids;
}

public List<String> getPatientUuids() {
return patientUuids;
}

public void setPatientUuids(List<String> patientUuids) {
this.patientUuids = patientUuids;
}

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public String getAppointmentKind() {
return appointmentKind;
}

public void setAppointmentKind(String appointmentKind) {
this.appointmentKind = appointmentKind;
}

public Boolean isWithoutDates() {
return withoutDates;
}

public void setWithoutDates(Boolean withoutDates) {
this.withoutDates = withoutDates;
}

public List<String> getPriorities() {
return priorities;
}

public void setPriorities(List<String> priorities) {
this.priorities = priorities;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@


import org.openmrs.annotation.Authorized;

import org.openmrs.module.appointments.model.Appointment;
import org.openmrs.module.appointments.model.AppointmentProvider;
import org.openmrs.module.appointments.model.AppointmentSearchRequest;
import org.openmrs.module.appointments.model.AppointmentServiceDefinition;
import org.openmrs.module.appointments.model.AppointmentServiceType;
import org.openmrs.module.appointments.model.AppointmentStatus;
import org.openmrs.module.appointments.model.AppointmentProvider;
import org.openmrs.module.appointments.model.AppointmentSearchRequest;
import org.openmrs.module.appointments.model.AppointmentSearchRequestModel;

import org.openmrs.module.appointments.validator.AppointmentValidator;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -82,6 +85,10 @@ public interface AppointmentsService {
@Authorized({VIEW_APPOINTMENTS, MANAGE_APPOINTMENTS})
List<Appointment> search(AppointmentSearchRequest appointmentSearchRequest);

@Transactional
@Authorized({VIEW_APPOINTMENTS, MANAGE_APPOINTMENTS})
List<Appointment> search(AppointmentSearchRequestModel searchQuery);

@Authorized({VIEW_APPOINTMENTS, MANAGE_APPOINTMENTS})
Map<Enum, List<Appointment>> getAppointmentConflicts(Appointment appointment);

Expand All @@ -101,6 +108,6 @@ public interface AppointmentsService {

@Transactional
@Authorized({VIEW_APPOINTMENTS, MANAGE_APPOINTMENTS})
List<Appointment> searchAppointmentsWithoutDates();
List<Appointment> searchAppointmentsWithoutDates(AppointmentSearchRequestModel searchQuery);
}

Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
import org.openmrs.module.appointments.dao.AppointmentDao;
import org.openmrs.module.appointments.helper.AppointmentServiceHelper;
import org.openmrs.module.appointments.model.Appointment;
import org.openmrs.module.appointments.model.AppointmentAudit;
import org.openmrs.module.appointments.model.AppointmentKind;
import org.openmrs.module.appointments.model.AppointmentProvider;
import org.openmrs.module.appointments.model.AppointmentProviderResponse;
import org.openmrs.module.appointments.model.AppointmentSearchRequest;
import org.openmrs.module.appointments.model.AppointmentServiceDefinition;
import org.openmrs.module.appointments.model.AppointmentServiceType;
import org.openmrs.module.appointments.model.AppointmentStatus;
import org.openmrs.module.appointments.model.AppointmentProvider;
import org.openmrs.module.appointments.model.AppointmentSearchRequest;
import org.openmrs.module.appointments.model.AppointmentSearchRequestModel;
import org.openmrs.module.appointments.model.AppointmentProviderResponse;
import org.openmrs.module.appointments.model.AppointmentKind;
import org.openmrs.module.appointments.model.AppointmentAudit;
import org.openmrs.module.appointments.notification.NotificationResult;
import org.openmrs.module.appointments.service.AppointmentsService;
import org.openmrs.module.appointments.validator.AppointmentStatusChangeValidator;
Expand Down Expand Up @@ -143,10 +144,10 @@ public Appointment validateAndSave(Supplier<Appointment> mapper) {
}

@Override
public List<Appointment> searchAppointmentsWithoutDates() {
public List<Appointment> searchAppointmentsWithoutDates(AppointmentSearchRequestModel searchQuery) {
String limitString = Context.getAdministrationService().getGlobalProperty("webservices.rest.maxResultsDefault");
Integer limit = StringUtils.isNotEmpty(limitString) ? Integer.parseInt(limitString) : null;
return appointmentDao.getAppointmentsWithoutDates(limit);
return appointmentDao.getAppointmentsWithoutDates(searchQuery, limit);
}

private void setupTeleconsultation(Appointment appointment) {
Expand Down Expand Up @@ -220,6 +221,13 @@ public List<Appointment> search(Appointment appointment) {
return appointments.stream().filter(searchedAppointment -> !isServiceOrServiceTypeVoided(searchedAppointment)).collect(Collectors.toList());
}

@Transactional
@Override
public List<Appointment> search(AppointmentSearchRequestModel searchQuery) {
List<Appointment> appointments = appointmentDao.search(searchQuery);
return appointments.stream().filter(searchedAppointment -> !isServiceOrServiceTypeVoided(searchedAppointment)).collect(Collectors.toList());
}

@Transactional
@Override
public List<Appointment> getAllFutureAppointmentsForService(AppointmentServiceDefinition appointmentServiceDefinition) {
Expand Down
Loading

0 comments on commit 5b5dd73

Please sign in to comment.