ItEr11S13ProbasModuloRecursos: Satisfactions validation before saving and simple validation in interface.

This commit is contained in:
Óscar González Fernández 2009-06-08 10:59:33 +02:00 committed by Javier Moran Rua
parent 668a449b41
commit b06347a650
10 changed files with 308 additions and 62 deletions

View file

@ -4,6 +4,7 @@ import java.util.Comparator;
import java.util.Date; import java.util.Date;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.ToStringBuilder;
/** /**
* Declares a interval of time in which the criterion is satisfied <br /> * Declares a interval of time in which the criterion is satisfied <br />
@ -63,6 +64,20 @@ public class CriterionSatisfaction {
private Resource resource; private Resource resource;
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
public CriterionSatisfaction copy() {
CriterionSatisfaction result = new CriterionSatisfaction();
result.startDate = startDate;
result.finishDate = finishDate;
result.criterion = criterion;
result.resource = resource;
return result;
}
public Date getStartDate() { public Date getStartDate() {
return startDate != null ? new Date(startDate.getTime()) : null; return startDate != null ? new Date(startDate.getTime()) : null;
} }
@ -119,20 +134,26 @@ public class CriterionSatisfaction {
} }
public void setEndDate(Date date) { public void setEndDate(Date date) {
if (date == null) { finishDate = date;
finishDate = null;
}
if ((startDate.equals(date) || startDate.before(date)))
finishDate = date;
} }
public void setStartDate(Date date) { public void setStartDate(Date date) {
if ((finishDate == null || finishDate.after(date))) startDate = date;
startDate = date;
} }
public boolean overlapsWith(Interval interval) { public boolean overlapsWith(Interval interval) {
return getInterval().overlapsWith(interval); return getInterval().overlapsWith(interval);
} }
public boolean goesBeforeWithoutOverlapping(CriterionSatisfaction other) {
int compare = BY_START_COMPARATOR.compare(this, other);
if (compare > 0) {
return false;
} else {
Interval thisInterval = getInterval();
return !thisInterval.overlapsWith(other.getInterval());
}
}
} }

View file

@ -109,6 +109,12 @@ class Range extends Interval {
.compareTo(interval.start) > 0); .compareTo(interval.start) > 0);
} }
@Override
public String toString() {
return new StringBuilder("[").append(start).append(", ").append(end)
.append(")").toString();
}
} }
class OpenEndedInterval extends Interval { class OpenEndedInterval extends Interval {
@ -131,6 +137,11 @@ class OpenEndedInterval extends Interval {
return start.before(interval.start) || interval.end == null return start.before(interval.start) || interval.end == null
|| start.before(interval.end); || start.before(interval.end);
} }
@Override
public String toString() {
return new StringBuilder("[").append(start).append(",...)").toString();
}
} }
class Point extends Interval { class Point extends Interval {
@ -154,4 +165,10 @@ class Point extends Interval {
return interval.contains(end) && !interval.start.equals(end); return interval.contains(end) && !interval.start.equals(end);
} }
@Override
public String toString() {
return new StringBuilder().append("[").append(start).append(")")
.toString();
}
} }

View file

@ -1,12 +1,14 @@
package org.navalplanner.business.resources.entities; package org.navalplanner.business.resources.entities;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.ListIterator;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
@ -142,6 +144,25 @@ public abstract class Resource {
return new ArrayList<Criterion>(result); return new ArrayList<Criterion>(result);
} }
public Query oneOf(ICriterionType<?>[] laboralRelatedTypes) {
return oneOf(Arrays.asList(laboralRelatedTypes));
}
public Query oneOf(final Collection<? extends ICriterionType<?>> types) {
return withNewPredicate(new Predicate() {
@Override
public boolean accepts(CriterionSatisfaction satisfaction) {
for (ICriterionType<?> criterionType : types) {
if (criterionType.contains(satisfaction.getCriterion())) {
return true;
}
}
return false;
}
});
}
} }
public Query query() { public Query query() {
@ -245,8 +266,8 @@ public abstract class Resource {
} }
public CriterionSatisfaction addSatisfaction( public CriterionSatisfaction addSatisfaction(ICriterionType<?> type,
ICriterionType<Criterion> type, CriterionSatisfaction satisfaction) { CriterionSatisfaction satisfaction) {
return new EnsureSatisfactionIsCorrect(this, type, satisfaction) return new EnsureSatisfactionIsCorrect(this, type, satisfaction)
.addSatisfaction(); .addSatisfaction();
} }
@ -347,7 +368,8 @@ public abstract class Resource {
public boolean canAddSatisfaction(ICriterionType<?> type, public boolean canAddSatisfaction(ICriterionType<?> type,
CriterionSatisfaction satisfaction) { CriterionSatisfaction satisfaction) {
return new EnsureSatisfactionIsCorrect(this, type, satisfaction) EnsureSatisfactionIsCorrect ensureSatisfactionIsCorrect = new EnsureSatisfactionIsCorrect(this, type, satisfaction);
return ensureSatisfactionIsCorrect
.canAddSatisfaction(); .canAddSatisfaction();
} }
@ -371,8 +393,7 @@ public abstract class Resource {
return previous; return previous;
} }
public void removeCriterionSatisfaction(CriterionSatisfaction satisfaction) public void removeCriterionSatisfaction(CriterionSatisfaction satisfaction) {
throws InstanceNotFoundException {
criterionSatisfactions.remove(satisfaction); criterionSatisfactions.remove(satisfaction);
} }
@ -380,4 +401,66 @@ public abstract class Resource {
return criterionSatisfactions.contains(satisfaction); return criterionSatisfactions.contains(satisfaction);
} }
public void checkNotOverlaps(List<ICriterionType<?>> types) {
for (ICriterionType<?> criterionType : types) {
if (!criterionType.allowSimultaneousCriterionsPerResource()) {
List<CriterionSatisfaction> satisfactions = query().from(
criterionType).sortByStartDate().result();
ListIterator<CriterionSatisfaction> listIterator = satisfactions
.listIterator();
while (listIterator.hasNext()) {
CriterionSatisfaction current = listIterator.next();
CriterionSatisfaction previous = getPrevious(listIterator);
CriterionSatisfaction next = getNext(listIterator);
if (previous != null) {
checkNotOverlaps(previous, current);
}
if (next != null)
checkNotOverlaps(current, next);
}
}
}
}
private void checkNotOverlaps(CriterionSatisfaction before,
CriterionSatisfaction after) {
if (!before.goesBeforeWithoutOverlapping(after)) {
throw new IllegalArgumentException(createOverlapsMessage(before,
after));
}
}
private String createOverlapsMessage(CriterionSatisfaction before,
CriterionSatisfaction after) {
return new StringBuilder("the satisfaction").append(before).append(
"overlaps with").append(after).toString();
}
private CriterionSatisfaction getNext(
ListIterator<CriterionSatisfaction> listIterator) {
if (listIterator.hasNext()) {
CriterionSatisfaction result = listIterator.next();
listIterator.previous();
return result;
}
return null;
}
private CriterionSatisfaction getPrevious(
ListIterator<CriterionSatisfaction> listIterator) {
listIterator.previous();
try {
if (listIterator.hasPrevious()) {
CriterionSatisfaction result = listIterator.previous();
listIterator.next();
return result;
}
return null;
} finally {
listIterator.next();
}
}
} }

View file

@ -4,7 +4,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
//import org.navalplanner.business.resources.entities.CriterionSatisfaction; import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.entities.ICriterion; import org.navalplanner.business.resources.entities.ICriterion;
import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.resources.entities.Worker; import org.navalplanner.business.resources.entities.Worker;
@ -19,6 +19,7 @@ public interface ResourceService {
* It updates or inserts the resource passed as a parameter. If the resource * It updates or inserts the resource passed as a parameter. If the resource
* is a composite resource, updating or inserting is cascaded to the * is a composite resource, updating or inserting is cascaded to the
* resources contained in it. * resources contained in it.
* @throws ValidationException
*/ */
public void saveResource(Resource resource); public void saveResource(Resource resource);

View file

@ -5,9 +5,10 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.resources.bootstrap.ICriterionsBootstrap;
import org.navalplanner.business.resources.daos.IResourceDao; import org.navalplanner.business.resources.daos.IResourceDao;
import org.navalplanner.business.resources.entities.ICriterion; import org.navalplanner.business.resources.entities.ICriterion;
import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.resources.entities.Worker; import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.business.resources.services.ResourceService; import org.navalplanner.business.resources.services.ResourceService;
@ -25,10 +26,20 @@ public class ResourceServiceImpl implements ResourceService {
@Autowired @Autowired
private IResourceDao resourceDao; private IResourceDao resourceDao;
@Autowired
private ICriterionsBootstrap criterionsBootstrap;
@Transactional
public void saveResource(Resource resource) { public void saveResource(Resource resource) {
checkResourceIsOk(resource);
resourceDao.save(resource); resourceDao.save(resource);
} }
private void checkResourceIsOk(Resource resource) {
List<ICriterionType<?>> types = criterionsBootstrap.getTypes();
resource.checkNotOverlaps(types);
}
@Transactional(readOnly = true) @Transactional(readOnly = true)
public Resource findResource(Long resourceId) public Resource findResource(Long resourceId)
throws InstanceNotFoundException { throws InstanceNotFoundException {

View file

@ -127,4 +127,37 @@ public class CriterionSatisfactionTest {
assertThat(copy, equalTo(orderedSatisfactions)); assertThat(copy, equalTo(orderedSatisfactions));
} }
} }
@Test
public void testGoesBeforeWithoutOverlapping() {
final Criterion criterion = CriterionDAOTest.createValidCriterion();
Worker worker = new Worker("firstName", "surName", "2333232", 10);
CriterionSatisfaction posterior = new CriterionSatisfaction();
posterior.setCriterion(criterion);
posterior.setStartDate(year(2000));
posterior.setEndDate(year(2008));
Interval[] goesAfterOrOverlapsIntervals = { Interval.from(year(2000)),
Interval.from(year(2001)), Interval.from(year(1999)),
Interval.range(year(1999), year(2001)),
Interval.from(year(2009)),
Interval.range(year(2009), year(2012)) };
for (Interval interval : goesAfterOrOverlapsIntervals) {
CriterionSatisfaction copied = posterior.copy();
copied.setStartDate(interval.getStart());
copied.setEndDate(interval.getEnd());
assertFalse(interval + " shouldn't go before", copied
.goesBeforeWithoutOverlapping(posterior));
}
Interval[] goesBeforeWithoutOverlappingInterval = {
Interval.point(year(2000)),
Interval.range(year(1990), year(2000)),
Interval.range(year(1990), year(1997)) };
for (Interval interval : goesBeforeWithoutOverlappingInterval) {
CriterionSatisfaction copied = posterior.copy();
copied.setStartDate(interval.getStart());
copied.setEndDate(interval.getEnd());
assertTrue(copied.goesBeforeWithoutOverlapping(posterior));
}
}
} }

View file

@ -37,7 +37,15 @@ public interface IWorkerModel {
Map<ICriterionType<?>, Collection<Criterion>> getLaboralRelatedCriterions(); Map<ICriterionType<?>, Collection<Criterion>> getLaboralRelatedCriterions();
Set<CriterionSatisfaction> getLaboralRelatedCriterionSatisfactions( List<CriterionSatisfaction> getLaboralRelatedCriterionSatisfactions(
Worker worker); Worker worker);
public enum AddingSatisfactionResult {
OK, SATISFACTION_WRONG, DONT_COMPLY_OVERLAPPING_RESTRICTIONS;
}
AddingSatisfactionResult addSatisfaction(ICriterionType<?> type,
CriterionSatisfaction originalSatisfaction,
CriterionSatisfaction edited);
} }

View file

@ -3,9 +3,8 @@ package org.navalplanner.web.resources.worker;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
@ -13,8 +12,11 @@ import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionSatisfaction; import org.navalplanner.business.resources.entities.CriterionSatisfaction;
import org.navalplanner.business.resources.entities.CriterionWithItsType; import org.navalplanner.business.resources.entities.CriterionWithItsType;
import org.navalplanner.business.resources.entities.ICriterionType; import org.navalplanner.business.resources.entities.ICriterionType;
import org.navalplanner.business.resources.entities.Interval;
import org.navalplanner.business.resources.entities.Worker; import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.web.common.IMessagesForUser;
import org.navalplanner.web.common.Level;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.resources.worker.IWorkerModel.AddingSatisfactionResult;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.util.GenericForwardComposer; import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Listbox; import org.zkoss.zul.Listbox;
@ -34,26 +36,28 @@ public class WorkRelationshipsController extends GenericForwardComposer {
* CriterionSatisfaction(); * CriterionSatisfaction();
*/ */
private CriterionSatisfaction editRelationship = new CriterionSatisfaction(); private CriterionSatisfaction satisfactionEdited = new CriterionSatisfaction();
private Collection<Criterion> workCriterions; private List<Criterion> workCriterions;
private Listbox selectedWorkCriterion; private Listbox selectedWorkCriterion;
/*
* private Datebox newWorkRelationshipStartDate;
*
* private Datebox newWorkRelationshipEndDate;
*/
private HashMap<Criterion, CriterionWithItsType> fromCriterionToType; private HashMap<Criterion, CriterionWithItsType> fromCriterionToType;
private boolean editing; private boolean editing;
private Component containerComponent;
private CriterionSatisfaction originalSatisfaction;
private final IMessagesForUser messagesForUser;
public WorkRelationshipsController(IWorkerModel workerModel, public WorkRelationshipsController(IWorkerModel workerModel,
WorkerCRUDController workerCRUDController) { WorkerCRUDController workerCRUDController,
IMessagesForUser messagesForUser) {
this.workerModel = workerModel; this.workerModel = workerModel;
this.workerCRUDController = workerCRUDController; this.workerCRUDController = workerCRUDController;
this.messagesForUser = messagesForUser;
this.workCriterions = new ArrayList<Criterion>(); this.workCriterions = new ArrayList<Criterion>();
Map<ICriterionType<?>, Collection<Criterion>> map = workerModel Map<ICriterionType<?>, Collection<Criterion>> map = workerModel
.getLaboralRelatedCriterions(); .getLaboralRelatedCriterions();
@ -68,13 +72,12 @@ public class WorkRelationshipsController extends GenericForwardComposer {
} }
} }
public Set<CriterionSatisfaction> getCriterionSatisfactions() { public List<CriterionSatisfaction> getCriterionSatisfactions() {
if (this.workerCRUDController.getWorker() == null) { if (getWorker() == null) {
return new HashSet<CriterionSatisfaction>(); return new ArrayList<CriterionSatisfaction>();
} else { } else {
return workerModel return workerModel
.getLaboralRelatedCriterionSatisfactions(this.workerCRUDController .getLaboralRelatedCriterionSatisfactions(getWorker());
.getWorker());
} }
} }
@ -86,47 +89,88 @@ public class WorkRelationshipsController extends GenericForwardComposer {
} }
public void prepareForCreate() { public void prepareForCreate() {
this.editRelationship = new CriterionSatisfaction(); this.satisfactionEdited = new CriterionSatisfaction();
this.originalSatisfaction = this.satisfactionEdited;
Util.reloadBindings(containerComponent);
editing = false; editing = false;
} }
public void prepareForEdit(CriterionSatisfaction criterionSatisfaction) { public void prepareForEdit(CriterionSatisfaction criterionSatisfaction) {
this.editRelationship = criterionSatisfaction; this.satisfactionEdited = criterionSatisfaction.copy();
this.originalSatisfaction = criterionSatisfaction;
Util.reloadBindings(containerComponent);
this.satisfactionEdited.setCriterion(select(this.satisfactionEdited
.getCriterion()));
// the criterion retrieved is used instead of the original one, so the
// call fromCriterionToType.get(criterion) works
editing = true; editing = true;
} }
public void saveCriterionSatisfaction() throws InstanceNotFoundException { private Criterion select(Criterion criterion) {
int i = 0;
// Add new criterion for (Criterion c : workCriterions) {
Criterion selectedCriterion = (Criterion) selectedWorkCriterion if (c.isEquivalent(criterion)) {
.getSelectedItem().getValue(); selectedWorkCriterion.setSelectedIndex(i);
CriterionWithItsType criterionWithItsType = fromCriterionToType return c;
.get(selectedCriterion); }
System.out.println("SAVE!!: " + selectedCriterion.getName()); i++;
if (this.workerCRUDController.getWorker().contains(editRelationship)) {
this.workerCRUDController.getWorker().removeCriterionSatisfaction(
editRelationship);
} }
this.workerCRUDController.getWorker().addSatisfaction( throw new RuntimeException("not found criterion" + criterion);
criterionWithItsType, }
Interval.range(editRelationship.getStartDate(),
editRelationship.getEndDate()));
// Delete the former one public void saveCriterionSatisfaction() {
workerCRUDController.getWorker().removeCriterionSatisfaction( Criterion choosenCriterion = getChoosenCriterion();
this.editRelationship); CriterionWithItsType criterionWithItsType = fromCriterionToType
.get(choosenCriterion);
satisfactionEdited.setCriterion(choosenCriterion);
AddingSatisfactionResult addSatisfaction = workerModel.addSatisfaction(
criterionWithItsType.getType(), originalSatisfaction,
satisfactionEdited);
switch (addSatisfaction) {
case OK:
messagesForUser.showMessage(Level.INFO, "Periodo gardado");
this.workerCRUDController.goToEditForm();
break;
case SATISFACTION_WRONG:
messagesForUser
.showMessage(Level.WARNING,
"O periodo ten datos inválidos. A fecha de fin debe ser posterior á de inicio");
break;
case DONT_COMPLY_OVERLAPPING_RESTRICTIONS:
messagesForUser
.showMessage(Level.WARNING,
"O periodo non se puido gardar. Solápase cun periodo non compatible.");
this.workerCRUDController.goToEditForm();
break;
default:
throw new RuntimeException("unexpected: " + addSatisfaction);
}
}
this.workerCRUDController.goToEditForm(); private Criterion getChoosenCriterion() {
Criterion criterion;
if (editing) {
criterion = satisfactionEdited.getCriterion();
} else {
criterion = (Criterion) this.selectedWorkCriterion
.getSelectedItemApi().getValue();
}
return criterion;
}
private Worker getWorker() {
return this.workerModel.getWorker();
} }
@Override @Override
public void doAfterCompose(Component comp) throws Exception { public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp); super.doAfterCompose(comp);
this.containerComponent = comp;
this.selectedWorkCriterion.setSelectedIndex(0); this.selectedWorkCriterion.setSelectedIndex(0);
} }
public CriterionSatisfaction getEditRelationship() { public CriterionSatisfaction getEditRelationship() {
return this.editRelationship; return this.satisfactionEdited;
} }
public Collection<Criterion> getWorkCriterions() { public Collection<Criterion> getWorkCriterions() {

View file

@ -130,7 +130,6 @@ public class WorkerCRUDController extends GenericForwardComposer implements
public void goToAddWorkRelationshipForm() { public void goToAddWorkRelationshipForm() {
this.addWorkRelationship.prepareForCreate(); this.addWorkRelationship.prepareForCreate();
getVisibility().showOnly(addWorkRelationshipWindow); getVisibility().showOnly(addWorkRelationshipWindow);
Util.reloadBindings(addWorkRelationshipWindow);
} }
public void goToCreateForm() { public void goToCreateForm() {
@ -142,7 +141,6 @@ public class WorkerCRUDController extends GenericForwardComposer implements
public void goToEditWorkRelationshipForm(CriterionSatisfaction satisfaction) { public void goToEditWorkRelationshipForm(CriterionSatisfaction satisfaction) {
this.editWorkRelationship.prepareForEdit(satisfaction); this.editWorkRelationship.prepareForEdit(satisfaction);
getVisibility().showOnly(editWorkRelationshipWindow); getVisibility().showOnly(editWorkRelationshipWindow);
Util.reloadBindings(editWorkRelationshipWindow);
} }
@Override @Override
@ -158,12 +156,13 @@ public class WorkerCRUDController extends GenericForwardComposer implements
throw new RuntimeException("messagesContainer is needed"); throw new RuntimeException("messagesContainer is needed");
messages = new MessagesForUser(messagesContainer); messages = new MessagesForUser(messagesContainer);
this.addWorkRelationship = new WorkRelationshipsController( this.addWorkRelationship = new WorkRelationshipsController(
this.workerModel, this); this.workerModel, this, messages);
setupWorkRelationshipController(this.addWorkRelationship, setupWorkRelationshipController(this.addWorkRelationship,
this.addWorkRelationshipWindow); this.addWorkRelationshipWindow);
setupWorkRelationshipController( setupWorkRelationshipController(
this.editWorkRelationship = new WorkRelationshipsController( this.editWorkRelationship = new WorkRelationshipsController(
this.workerModel, this), editWorkRelationshipWindow); this.workerModel, this, messages),
editWorkRelationshipWindow);
URLHandler<IWorkerCRUDControllerEntryPoints> handler = URLHandlerRegistry URLHandler<IWorkerCRUDControllerEntryPoints> handler = URLHandlerRegistry
.getRedirectorFor(IWorkerCRUDControllerEntryPoints.class); .getRedirectorFor(IWorkerCRUDControllerEntryPoints.class);

View file

@ -110,6 +110,34 @@ public class WorkerModel implements IWorkerModel {
return worker.getAllSatisfactions(); return worker.getAllSatisfactions();
} }
@Transactional
public AddingSatisfactionResult addSatisfaction(ICriterionType<?> type,
CriterionSatisfaction original, CriterionSatisfaction edited) {
Worker worker = getWorker();
edited.setResource(worker);
boolean previouslyContained = false;
if (previouslyContained = worker.contains(original)) {
worker.removeCriterionSatisfaction(original);
}
boolean canAdd = false;
try {
canAdd = worker.canAddSatisfaction(type, edited);
} catch (IllegalArgumentException e) {
if (previouslyContained) {
worker.addSatisfaction(type, original);
}
return AddingSatisfactionResult.SATISFACTION_WRONG;
}
if (!canAdd) {
if (previouslyContained) {
worker.addSatisfaction(type, original);
}
return AddingSatisfactionResult.DONT_COMPLY_OVERLAPPING_RESTRICTIONS;
}
worker.addSatisfaction(type, edited);
return AddingSatisfactionResult.OK;
}
private static class NullAssigner implements private static class NullAssigner implements
IMultipleCriterionActiveAssigner { IMultipleCriterionActiveAssigner {
@ -252,7 +280,8 @@ public class WorkerModel implements IWorkerModel {
public void applyChanges() { public void applyChanges() {
for (CriterionSatisfaction criterionSatisfaction : added) { for (CriterionSatisfaction criterionSatisfaction : added) {
resource.addSatisfaction(new CriterionWithItsType(type, resource.addSatisfaction(new CriterionWithItsType(type,
criterionSatisfaction.getCriterion()), Interval.from(criterionSatisfaction.getStartDate())); criterionSatisfaction.getCriterion()), Interval
.from(criterionSatisfaction.getStartDate()));
} }
for (Criterion criterion : unassigned.keySet()) { for (Criterion criterion : unassigned.keySet()) {
resource.finish(new CriterionWithItsType(type, criterion)); resource.finish(new CriterionWithItsType(type, criterion));
@ -307,13 +336,13 @@ public class WorkerModel implements IWorkerModel {
} }
@Override @Override
public Set<CriterionSatisfaction> getLaboralRelatedCriterionSatisfactions( public List<CriterionSatisfaction> getLaboralRelatedCriterionSatisfactions(
Worker worker) { Worker worker) {
Set<CriterionSatisfaction> result = new HashSet<CriterionSatisfaction>(); Set<CriterionSatisfaction> result = new HashSet<CriterionSatisfaction>();
for (ICriterionType<?> criterionType : laboralRelatedTypes) { for (ICriterionType<?> criterionType : laboralRelatedTypes) {
result.addAll(worker.getSatisfactionsFor(criterionType)); result.addAll(worker.getSatisfactionsFor(criterionType));
} }
return result; return worker.query().oneOf(laboralRelatedTypes).sortByStartDate()
.result();
} }
} }