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 bafe9f84f..040a2e725 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 @@ -263,33 +263,25 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar { } public EffortDuration getCapacityOn(PartialDay date) { - return date.limitDuration(getWorkableTimeAt(date.getDate())); + return date.limitDuration(findCapacityAt(date.getDate()) + .getStandardEffort()); } - private EffortDuration getWorkableTimeAt(LocalDate date) { + private Capacity findCapacityAt(LocalDate date) { if (!isActive(date)) { - return EffortDuration.zero(); + return Capacity.zero(); } CalendarException exceptionDay = getExceptionDay(date); if (exceptionDay != null) { - return exceptionDay.getDuration(); + return exceptionDay.getCapacity(); } - return getCapacityConsideringCalendarDatasOn(date, getDayFrom(date)) - .getStandardEffort(); + return getCapacityConsideringCalendarDatasOn(date, getDayFrom(date)); } private Days getDayFrom(LocalDate date) { return Days.values()[date.getDayOfWeek() - 1]; } - private boolean isOverAssignable(LocalDate localDate) { - CalendarException exceptionDay = getExceptionDay(localDate); - if (exceptionDay != null) { - return exceptionDay.getType().isOverAssignableWithoutLimit(); - } - return true; - } - public Capacity getCapacityConsideringCalendarDatasOn(LocalDate date, Days day) { CalendarData calendarData = getCalendarData(date); @@ -750,24 +742,12 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar { @Override public EffortDuration asDurationOn(PartialDay day, ResourcesPerDay amount) { - EffortDuration workableDuration = day - .limitDuration(getWorkableTimeAt(day.getDate())); + Capacity capacity = findCapacityAt(day.getDate()); + EffortDuration workableDuration = day.limitDuration(capacity + .getStandardEffort()); EffortDuration asDuration = amount .asDurationGivenWorkingDayOf(workableDuration); - return limitOverAssignability(day.getDate(), asDuration, - workableDuration); - } - - private EffortDuration limitOverAssignability(LocalDate day, - EffortDuration effortInitiallyCalculated, - EffortDuration workableHoursAtDay) { - boolean overAssignable = isOverAssignable(day); - if (overAssignable) { - return effortInitiallyCalculated; - } else { - return EffortDuration.min(effortInitiallyCalculated, - multiplyByCapacity(workableHoursAtDay)); - } + return capacity.limitDuration(asDuration); } /** diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/Capacity.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/Capacity.java index 07f88d2f2..db1bf51df 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/Capacity.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/Capacity.java @@ -142,4 +142,12 @@ public class Capacity { .append(allowedExtraEffort).toHashCode(); } + public EffortDuration limitDuration(EffortDuration duration) { + if (isOverAssignableWithoutLimit()) { + return duration; + } + return EffortDuration.min(standardEffort.plus(allowedExtraEffort), + duration); + } + } diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/BaseCalendarTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/BaseCalendarTest.java index 6ff9c4b98..84d35e7c5 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/BaseCalendarTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/BaseCalendarTest.java @@ -42,6 +42,8 @@ import org.navalplanner.business.calendars.entities.CalendarException; import org.navalplanner.business.calendars.entities.CalendarExceptionType; import org.navalplanner.business.calendars.entities.Capacity; import org.navalplanner.business.workingday.EffortDuration; +import org.navalplanner.business.workingday.IntraDayDate.PartialDay; +import org.navalplanner.business.workingday.ResourcesPerDay; /** * Tests for {@link BaseCalendar}. @@ -773,4 +775,107 @@ public class BaseCalendarTest { assertTrue(nonWorkableDays.contains(SUNDAY_LOCAL_DATE)); } + @Test + public void aCalendarHasAMethodToConvertAnAmountOfResourcesPerDayToAEffortDuration() { + BaseCalendar calendar = createBasicCalendar(); + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(1)), equalTo(hours(8))); + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(2)), equalTo(hours(16))); + } + + @Test + public void asDurationOnRespectsTheOverAssignablePropertyOfCalendarData() { + BaseCalendar calendar = createBasicCalendar(); + calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(8)) + .overAssignableWithoutLimit(true)); + + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(1)), equalTo(hours(8))); + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(2)), equalTo(hours(16))); + } + + @Test + public void asDurationOnRespectsTheNotOverAssignablePropertyOfCalendarData() { + BaseCalendar calendar = createBasicCalendar(); + calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(8)) + .overAssignableWithoutLimit(false)); + + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(1)), equalTo(hours(8))); + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(2)), equalTo(hours(8))); + } + + @Test + public void DurationOnRespectsTheExtraEffortPropertyOfCalendarData() { + BaseCalendar calendar = createBasicCalendar(); + calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(8)) + .extraEffort(hours(2))); + + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(1)), equalTo(hours(8))); + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(2)), equalTo(hours(10))); + + } + + private void addExceptionOn(BaseCalendar calendar, LocalDate onDate, + Capacity capacity) { + calendar.addExceptionDay(CalendarException.create(onDate, capacity, + createCalendarExceptionType())); + } + + @Test + public void asDurationOnRespectsAnOverAssignableCalendarException() { + BaseCalendar calendar = createBasicCalendar(); + addExceptionOn(calendar, MONDAY_LOCAL_DATE, Capacity.create(hours(1)) + .overAssignableWithoutLimit(true)); + + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(1)), equalTo(hours(1))); + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(2)), equalTo(hours(2))); + } + + @Test + public void asDurationOnRespectsANotOverAssignableCalendarException() { + BaseCalendar calendar = createBasicCalendar(); + addExceptionOn(calendar, MONDAY_LOCAL_DATE, Capacity.create(hours(1)) + .overAssignableWithoutLimit(false)); + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(1)), equalTo(hours(1))); + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(2)), equalTo(hours(1))); + } + + @Test + public void asDurationOnRespectsCapacityExtraEffort() { + BaseCalendar calendar = createBasicCalendar(); + addExceptionOn(calendar, MONDAY_LOCAL_DATE, Capacity.create(hours(2)) + .extraEffort(hours(3))); + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(1)), equalTo(hours(2))); + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(2)), equalTo(hours(4))); + assertThat(calendar.asDurationOn( + PartialDay.wholeDay(MONDAY_LOCAL_DATE), + ResourcesPerDay.amount(3)), equalTo(hours(5))); + } + }