Skip to content

Commit

Permalink
UHM-1137, filter appointment blocks by multiple types
Browse files Browse the repository at this point in the history
  • Loading branch information
cioan committed Mar 31, 2014
1 parent 85426a5 commit a5303e8
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,18 @@ public interface AppointmentService extends OpenmrsService {
*/
void purgeAppointmentBlock(AppointmentBlock appointmentBlock);

/**
* Gets appointment blocks which have a given date, location, provider and list of appointment
* types
*
* @return a list of appointment block objects.
* @should get all appointment blocks which have contains in a given date interval and
* corresponds to a given locations, provider and appointment types.
* @should not return voided appointment blocks
*/
List<AppointmentBlock> getAppointmentBlocksByTypes(Date fromDate, Date toDate, String locations, Provider provider,
List<AppointmentType> appointmentTypes);

/**
* Gets appointment blocks which have a given date and location.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
public interface AppointmentBlockDAO extends SingleClassDAO {

List<AppointmentBlock> getAppointmentBlocks(Date fromDate, Date toDate, String locations, Provider provider,
AppointmentType appointmentType);
List<AppointmentType> appointmentType);

List<AppointmentBlock> getOverlappingAppointmentBlocks(AppointmentBlock appointmentBlock);
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@
import org.openmrs.module.appointmentscheduling.api.db.AppointmentBlockDAO;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;

public class HibernateAppointmentBlockDAO extends HibernateSingleClassDAO implements AppointmentBlockDAO {

Expand All @@ -44,13 +42,13 @@ public HibernateAppointmentBlockDAO() {
* @param toDate the upper bound of the date interval.
* @param locations the of locations to filter by.
* @param provider the provider to filter by.
* @param appointment type the type of appointment to filter by.
* @param appointmentTypes types of appointment to filter by.
* @return the appointment blocks that is on the given date interval and locations.
*/
@Override
@Transactional(readOnly = true)
public List<AppointmentBlock> getAppointmentBlocks(Date fromDate, Date toDate, String locations, Provider provider,
AppointmentType appointmentType) {
List<AppointmentType> appointmentTypes) {
List<AppointmentBlock> filteredAppointmentBlocks = null;
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(AppointmentBlock.class);

Expand All @@ -75,29 +73,21 @@ public List<AppointmentBlock> getAppointmentBlocks(Date fromDate, Date toDate, S
if (provider != null) {
criteria.add(Restrictions.eq("provider.id", provider.getProviderId()));
}
if (appointmentTypes != null && appointmentTypes.size() > 0) {
Set<Integer> types = new HashSet<Integer>();
for (AppointmentType type : appointmentTypes) {
types.add(type.getAppointmentTypeId());
}
criteria.createAlias("types", "appointmentType");
criteria.add(Restrictions.in("appointmentType.id", types));
}

criteria.addOrder(Order.asc("startDate"));
criteria.addOrder(Order.asc("endDate"));

List<AppointmentBlock> appointmentBlocks = criteria.list();
if (appointmentType != null) {
filteredAppointmentBlocks = new ArrayList<AppointmentBlock>();
String stringQuery = "SELECT appointmentBlock FROM AppointmentBlock AS appointmentBlock WHERE :appointmentType IN elements(appointmentBlock.types) AND voided = 0 ORDER BY appointmentBlock.startDate, appointmentBlock.endDate";
Query query = super.sessionFactory.getCurrentSession().createQuery(stringQuery)
.setParameter("appointmentType", appointmentType);
List<AppointmentBlock> appointmentBlocksFilteredByType = query.list();
for (AppointmentBlock appointmentBlockContainsType : appointmentBlocksFilteredByType) {
for (AppointmentBlock appointmentBlock : appointmentBlocks) {
if (appointmentBlock.getId().equals(appointmentBlockContainsType.getId())) {
//Intersection
filteredAppointmentBlocks.add(appointmentBlock);
}
}
}
} else
filteredAppointmentBlocks = appointmentBlocks;

return filteredAppointmentBlocks;
return appointmentBlocks;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,15 @@ public void purgeAppointmentBlock(AppointmentBlock appointmentBlock) {
@Transactional(readOnly = true)
public List<AppointmentBlock> getAppointmentBlocks(Date fromDate, Date toDate, String locations, Provider provider,
AppointmentType appointmentType) {
return getAppointmentBlockDAO().getAppointmentBlocks(fromDate, toDate, locations, provider, appointmentType);
return getAppointmentBlocksByTypes(fromDate, toDate, locations, provider,
(appointmentType != null) ? Arrays.asList(appointmentType) : null);
}

@Override
@Transactional(readOnly = true)
public List<AppointmentBlock> getAppointmentBlocksByTypes(Date fromDate, Date toDate, String locations,
Provider provider, List<AppointmentType> appointmentTypes) {
return getAppointmentBlockDAO().getAppointmentBlocks(fromDate, toDate, locations, provider, appointmentTypes);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,68 +1,68 @@
package org.openmrs.module.appointmentscheduling.validator;

import java.util.Arrays;
import java.util.HashSet;

import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openmrs.api.context.Context;
import org.openmrs.module.appointmentscheduling.AppointmentBlock;
import org.openmrs.module.appointmentscheduling.api.AppointmentService;
import org.openmrs.test.BaseModuleContextSensitiveTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;

public class AppointmentBlockValidatorComponentTest extends BaseModuleContextSensitiveTest {

@Autowired
private AppointmentBlockValidator appointmentBlockValidator;

private Errors errors;

@Before
public void before() throws Exception {
executeDataSet("standardAppointmentTestDataset.xml");
}

@Test
public void shouldNotAllowCreationOfOverlappingAppointmentBlock() {

AppointmentBlock appointmentBlock = new AppointmentBlock();
// this overlaps with appointment block #1 in the test dataset
appointmentBlock.setStartDate(new DateTime(2005, 1, 1, 0, 0).toDate());
appointmentBlock.setEndDate(new DateTime(2005, 1, 2, 0, 0).toDate());

appointmentBlock.setProvider(Context.getProviderService().getProvider(1));
appointmentBlock.setLocation(Context.getLocationService().getLocation(1));
appointmentBlock.setTypes(new HashSet(Arrays.asList(Context.getService(AppointmentService.class).getAppointmentType(
1))));

errors = new BindException(appointmentBlock, "test");
appointmentBlockValidator.validate(appointmentBlock, errors);

Assert.assertEquals(1, errors.getFieldErrorCount());
Assert.assertEquals("appointmentscheduling.AppointmentBlock.error.appointmentBlockOverlap",
errors.getFieldError("provider").getCode());
}

@Test
public void shouldAllowCreationOfNonOverlappingAppointmentBlock() {

AppointmentBlock appointmentBlock = new AppointmentBlock();
appointmentBlock.setStartDate(new DateTime(2007, 1, 1, 0, 0).toDate());
appointmentBlock.setEndDate(new DateTime(2007, 1, 2, 0, 0).toDate());

appointmentBlock.setProvider(Context.getProviderService().getProvider(1));
appointmentBlock.setLocation(Context.getLocationService().getLocation(1));
appointmentBlock.setTypes(new HashSet(Arrays.asList(Context.getService(AppointmentService.class).getAppointmentType(
1))));

errors = new BindException(appointmentBlock, "test");
appointmentBlockValidator.validate(appointmentBlock, errors);

Assert.assertEquals(0, errors.getFieldErrorCount());
}
}
package org.openmrs.module.appointmentscheduling.validator;

import java.util.Arrays;
import java.util.HashSet;

import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openmrs.api.context.Context;
import org.openmrs.module.appointmentscheduling.AppointmentBlock;
import org.openmrs.module.appointmentscheduling.api.AppointmentService;
import org.openmrs.test.BaseModuleContextSensitiveTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;

public class AppointmentBlockValidatorComponentTest extends BaseModuleContextSensitiveTest {

@Autowired
private AppointmentBlockValidator appointmentBlockValidator;

private Errors errors;

@Before
public void before() throws Exception {
executeDataSet("standardAppointmentTestDataset.xml");
}

@Test
public void shouldNotAllowCreationOfOverlappingAppointmentBlock() {

AppointmentBlock appointmentBlock = new AppointmentBlock();
// this overlaps with appointment block #1 in the test dataset
appointmentBlock.setStartDate(new DateTime(2005, 1, 1, 0, 0).toDate());
appointmentBlock.setEndDate(new DateTime(2005, 1, 2, 0, 0).toDate());

appointmentBlock.setProvider(Context.getProviderService().getProvider(1));
appointmentBlock.setLocation(Context.getLocationService().getLocation(1));
appointmentBlock.setTypes(new HashSet(Arrays.asList(Context.getService(AppointmentService.class).getAppointmentType(
1))));

errors = new BindException(appointmentBlock, "test");
appointmentBlockValidator.validate(appointmentBlock, errors);

Assert.assertEquals(1, errors.getFieldErrorCount());
Assert.assertEquals("appointmentscheduling.AppointmentBlock.error.appointmentBlockOverlap",
errors.getFieldError("provider").getCode());
}

@Test
public void shouldAllowCreationOfNonOverlappingAppointmentBlock() {

AppointmentBlock appointmentBlock = new AppointmentBlock();
appointmentBlock.setStartDate(new DateTime(2007, 1, 1, 0, 0).toDate());
appointmentBlock.setEndDate(new DateTime(2007, 1, 2, 0, 0).toDate());

appointmentBlock.setProvider(Context.getProviderService().getProvider(1));
appointmentBlock.setLocation(Context.getLocationService().getLocation(1));
appointmentBlock.setTypes(new HashSet(Arrays.asList(Context.getService(AppointmentService.class).getAppointmentType(
1))));

errors = new BindException(appointmentBlock, "test");
appointmentBlockValidator.validate(appointmentBlock, errors);

Assert.assertEquals(0, errors.getFieldErrorCount());
}
}

0 comments on commit a5303e8

Please sign in to comment.