diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/BaseCalendar.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/BaseCalendar.java index 6d8c7059d..b324b8f0c 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/BaseCalendar.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/BaseCalendar.java @@ -884,15 +884,6 @@ public class BaseCalendar extends IntegrationEntity implements IWorkHours { calendarAvailability.setEndDate(endDate); } - @Override - @Deprecated - public Integer toHours(LocalDate day, ResourcesPerDay resourcesPerDay) { - final EffortDuration workableHours = getWorkableTimeAt(day); - return limitOverAssignability(day, - resourcesPerDay.asDurationGivenWorkingDayOf(workableHours), - workableHours).roundToHours(); - } - @Override public EffortDuration asDurationOn(LocalDate day, ResourcesPerDay resourcesPerDay) { diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CombinedWorkHours.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CombinedWorkHours.java index cb5800121..0bad993b5 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CombinedWorkHours.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CombinedWorkHours.java @@ -82,12 +82,6 @@ public abstract class CombinedWorkHours implements IWorkHours { return current; } - @Override - @Deprecated - public Integer toHours(LocalDate day, ResourcesPerDay amount) { - return asDurationOn(day, amount).roundToHours(); - } - @Override public EffortDuration asDurationOn(LocalDate day, ResourcesPerDay amount) { EffortDuration result = null; diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/IWorkHours.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/IWorkHours.java index 5da31a855..5596416bd 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/IWorkHours.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/IWorkHours.java @@ -26,18 +26,6 @@ import org.navalplanner.business.workingday.ResourcesPerDay; public interface IWorkHours { - /** - * Translates the received amount into the corresponding hours at the given - * date - * - * @deprecated use asDurationOn - * @param day - * @param amount - * @return - */ - @Deprecated - public Integer toHours(LocalDate day, ResourcesPerDay amount); - /** * Translates the received amount into the corresponding duration at the * given date diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/SameWorkHoursEveryDay.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/SameWorkHoursEveryDay.java index ca2c695bf..0c0b656a9 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/SameWorkHoursEveryDay.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/SameWorkHoursEveryDay.java @@ -46,12 +46,6 @@ public class SameWorkHoursEveryDay implements IWorkHours { return EffortDuration.hours(hours); } - @Override - @Deprecated - public Integer toHours(LocalDate day, ResourcesPerDay amount) { - return asDurationOn(day, amount).roundToHours(); - } - @Override public EffortDuration asDurationOn(LocalDate day, ResourcesPerDay amount) { return amount.asDurationGivenWorkingDayOf(getCapacityDurationAt(day)); diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/ThereAreHoursOnWorkHoursCalculator.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/ThereAreHoursOnWorkHoursCalculator.java index e7d4603a2..b6d8b5a5d 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/ThereAreHoursOnWorkHoursCalculator.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/ThereAreHoursOnWorkHoursCalculator.java @@ -19,6 +19,9 @@ */ package org.navalplanner.business.calendars.entities; +import static org.navalplanner.business.workingday.EffortDuration.hours; +import static org.navalplanner.business.workingday.EffortDuration.zero; + import java.util.List; import org.joda.time.LocalDate; @@ -26,6 +29,7 @@ import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.EndOfTi import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.FixedPoint; import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.Interval; import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.StartOfTime; +import org.navalplanner.business.workingday.EffortDuration; import org.navalplanner.business.workingday.ResourcesPerDay; /** @@ -92,16 +96,17 @@ public class ThereAreHoursOnWorkHoursCalculator { private static int sumHoursUntil(IWorkHours workHours, int maximum, ResourcesPerDay resourcesPerDay, LocalDate start, LocalDate end) { - int result = 0; + EffortDuration result = zero(); + EffortDuration maximumDuration = hours(maximum); int days = org.joda.time.Days.daysBetween(start, end).getDays(); for (int i = 0; i < days; i++) { LocalDate current = start.plusDays(i); - result += workHours.toHours(current, resourcesPerDay); - if (result >= maximum) { - return result; + result = result.plus(workHours.asDurationOn(current, resourcesPerDay)); + if (result.compareTo(maximumDuration) >= 0) { + return result.getHours(); } } - return result; + return result.getHours(); } } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/EffortDistributor.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/EffortDistributor.java index fe27bf567..7f0dc0801 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/EffortDistributor.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/EffortDistributor.java @@ -237,8 +237,8 @@ public class EffortDistributor { EffortDuration alreadyAssigned = assignedHoursForResource .getAssignedDurationAt(resource, day); final int alreadyAssignedSeconds = alreadyAssigned.getSeconds(); - Integer capacityEachOneSeconds = workHoursForResource.toHours(day, - ONE) * 3600; + Integer capacityEachOneSeconds = workHoursForResource.asDurationOn( + day, ONE).getSeconds(); final int capacityUnits = resources.get(i).capacityUnits; assert capacityUnits >= 1; final int assignedForEach = alreadyAssignedSeconds / capacityUnits; diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/ResourceAllocation.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/ResourceAllocation.java index db567200b..8ebc14011 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/ResourceAllocation.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/ResourceAllocation.java @@ -725,9 +725,7 @@ public abstract class ResourceAllocation extends final EffortDuration calculateTotalToDistribute(LocalDate day, ResourcesPerDay resourcesPerDay) { - // FIXME get a duration from workHoursPerDay - return EffortDuration.hours(getWorkHoursPerDay().toHours(day, - resourcesPerDay)); + return getWorkHoursPerDay().asDurationOn(day, resourcesPerDay); } public ResourcesPerDay calculateResourcesPerDayFromAssignments() { @@ -739,11 +737,10 @@ public abstract class ResourceAllocation extends Map> byDay = DayAssignment.byDay(assignments); EffortDuration sumTotalEffort = zero(); EffortDuration sumWorkableEffort = zero(); - final ResourcesPerDay one = ResourcesPerDay.amount(1); + final ResourcesPerDay ONE_RESOURCE_PER_DAY = ResourcesPerDay.amount(1); for (Entry> entry : byDay.entrySet()) { - sumWorkableEffort = sumWorkableEffort - .plus(hours(getWorkHoursPerDay().toHours(entry.getKey(), - one))); + sumWorkableEffort = sumWorkableEffort.plus(getWorkHoursPerDay() + .asDurationOn(entry.getKey(), ONE_RESOURCE_PER_DAY)); sumTotalEffort = sumTotalEffort.plus(getAssignedDuration(entry .getValue())); } @@ -773,11 +770,6 @@ public abstract class ResourceAllocation extends } } - @Override - public Integer toHours(LocalDate day, ResourcesPerDay amount) { - return getSubyacent().toHours(day, amount); - } - @Override public EffortDuration asDurationOn(LocalDate day, ResourcesPerDay amount) { diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/limiting/entities/LimitingResourceAllocator.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/limiting/entities/LimitingResourceAllocator.java index af4db138b..07207d986 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/limiting/entities/LimitingResourceAllocator.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/limiting/entities/LimitingResourceAllocator.java @@ -21,6 +21,8 @@ package org.navalplanner.business.planner.limiting.entities; import static org.navalplanner.business.workingday.EffortDuration.hours; +import static org.navalplanner.business.workingday.EffortDuration.min; +import static org.navalplanner.business.workingday.EffortDuration.zero; import java.math.BigDecimal; import java.util.ArrayList; @@ -38,6 +40,7 @@ import org.navalplanner.business.planner.entities.SpecificDayAssignment; import org.navalplanner.business.planner.entities.SpecificResourceAllocation; import org.navalplanner.business.resources.entities.LimitingResourceQueue; import org.navalplanner.business.resources.entities.Resource; +import org.navalplanner.business.workingday.EffortDuration; import org.navalplanner.business.workingday.ResourcesPerDay; /** @@ -269,39 +272,45 @@ public class LimitingResourceAllocator { List assignments = new LinkedList(); LocalDate date = startTime.getDate(); - final int totalHours = resourceAllocation.getIntendedTotalHours(); - int hoursAssigned = 0; + final EffortDuration totalEffort = hours(resourceAllocation + .getIntendedTotalHours()); + EffortDuration effortAssigned = zero(); // Generate first day assignment - int hoursCanAllocate = hoursCanWorkOnDay(resource, date, startTime.getHour()); - int hoursToAllocate = Math.min(totalHours, hoursCanAllocate); + EffortDuration effortCanAllocate = effortCanWorkOnDay(resource, date, + startTime.getHour()); + EffortDuration effortToAllocate = min(totalEffort, effortCanAllocate); DayAssignment dayAssignment = createDayAssignment(resourceAllocation, - resource, date, hoursToAllocate); - hoursAssigned += addDayAssignment(assignments, dayAssignment); + resource, date, effortToAllocate); + effortAssigned = effortAssigned.plus(addDayAssignment(assignments, + dayAssignment)); // Generate rest of day assignments - for (date = date.plusDays(1); hoursAssigned < totalHours + for (date = date.plusDays(1); effortAssigned.compareTo(totalEffort) < 0 || endsAfter.isAfter(date); date = date.plusDays(1)) { - hoursAssigned += addDayAssignment(assignments, + effortAssigned = effortAssigned.plus(addDayAssignment( + assignments, generateDayAssignment(resourceAllocation, resource, date, - totalHours)); + totalEffort))); } - if (hoursAssigned > totalHours) { - stripStartAssignments(assignments, hoursAssigned - totalHours); + if (effortAssigned.compareTo(totalEffort) > 0) { + stripStartAssignments(assignments, + effortAssigned.minus(totalEffort)); } return new ArrayList(assignments); } private static void stripStartAssignments(List assignments, - int hoursSurplus) { + EffortDuration durationSurplus) { ListIterator listIterator = assignments.listIterator(); - while (listIterator.hasNext() && hoursSurplus > 0) { + while (listIterator.hasNext() && durationSurplus.compareTo(zero()) > 0) { DayAssignment current = listIterator.next(); - int hoursTaken = Math.min(hoursSurplus, current.getHours()); - hoursSurplus -= hoursTaken; - if (hoursTaken == current.getHours()) { + EffortDuration durationTaken = min(durationSurplus, + current.getDuration()); + durationSurplus = durationSurplus.minus(durationTaken); + if (durationTaken.compareTo(current.getDuration()) == 0) { listIterator.remove(); } else { - listIterator.set(current.withDuration(hours(hoursTaken))); + listIterator.set(current.withDuration(durationTaken)); } } } @@ -313,60 +322,77 @@ public class LimitingResourceAllocator { List assignments = new ArrayList(); LocalDate date = endTime.getDate(); - int totalHours = resourceAllocation.getIntendedTotalHours(); + EffortDuration totalIntended = hours(resourceAllocation + .getIntendedTotalHours()); // Generate last day assignment - int hoursCanAllocate = hoursCanWorkOnDay(resource, date, endTime.getHour()); - if (hoursCanAllocate > 0) { - int hoursToAllocate = Math.min(totalHours, hoursCanAllocate); - DayAssignment dayAssignment = createDayAssignment(resourceAllocation, resource, date, hoursToAllocate); - totalHours -= addDayAssignment(assignments, dayAssignment); + EffortDuration effortCanAllocate = effortCanWorkOnDay(resource, date, + endTime.getHour()); + if (effortCanAllocate.compareTo(zero()) > 0) { + EffortDuration effortToAllocate = min(totalIntended, + effortCanAllocate); + DayAssignment dayAssignment = createDayAssignment( + resourceAllocation, resource, date, effortToAllocate); + totalIntended = totalIntended.minus(addDayAssignment(assignments, + dayAssignment)); } // Generate rest of day assignments - for (date = date.minusDays(1); totalHours > 0; date = date.minusDays(1)) { - totalHours -= addDayAssignment(assignments, generateDayAssignment( - resourceAllocation, resource, date, totalHours)); + for (date = date.minusDays(1); totalIntended.compareTo(zero()) > 0; date = date + .minusDays(1)) { + totalIntended = totalIntended.minus(addDayAssignment( + assignments, + generateDayAssignment(resourceAllocation, resource, date, + totalIntended))); } return assignments; } - private static DayAssignment createDayAssignment(ResourceAllocation resourceAllocation, - Resource resource, LocalDate date, int hoursToAllocate) { + private static DayAssignment createDayAssignment( + ResourceAllocation resourceAllocation, Resource resource, + LocalDate date, EffortDuration toAllocate) { if (resourceAllocation instanceof SpecificResourceAllocation) { - return SpecificDayAssignment.create(date, hoursToAllocate, resource); + return SpecificDayAssignment.create(date, toAllocate, resource); } else if (resourceAllocation instanceof GenericResourceAllocation) { - return GenericDayAssignment.create(date, hoursToAllocate, resource); + return GenericDayAssignment.create(date, toAllocate, resource); } return null; } - private static int addDayAssignment(List list, DayAssignment dayAssignment) { + private static EffortDuration addDayAssignment(List list, + DayAssignment dayAssignment) { if (dayAssignment != null) { list.add(dayAssignment); - return dayAssignment.getHours(); + return dayAssignment.getDuration(); } - return 0; + return zero(); } - private static int hoursCanWorkOnDay(final Resource resource, + private static EffortDuration effortCanWorkOnDay(final Resource resource, final LocalDate date, int alreadyWorked) { final ResourceCalendar calendar = resource.getCalendar(); - int hoursCanAllocate = calendar.toHours(date, ONE_RESOURCE_PER_DAY); - return hoursCanAllocate - alreadyWorked; + EffortDuration durationCanAllocate = calendar + .asDurationOn(date, ONE_RESOURCE_PER_DAY); + EffortDuration alreadyWorkedAsDuration = hours(alreadyWorked); + if (durationCanAllocate.compareTo(alreadyWorkedAsDuration) <= 0) { + return zero(); + } + return durationCanAllocate.minus(alreadyWorkedAsDuration); } private static DayAssignment generateDayAssignment( final ResourceAllocation resourceAllocation, Resource resource, - final LocalDate date, int intentedHours) { + final LocalDate date, EffortDuration intendedEffort) { final ResourceCalendar calendar = resource.getCalendar(); - int hoursCanAllocate = calendar.toHours(date, ONE_RESOURCE_PER_DAY); - if (hoursCanAllocate > 0) { - int hoursToAllocate = Math.min(intentedHours, hoursCanAllocate); - return createDayAssignment(resourceAllocation, resource, date, hoursToAllocate); + EffortDuration effortCanAllocate = calendar.asDurationOn(date, + ONE_RESOURCE_PER_DAY); + if (effortCanAllocate.compareTo(zero()) > 0) { + EffortDuration toAllocate = min(intendedEffort, effortCanAllocate); + return createDayAssignment(resourceAllocation, resource, date, + toAllocate); } return null; } diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/GenericResourceAllocationTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/GenericResourceAllocationTest.java index 9be745563..cec434911 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/GenericResourceAllocationTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/GenericResourceAllocationTest.java @@ -234,23 +234,21 @@ public class GenericResourceAllocationTest { .andReturn(hours(hoursPerDay)).anyTimes(); expect(baseCalendar.isActive(isA(LocalDate.class))).andReturn(true) .anyTimes(); - expect( - baseCalendar.toHours(isA(LocalDate.class), - isA(ResourcesPerDay.class))).andAnswer( - new IAnswer() { - - @Override - public Integer answer() throws Throwable { - ResourcesPerDay resourcesPerDay = (ResourcesPerDay) getCurrentArguments()[1]; - return resourcesPerDay.asDurationGivenWorkingDayOf( - EffortDuration.hours(hoursPerDay)) - .roundToHours(); - } - }).anyTimes(); expect(baseCalendar.canWork(isA(LocalDate.class))).andReturn(true) .anyTimes(); expect(baseCalendar.getAvailability()).andReturn( AvailabilityTimeLine.allValid()).anyTimes(); + expect( + baseCalendar.asDurationOn(isA(LocalDate.class), + isA(ResourcesPerDay.class))).andAnswer( + new IAnswer() { + @Override + public EffortDuration answer() throws Throwable { + ResourcesPerDay resourcesPerDay = (ResourcesPerDay) getCurrentArguments()[1]; + return resourcesPerDay + .asDurationGivenWorkingDayOf(hours(hoursPerDay)); + } + }).anyTimes(); if (baseCalendar instanceof ResourceCalendar) { ResourceCalendar resourceCalendar = (ResourceCalendar) baseCalendar; expect(resourceCalendar.getCapacity()).andReturn(1); @@ -569,10 +567,14 @@ public class GenericResourceAllocationTest { private ResourceCalendar createCalendar(int capacity, int unit) { ResourceCalendar calendar = createNiceMock(ResourceCalendar.class); - expect(calendar.toHours(isA(LocalDate.class), - isA(ResourcesPerDay.class))).andReturn(unit).anyTimes(); expect(calendar.isActive(isA(LocalDate.class))).andReturn(true) .anyTimes(); + + expect( + calendar.asDurationOn(isA(LocalDate.class), + isA(ResourcesPerDay.class))).andReturn(hours(unit)) + .anyTimes(); + expect(calendar.canWork(isA(LocalDate.class))).andReturn(true) .anyTimes(); expect(calendar.getCapacity()).andReturn(capacity).anyTimes(); diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/SpecificResourceAllocationTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/SpecificResourceAllocationTest.java index c67fb25b1..31186df06 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/SpecificResourceAllocationTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/SpecificResourceAllocationTest.java @@ -80,9 +80,6 @@ public class SpecificResourceAllocationTest { this.calendar = createNiceMock(ResourceCalendar.class); expect(this.calendar.getCapacityDurationAt(isA(LocalDate.class))) .andReturn(EffortDuration.hours(hours)).anyTimes(); - expect(this.calendar.toHours(isA(LocalDate.class), - isA(ResourcesPerDay.class))).andAnswer( - toHoursAnswer(hours)).anyTimes(); expect( this.calendar.asDurationOn(isA(LocalDate.class), isA(ResourcesPerDay.class))).andAnswer( @@ -147,10 +144,6 @@ public class SpecificResourceAllocationTest { return toHoursAnswer(hours).answer(); } }; - expect( - this.calendar.toHours(isA(LocalDate.class), - isA(ResourcesPerDay.class))).andAnswer(toHoursAnswer) - .anyTimes(); expect( this.calendar.asDurationOn(isA(LocalDate.class), isA(ResourcesPerDay.class))).andAnswer(