Use PartialDay for doing allocations
Now the start date used is the intra day one so the allocations are more precise. FEA: ItEr61S08TimeUnitConfigurablePlanning
This commit is contained in:
parent
1ee7b2d536
commit
5afea4ffb1
9 changed files with 144 additions and 92 deletions
|
|
@ -52,6 +52,7 @@ import org.navalplanner.business.util.deepcopy.OnCopy;
|
|||
import org.navalplanner.business.util.deepcopy.Strategy;
|
||||
import org.navalplanner.business.workingday.EffortDuration;
|
||||
import org.navalplanner.business.workingday.IntraDayDate;
|
||||
import org.navalplanner.business.workingday.IntraDayDate.PartialDay;
|
||||
import org.navalplanner.business.workingday.ResourcesPerDay;
|
||||
|
||||
/**
|
||||
|
|
@ -470,16 +471,15 @@ public class GenericResourceAllocation extends
|
|||
}
|
||||
|
||||
public List<DayAssignment> createAssignmentsAtDay(List<Resource> resources,
|
||||
LocalDate day, ResourcesPerDay resourcesPerDay,
|
||||
PartialDay day, ResourcesPerDay resourcesPerDay,
|
||||
final EffortDuration maxLimit) {
|
||||
final EffortDuration durations = min(
|
||||
calculateTotalToDistribute(day, resourcesPerDay), maxLimit);
|
||||
GenericAllocation genericAllocation = new GenericAllocation(resources);
|
||||
return new ArrayList<DayAssignment>(genericAllocation.distributeForDay(
|
||||
day, durations));
|
||||
day.getDate(), durations));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Resource> getAssociatedResources() {
|
||||
return new ArrayList<Resource>(DayAssignment
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
package org.navalplanner.business.planner.entities;
|
||||
|
||||
import static org.navalplanner.business.workingday.EffortDuration.hours;
|
||||
import static org.navalplanner.business.workingday.EffortDuration.min;
|
||||
import static org.navalplanner.business.workingday.EffortDuration.seconds;
|
||||
import static org.navalplanner.business.workingday.EffortDuration.zero;
|
||||
|
||||
|
|
@ -65,6 +64,7 @@ import org.navalplanner.business.util.deepcopy.OnCopy;
|
|||
import org.navalplanner.business.util.deepcopy.Strategy;
|
||||
import org.navalplanner.business.workingday.EffortDuration;
|
||||
import org.navalplanner.business.workingday.IntraDayDate;
|
||||
import org.navalplanner.business.workingday.IntraDayDate.PartialDay;
|
||||
import org.navalplanner.business.workingday.ResourcesPerDay;
|
||||
|
||||
/**
|
||||
|
|
@ -226,7 +226,7 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
|
||||
@Override
|
||||
protected List<DayAssignment> createAssignmentsAtDay(
|
||||
ResourcesPerDayModification allocation, LocalDate day,
|
||||
ResourcesPerDayModification allocation, PartialDay day,
|
||||
EffortDuration limit) {
|
||||
return allocation.createAssignmentsAtDay(day, limit);
|
||||
}
|
||||
|
|
@ -484,22 +484,21 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
@Override
|
||||
public final void allocate(ResourcesPerDay resourcesPerDay) {
|
||||
Task currentTask = getTask();
|
||||
LocalDate startInclusive = new LocalDate(currentTask.getStartDate());
|
||||
LocalDate endExclusive = new LocalDate(currentTask.getEndDate());
|
||||
List<T> assignmentsCreated = createAssignments(resourcesPerDay,
|
||||
startInclusive, endExclusive);
|
||||
currentTask.getIntraDayStartDate(),
|
||||
currentTask.getIntraDayEndDate());
|
||||
resetAssignmentsTo(assignmentsCreated);
|
||||
updateResourcesPerDay();
|
||||
}
|
||||
|
||||
private List<T> createAssignments(ResourcesPerDay resourcesPerDay,
|
||||
LocalDate startInclusive, LocalDate endExclusive) {
|
||||
IntraDayDate startInclusive, IntraDayDate endExclusive) {
|
||||
List<T> assignmentsCreated = new ArrayList<T>();
|
||||
for (LocalDate day : getDays(startInclusive, endExclusive)) {
|
||||
for (PartialDay day : getDays(startInclusive, endExclusive)) {
|
||||
EffortDuration durationForDay = calculateTotalToDistribute(day,
|
||||
resourcesPerDay);
|
||||
assignmentsCreated
|
||||
.addAll(distributeForDay(day, durationForDay));
|
||||
assignmentsCreated.addAll(distributeForDay(day.getDate(),
|
||||
durationForDay));
|
||||
}
|
||||
return assignmentsCreated;
|
||||
}
|
||||
|
|
@ -512,8 +511,8 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
public void allocate(ResourcesPerDay resourcesPerDay) {
|
||||
IntraDayDate startInclusive = getStartAfterConsolidated();
|
||||
List<T> assignmentsCreated = createAssignments(
|
||||
resourcesPerDay, startInclusive.getDate(),
|
||||
endExclusive);
|
||||
resourcesPerDay, startInclusive,
|
||||
IntraDayDate.startOfDay(endExclusive));
|
||||
resetAssignmentsTo(assignmentsCreated);
|
||||
updateResourcesPerDay();
|
||||
}
|
||||
|
|
@ -521,19 +520,13 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
};
|
||||
}
|
||||
|
||||
private List<LocalDate> getDays(LocalDate startInclusive,
|
||||
LocalDate endExclusive) {
|
||||
private List<PartialDay> getDays(IntraDayDate startInclusive,
|
||||
IntraDayDate endExclusive) {
|
||||
Validate.notNull(startInclusive);
|
||||
Validate.notNull(endExclusive);
|
||||
Validate.isTrue(startInclusive.compareTo(endExclusive) <= 0,
|
||||
"the end must be equal or posterior than start");
|
||||
List<LocalDate> result = new ArrayList<LocalDate>();
|
||||
LocalDate current = startInclusive;
|
||||
while (current.compareTo(endExclusive) < 0) {
|
||||
result.add(current);
|
||||
current = current.plusDays(1);
|
||||
}
|
||||
return result;
|
||||
return IntraDayDate.toList(startInclusive.daysUntil(endExclusive));
|
||||
}
|
||||
|
||||
private class AllocateHoursOnInterval implements
|
||||
|
|
@ -573,9 +566,8 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
|
||||
private void allocate(LocalDate end, EffortDuration durationToAssign) {
|
||||
IntraDayDate startInclusive = getStartAfterConsolidated();
|
||||
List<T> assignmentsCreated = createAssignments(
|
||||
startInclusive.getDate(), end,
|
||||
durationToAssign);
|
||||
List<T> assignmentsCreated = createAssignments(startInclusive,
|
||||
IntraDayDate.startOfDay(end), durationToAssign);
|
||||
resetAssignmentsTo(assignmentsCreated);
|
||||
updateResourcesPerDay();
|
||||
}
|
||||
|
|
@ -587,28 +579,29 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
IntraDayDate start = IntraDayDate.max(
|
||||
IntraDayDate.startOfDay(startInclusive),
|
||||
firstDayNotConsolidated);
|
||||
List<T> assignmentsCreated = createAssignments(startInclusive,
|
||||
endExclusive, durationToAssign);
|
||||
List<T> assignmentsCreated = createAssignments(
|
||||
IntraDayDate.startOfDay(startInclusive),
|
||||
IntraDayDate.startOfDay(endExclusive), durationToAssign);
|
||||
resetAssigmentsForInterval(start.getDate(), endExclusive,
|
||||
assignmentsCreated);
|
||||
}
|
||||
|
||||
protected abstract AvailabilityTimeLine getResourcesAvailability();
|
||||
|
||||
private List<T> createAssignments(LocalDate startInclusive,
|
||||
LocalDate endExclusive, EffortDuration durationToAssign) {
|
||||
private List<T> createAssignments(IntraDayDate startInclusive,
|
||||
IntraDayDate endExclusive, EffortDuration durationToAssign) {
|
||||
List<T> assignmentsCreated = new ArrayList<T>();
|
||||
AvailabilityTimeLine availability = getAvailability();
|
||||
|
||||
List<LocalDate> days = getDays(startInclusive, endExclusive);
|
||||
List<PartialDay> days = getDays(startInclusive, endExclusive);
|
||||
EffortDuration[] durationsEachDay = secondsDistribution(
|
||||
availability, days, durationToAssign);
|
||||
int i = 0;
|
||||
for (LocalDate day : days) {
|
||||
for (PartialDay day : days) {
|
||||
// if all days are not available, it would try to assign
|
||||
// them anyway, preventing it with a check
|
||||
if (availability.isValid(day)) {
|
||||
assignmentsCreated.addAll(distributeForDay(day,
|
||||
if (availability.isValid(day.getDate())) {
|
||||
assignmentsCreated.addAll(distributeForDay(day.getDate(),
|
||||
durationsEachDay[i]));
|
||||
}
|
||||
i++;
|
||||
|
|
@ -638,11 +631,11 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
}
|
||||
|
||||
private EffortDuration[] secondsDistribution(
|
||||
AvailabilityTimeLine availability,
|
||||
List<LocalDate> days, EffortDuration duration) {
|
||||
AvailabilityTimeLine availability, List<PartialDay> days,
|
||||
EffortDuration duration) {
|
||||
List<Share> shares = new ArrayList<Share>();
|
||||
for (LocalDate day : days) {
|
||||
shares.add(getShareAt(day, availability));
|
||||
for (PartialDay each : days) {
|
||||
shares.add(getShareAt(each, availability));
|
||||
}
|
||||
ShareDivision original = ShareDivision.create(shares);
|
||||
ShareDivision newShare = original.plus(duration.getSeconds());
|
||||
|
|
@ -657,9 +650,9 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
return result;
|
||||
}
|
||||
|
||||
private Share getShareAt(LocalDate day,
|
||||
private Share getShareAt(PartialDay day,
|
||||
AvailabilityTimeLine availability) {
|
||||
if (availability.isValid(day)) {
|
||||
if (availability.isValid(day.getDate())) {
|
||||
EffortDuration capacityAtDay = getAllocationCalendar()
|
||||
.getCapacityOn(day);
|
||||
return new Share(-capacityAtDay.getSeconds());
|
||||
|
|
@ -759,7 +752,7 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
getDayAssignmentsState().removingAssignments(assignments);
|
||||
}
|
||||
|
||||
final EffortDuration calculateTotalToDistribute(LocalDate day,
|
||||
final EffortDuration calculateTotalToDistribute(PartialDay day,
|
||||
ResourcesPerDay resourcesPerDay) {
|
||||
return getAllocationCalendar().asDurationOn(day, resourcesPerDay);
|
||||
}
|
||||
|
|
@ -775,15 +768,10 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
EffortDuration sumWorkableEffort = zero();
|
||||
final ResourcesPerDay ONE_RESOURCE_PER_DAY = ResourcesPerDay.amount(1);
|
||||
for (Entry<LocalDate, List<T>> entry : byDay.entrySet()) {
|
||||
LocalDate day = entry.getKey();
|
||||
LocalDate dayDate = entry.getKey();
|
||||
PartialDay day = dayFor(dayDate);
|
||||
EffortDuration incrementWorkable = getAllocationCalendar()
|
||||
.asDurationOn(entry.getKey(), ONE_RESOURCE_PER_DAY);
|
||||
IntraDayDate intraDayEnd = getDayAssignmentsState()
|
||||
.getIntraDayEnd();
|
||||
if (intraDayEnd != null && day.equals(intraDayEnd.getDate())) {
|
||||
incrementWorkable = min(incrementWorkable,
|
||||
intraDayEnd.getEffortDuration());
|
||||
}
|
||||
.asDurationOn(day, ONE_RESOURCE_PER_DAY);
|
||||
sumWorkableEffort = sumWorkableEffort.plus(incrementWorkable);
|
||||
sumTotalEffort = sumTotalEffort.plus(getAssignedDuration(entry
|
||||
.getValue()));
|
||||
|
|
@ -794,6 +782,26 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
return ResourcesPerDay.calculateFrom(sumTotalEffort, sumWorkableEffort);
|
||||
}
|
||||
|
||||
private PartialDay dayFor(LocalDate dayDate) {
|
||||
IntraDayDate startDate = startFor(dayDate);
|
||||
|
||||
IntraDayDate intraDayEnd = getDayAssignmentsState()
|
||||
.getIntraDayEnd();
|
||||
if (intraDayEnd != null && dayDate.equals(intraDayEnd.getDate())) {
|
||||
return new PartialDay(startDate, intraDayEnd);
|
||||
}
|
||||
return new PartialDay(startDate, startDate.nextDayAtStart());
|
||||
}
|
||||
|
||||
private IntraDayDate startFor(LocalDate dayDate) {
|
||||
IntraDayDate start = getIntraDayStartDate();
|
||||
if (start.getDate().equals(dayDate)) {
|
||||
return start;
|
||||
} else {
|
||||
return IntraDayDate.startOfDay(dayDate);
|
||||
}
|
||||
}
|
||||
|
||||
public ICalendar getAllocationCalendar() {
|
||||
return getCalendarGivenTaskCalendar(getTaskCalendar());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ import org.navalplanner.business.util.deepcopy.OnCopy;
|
|||
import org.navalplanner.business.util.deepcopy.Strategy;
|
||||
import org.navalplanner.business.workingday.EffortDuration;
|
||||
import org.navalplanner.business.workingday.IntraDayDate;
|
||||
import org.navalplanner.business.workingday.IntraDayDate.PartialDay;
|
||||
import org.navalplanner.business.workingday.ResourcesPerDay;
|
||||
|
||||
/**
|
||||
|
|
@ -180,9 +181,10 @@ public class SpecificResourceAllocation extends
|
|||
|
||||
private final class SpecificAssignmentsAllocation extends
|
||||
AssignmentsAllocation {
|
||||
|
||||
@Override
|
||||
protected List<SpecificDayAssignment> distributeForDay(
|
||||
LocalDate day, EffortDuration effort) {
|
||||
protected List<SpecificDayAssignment> distributeForDay(LocalDate day,
|
||||
EffortDuration effort) {
|
||||
return Arrays.asList(SpecificDayAssignment.create(day, effort,
|
||||
resource));
|
||||
}
|
||||
|
|
@ -209,11 +211,11 @@ public class SpecificResourceAllocation extends
|
|||
return SpecificDayAssignment.class;
|
||||
}
|
||||
|
||||
public List<DayAssignment> createAssignmentsAtDay(LocalDate day,
|
||||
public List<DayAssignment> createAssignmentsAtDay(PartialDay day,
|
||||
ResourcesPerDay resourcesPerDay, EffortDuration limit) {
|
||||
EffortDuration effort = calculateTotalToDistribute(day, resourcesPerDay);
|
||||
SpecificDayAssignment specific = SpecificDayAssignment.create(day,
|
||||
min(limit, effort), resource);
|
||||
SpecificDayAssignment specific = SpecificDayAssignment.create(
|
||||
day.getDate(), min(limit, effort), resource);
|
||||
List<DayAssignment> result = new ArrayList<DayAssignment>();
|
||||
result.add(specific);
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import org.navalplanner.business.planner.entities.ResourceAllocation;
|
|||
import org.navalplanner.business.planner.entities.Task;
|
||||
import org.navalplanner.business.workingday.EffortDuration;
|
||||
import org.navalplanner.business.workingday.IntraDayDate;
|
||||
import org.navalplanner.business.workingday.IntraDayDate.PartialDay;
|
||||
import org.navalplanner.business.workingday.ResourcesPerDay;
|
||||
|
||||
public abstract class AllocatorForSpecifiedResourcesPerDayAndHours {
|
||||
|
|
@ -68,8 +69,8 @@ public abstract class AllocatorForSpecifiedResourcesPerDayAndHours {
|
|||
IntraDayDate currentEnd = start;
|
||||
for (EffortPerAllocation each : effortPerAllocation(start.getDate(),
|
||||
effortToAllocate)) {
|
||||
IntraDayDate endCandidate = untilAllocating(start.getDate(),
|
||||
each.allocation, each.duration);
|
||||
IntraDayDate endCandidate = untilAllocating(start, each.allocation,
|
||||
each.duration);
|
||||
currentEnd = IntraDayDate.max(currentEnd, endCandidate);
|
||||
i++;
|
||||
}
|
||||
|
|
@ -90,22 +91,27 @@ public abstract class AllocatorForSpecifiedResourcesPerDayAndHours {
|
|||
* @param effortRemaining
|
||||
* @return the moment on which the allocation would be completed
|
||||
*/
|
||||
private IntraDayDate untilAllocating(LocalDate start,
|
||||
private IntraDayDate untilAllocating(IntraDayDate start,
|
||||
ResourcesPerDayModification resourcesPerDayModification,
|
||||
EffortDuration effortRemaining) {
|
||||
EffortDuration taken = zero();
|
||||
LocalDate lastDate = start;
|
||||
for (LocalDate current = start; effortRemaining.compareTo(zero()) > 0; current = current
|
||||
.plusDays(1)) {
|
||||
IntraDayDate lastDate = start;
|
||||
for (IntraDayDate current = start; effortRemaining.compareTo(zero()) > 0; current = current.nextDayAtStart()) {
|
||||
lastDate = current;
|
||||
taken = assignForDay(resourcesPerDayModification,
|
||||
current, effortRemaining);
|
||||
dayStartingAt(current), effortRemaining);
|
||||
lastDate = IntraDayDate.create(current.getDate(), taken);
|
||||
effortRemaining = effortRemaining.minus(taken);
|
||||
}
|
||||
if (resourcesPerDayModification.isDayFilled(lastDate, taken)) {
|
||||
return IntraDayDate.startOfDay(lastDate.plusDays(1));
|
||||
if (resourcesPerDayModification.isDayFilled(lastDate.getDate(),
|
||||
taken)) {
|
||||
return lastDate.nextDayAtStart();
|
||||
}
|
||||
return IntraDayDate.create(lastDate, taken);
|
||||
return lastDate;
|
||||
}
|
||||
|
||||
private PartialDay dayStartingAt(IntraDayDate start) {
|
||||
return new PartialDay(start, start.nextDayAtStart());
|
||||
}
|
||||
|
||||
private void setAssignmentsForEachAllocation(IntraDayDate end) {
|
||||
|
|
@ -133,7 +139,7 @@ public abstract class AllocatorForSpecifiedResourcesPerDayAndHours {
|
|||
ResourcesPerDay resourcesPerDay, List<T> dayAssignments);
|
||||
|
||||
protected abstract List<DayAssignment> createAssignmentsAtDay(
|
||||
ResourcesPerDayModification allocation, LocalDate day,
|
||||
ResourcesPerDayModification allocation, PartialDay day,
|
||||
EffortDuration limit);
|
||||
|
||||
protected abstract boolean thereAreAvailableHoursFrom(LocalDate start,
|
||||
|
|
@ -144,7 +150,7 @@ public abstract class AllocatorForSpecifiedResourcesPerDayAndHours {
|
|||
|
||||
private EffortDuration assignForDay(
|
||||
ResourcesPerDayModification resourcesPerDayModification,
|
||||
LocalDate day, EffortDuration remaining) {
|
||||
PartialDay day, EffortDuration remaining) {
|
||||
List<DayAssignment> newAssignments = createAssignmentsAtDay(
|
||||
resourcesPerDayModification, day, remaining);
|
||||
resultAssignments.get(resourcesPerDayModification).addAll(
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import org.navalplanner.business.resources.daos.IResourceDAO;
|
|||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
import org.navalplanner.business.workingday.EffortDuration;
|
||||
import org.navalplanner.business.workingday.IntraDayDate.PartialDay;
|
||||
import org.navalplanner.business.workingday.ResourcesPerDay;
|
||||
|
||||
public abstract class ResourcesPerDayModification extends
|
||||
|
|
@ -71,7 +72,7 @@ public abstract class ResourcesPerDayModification extends
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<DayAssignment> createAssignmentsAtDay(LocalDate day,
|
||||
public List<DayAssignment> createAssignmentsAtDay(PartialDay day,
|
||||
EffortDuration limit) {
|
||||
return genericAllocation.createAssignmentsAtDay(getResources(),
|
||||
day, getGoal(), limit);
|
||||
|
|
@ -123,7 +124,7 @@ public abstract class ResourcesPerDayModification extends
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<DayAssignment> createAssignmentsAtDay(LocalDate day,
|
||||
public List<DayAssignment> createAssignmentsAtDay(PartialDay day,
|
||||
EffortDuration limit) {
|
||||
return resourceAllocation.createAssignmentsAtDay(day, getGoal(),
|
||||
limit);
|
||||
|
|
@ -209,14 +210,14 @@ public abstract class ResourcesPerDayModification extends
|
|||
|
||||
public abstract void applyAllocationUntil(LocalDate endExclusive);
|
||||
|
||||
public abstract List<DayAssignment> createAssignmentsAtDay(LocalDate day,
|
||||
public abstract List<DayAssignment> createAssignmentsAtDay(PartialDay day,
|
||||
EffortDuration limit);
|
||||
|
||||
public abstract AvailabilityTimeLine getAvailability();
|
||||
|
||||
public boolean isDayFilled(LocalDate lastDate, EffortDuration taken) {
|
||||
public boolean isDayFilled(LocalDate day, EffortDuration taken) {
|
||||
return getBeingModified().getAllocationCalendar()
|
||||
.asDurationOn(lastDate, goal).equals(taken);
|
||||
.asDurationOn(PartialDay.wholeDay(day), goal).equals(taken);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -276,4 +276,8 @@ public class IntraDayDate implements Comparable<IntraDayDate> {
|
|||
return Arrays.toString(new Object[] { date, effortDuration });
|
||||
}
|
||||
|
||||
public IntraDayDate nextDayAtStart() {
|
||||
return IntraDayDate.startOfDay(getDate().plusDays(1));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import org.navalplanner.business.planner.entities.allocationalgorithms.Resources
|
|||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
import org.navalplanner.business.resources.entities.Worker;
|
||||
import org.navalplanner.business.workingday.EffortDuration;
|
||||
import org.navalplanner.business.workingday.IntraDayDate;
|
||||
import org.navalplanner.business.workingday.ResourcesPerDay;
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ public class AllocationUntilFillingHoursTest {
|
|||
|
||||
private Task task;
|
||||
|
||||
private LocalDate startDate;
|
||||
private IntraDayDate startDate;
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void allTasksOfAllocationsMustBeNotNull() {
|
||||
|
|
@ -80,7 +81,7 @@ public class AllocationUntilFillingHoursTest {
|
|||
givenSpecificAllocations(ResourcesPerDay.amount(2));
|
||||
IntraDayDate endDate = ResourceAllocation.allocating(allocations)
|
||||
.untilAllocating(32);
|
||||
assertThat(endDate.getDate(), equalTo(startDate.plusDays(2)));
|
||||
assertThat(endDate.getDate(), equalTo(startDate.getDate().plusDays(2)));
|
||||
assertTrue(endDate.isStartOfDay());
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +90,7 @@ public class AllocationUntilFillingHoursTest {
|
|||
givenSpecificAllocations(ResourcesPerDay.amount(2));
|
||||
IntraDayDate endDate = ResourceAllocation.allocating(allocations)
|
||||
.untilAllocating(31);
|
||||
assertThat(endDate.getDate(), equalTo(startDate.plusDays(1)));
|
||||
assertThat(endDate.getDate(), equalTo(startDate.getDate().plusDays(1)));
|
||||
assertThat(endDate.getEffortDuration(), equalTo(hours(15)));
|
||||
}
|
||||
|
||||
|
|
@ -122,6 +123,18 @@ public class AllocationUntilFillingHoursTest {
|
|||
equalTo(ResourcesPerDay.amount(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void theResourcesPerDayIsCalculatedCorrectlyIfTheStartIsInTheMiddleOfADay() {
|
||||
givenStartDate(IntraDayDate.create(new LocalDate(2009, 10, 10),
|
||||
EffortDuration.hours(2)));
|
||||
givenSpecificAllocations(ResourcesPerDay.amount(1));
|
||||
ResourceAllocation.allocating(allocations).untilAllocating(8);
|
||||
ResourceAllocation<?> allocation = allocations.get(0)
|
||||
.getBeingModified();
|
||||
assertThat(allocation.getResourcesPerDay(),
|
||||
equalTo(ResourcesPerDay.amount(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void theResourcesPerDayAreKeptCorrectlyCalculatedAfterUpdatingTheEndInterval() {
|
||||
final ResourcesPerDay oneResourcePerDay = ResourcesPerDay.amount(1);
|
||||
|
|
@ -131,14 +144,15 @@ public class AllocationUntilFillingHoursTest {
|
|||
.get(0)
|
||||
.getBeingModified();
|
||||
// hours per day: 8, 8, 8, 6
|
||||
allocation.onInterval(startDate, startDate.plusDays(1))
|
||||
allocation.onInterval(startDate.getDate(),
|
||||
startDate.getDate().plusDays(1))
|
||||
.allocateHours(6);
|
||||
// hours per day: 6, 8, 8, 6
|
||||
assertTrue(allocation.getResourcesPerDay().getAmount()
|
||||
.compareTo(oneResourcePerDay.getAmount()) < 0);
|
||||
|
||||
allocation.onInterval(startDate.plusDays(3), startDate.plusDays(4))
|
||||
.allocateHours(8);
|
||||
allocation.onInterval(startDate.getDate().plusDays(3),
|
||||
startDate.getDate().plusDays(4)).allocateHours(8);
|
||||
// hours per day: 6, 8, 8, 8
|
||||
assertThat(allocation.getResourcesPerDay(), equalTo(oneResourcePerDay));
|
||||
// This last assertion is questionable. A solution would be to keep a
|
||||
|
|
@ -146,14 +160,16 @@ public class AllocationUntilFillingHoursTest {
|
|||
// the user and then the real values. In the meantime doing an effort to
|
||||
// keep the original value
|
||||
|
||||
allocation.onInterval(startDate.plusDays(4), startDate.plusDays(5))
|
||||
allocation.onInterval(startDate.getDate().plusDays(4),
|
||||
startDate.getDate().plusDays(5))
|
||||
.allocateHours(8);
|
||||
// hours per day: 6, 8, 8, 8, 8
|
||||
assertTrue(allocation.getResourcesPerDay().getAmount()
|
||||
.compareTo(oneResourcePerDay.getAmount()) < 0);
|
||||
|
||||
// hours per day: 6, 8, 8, 8, 10
|
||||
allocation.onInterval(startDate.plusDays(4), startDate.plusDays(5))
|
||||
allocation.onInterval(startDate.getDate().plusDays(4),
|
||||
startDate.getDate().plusDays(5))
|
||||
.allocateHours(10);
|
||||
assertThat(allocation.getResourcesPerDay(), equalTo(oneResourcePerDay));
|
||||
}
|
||||
|
|
@ -261,22 +277,24 @@ public class AllocationUntilFillingHoursTest {
|
|||
return worker;
|
||||
}
|
||||
|
||||
private void givenStartDate(IntraDayDate start) {
|
||||
this.startDate = start;
|
||||
}
|
||||
|
||||
private void createTaskIfNotCreatedYet() {
|
||||
if (task != null) {
|
||||
return;
|
||||
}
|
||||
task = createNiceMock(Task.class);
|
||||
if (startDate == null) {
|
||||
startDate = new LocalDate(2009, 10, 10);
|
||||
startDate = IntraDayDate.startOfDay(new LocalDate(2009, 10, 10));
|
||||
}
|
||||
expect(task.getStartDate()).andReturn(
|
||||
startDate.toDateTimeAtStartOfDay().toDate()).anyTimes();
|
||||
expect(task.getIntraDayStartDate()).andReturn(
|
||||
IntraDayDate.startOfDay(startDate)).anyTimes();
|
||||
expect(task.getIntraDayStartDate()).andReturn(startDate).anyTimes();
|
||||
expect(task.getCriterions()).andReturn(
|
||||
Collections.<Criterion> emptySet()).anyTimes();
|
||||
expect(task.getFirstDayNotConsolidated()).andReturn(
|
||||
IntraDayDate.startOfDay(startDate))
|
||||
expect(task.getFirstDayNotConsolidated()).andReturn(startDate)
|
||||
.anyTimes();
|
||||
replay(task);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ import org.navalplanner.business.resources.entities.Worker;
|
|||
import org.navalplanner.business.scenarios.entities.Scenario;
|
||||
import org.navalplanner.business.workingday.EffortDuration;
|
||||
import org.navalplanner.business.workingday.IntraDayDate;
|
||||
import org.navalplanner.business.workingday.IntraDayDate.PartialDay;
|
||||
import org.navalplanner.business.workingday.ResourcesPerDay;
|
||||
|
||||
public class GenericResourceAllocationTest {
|
||||
|
|
@ -96,11 +97,14 @@ public class GenericResourceAllocationTest {
|
|||
setupCriterions(task);
|
||||
IntraDayDate start = IntraDayDate.startOfDay(interval.getStart()
|
||||
.toLocalDate());
|
||||
IntraDayDate end = IntraDayDate.startOfDay(interval.getEnd()
|
||||
.toLocalDate());
|
||||
expect(task.getStartDate()).andReturn(interval.getStart().toDate())
|
||||
.anyTimes();
|
||||
expect(task.getIntraDayStartDate()).andReturn(start).anyTimes();
|
||||
expect(task.getEndDate()).andReturn(interval.getEnd().toDate())
|
||||
.anyTimes();
|
||||
expect(task.getIntraDayEndDate()).andReturn(end).anyTimes();
|
||||
expect(task.getFirstDayNotConsolidated()).andReturn(start)
|
||||
.anyTimes();
|
||||
expect(task.getCalendar()).andReturn(baseCalendar).anyTimes();
|
||||
|
|
@ -235,23 +239,30 @@ public class GenericResourceAllocationTest {
|
|||
BaseCalendar baseCalendar = createNiceMock(klass);
|
||||
expect(baseCalendar.getCapacityOn(isA(LocalDate.class)))
|
||||
.andReturn(hours(hoursPerDay)).anyTimes();
|
||||
expect(baseCalendar.getCapacityOn(isA(PartialDay.class))).andReturn(
|
||||
hours(hoursPerDay)).anyTimes();
|
||||
expect(baseCalendar.isActive(isA(LocalDate.class))).andReturn(true)
|
||||
.anyTimes();
|
||||
expect(baseCalendar.canWork(isA(LocalDate.class))).andReturn(true)
|
||||
.anyTimes();
|
||||
expect(baseCalendar.getAvailability()).andReturn(
|
||||
AvailabilityTimeLine.allValid()).anyTimes();
|
||||
IAnswer<EffortDuration> durationAnswer = new IAnswer<EffortDuration>() {
|
||||
@Override
|
||||
public EffortDuration answer() throws Throwable {
|
||||
ResourcesPerDay resourcesPerDay = (ResourcesPerDay) getCurrentArguments()[1];
|
||||
return resourcesPerDay
|
||||
.asDurationGivenWorkingDayOf(hours(hoursPerDay));
|
||||
}
|
||||
};
|
||||
expect(
|
||||
baseCalendar.asDurationOn(isA(LocalDate.class),
|
||||
isA(ResourcesPerDay.class))).andAnswer(
|
||||
new IAnswer<EffortDuration>() {
|
||||
@Override
|
||||
public EffortDuration answer() throws Throwable {
|
||||
ResourcesPerDay resourcesPerDay = (ResourcesPerDay) getCurrentArguments()[1];
|
||||
return resourcesPerDay
|
||||
.asDurationGivenWorkingDayOf(hours(hoursPerDay));
|
||||
}
|
||||
}).anyTimes();
|
||||
durationAnswer).anyTimes();
|
||||
expect(
|
||||
baseCalendar.asDurationOn(isA(PartialDay.class),
|
||||
isA(ResourcesPerDay.class))).andAnswer(durationAnswer)
|
||||
.anyTimes();
|
||||
if (baseCalendar instanceof ResourceCalendar) {
|
||||
ResourceCalendar resourceCalendar = (ResourceCalendar) baseCalendar;
|
||||
expect(resourceCalendar.getCapacity()).andReturn(1);
|
||||
|
|
|
|||
|
|
@ -193,6 +193,8 @@ public class SpecificResourceAllocationTest {
|
|||
IntraDayDate.startOfDay(start)).anyTimes();
|
||||
expect(task.getEndDate()).andReturn(
|
||||
end.toDateTimeAtStartOfDay().toDate()).anyTimes();
|
||||
expect(task.getIntraDayEndDate()).andReturn(
|
||||
IntraDayDate.startOfDay(end)).anyTimes();
|
||||
expect(task.getFirstDayNotConsolidated()).andReturn(
|
||||
IntraDayDate.startOfDay(start)).anyTimes();
|
||||
replay(task);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue