From c59e5284bf5d74705f626a5a13dd105c2c97f8a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Tue, 19 Oct 2010 00:01:56 +0200 Subject: [PATCH] ThereAreHoursOnWorkHoursCalculator.thereIsAvailableCapacityFor returns an object with extra information This way the cause of not having enought capacity can be guessed. FEA: ItEr62S05BugFixing --- .../calendars/entities/BaseCalendar.java | 3 +- .../calendars/entities/CombinedWorkHours.java | 5 +- .../ThereAreHoursOnWorkHoursCalculator.java | 156 ++++++++++++++++-- .../UntilFillingHoursAllocatorTest.java | 3 +- 4 files changed, 150 insertions(+), 17 deletions(-) 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 787069514..950196e77 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 @@ -917,7 +917,8 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar { public boolean thereAreCapacityFor(AvailabilityTimeLine availability, ResourcesPerDay resourcesPerDay, EffortDuration durationToAllocate) { return ThereAreHoursOnWorkHoursCalculator.thereIsAvailableCapacityFor( - this, availability, resourcesPerDay, durationToAllocate); + this, availability, resourcesPerDay, durationToAllocate) + .thereIsCapacityAvailable(); } public boolean onlyGivesZeroHours() { 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 80f08927c..428e01bd1 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 @@ -112,8 +112,9 @@ public abstract class CombinedWorkHours implements ICalendar { @Override public boolean thereAreCapacityFor(AvailabilityTimeLine availability, ResourcesPerDay resourcesPerDay, EffortDuration durationToAllocate) { - return ThereAreHoursOnWorkHoursCalculator.thereIsAvailableCapacityFor(this, - availability, resourcesPerDay, durationToAllocate); + return ThereAreHoursOnWorkHoursCalculator.thereIsAvailableCapacityFor( + this, availability, resourcesPerDay, durationToAllocate) + .thereIsCapacityAvailable(); } } 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 82cd44dab..3bff6858b 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 @@ -21,6 +21,9 @@ package org.navalplanner.business.calendars.entities; import static org.navalplanner.business.workingday.EffortDuration.zero; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; import org.joda.time.LocalDate; @@ -38,38 +41,164 @@ import org.navalplanner.business.workingday.ResourcesPerDay; */ public class ThereAreHoursOnWorkHoursCalculator { - // Not instantiable + // Not instantiableisCapacityAvailable private ThereAreHoursOnWorkHoursCalculator() { } + public static abstract class CapacityResult { + public final boolean thereIsCapacityAvailable() { + return match(new IMatcher() { + + @Override + public Boolean on(CapacityAvailable result) { + return true; + } + + @Override + public Boolean on(ThereAreNoValidPeriods result) { + return false; + } + + @Override + public Boolean on(ValidPeriodsDontHaveCapacity result) { + return false; + } + + @Override + public Boolean on(ResourcesPerDayIsZero result) { + return false; + } + }); + } + + public interface IMatcher { + public T on(CapacityAvailable result); + + public T on(ThereAreNoValidPeriods result); + + public T on(ValidPeriodsDontHaveCapacity result); + + public T on(ResourcesPerDayIsZero result); + } + + public abstract T match(IMatcher matcher); + } + + public static class CapacityAvailable extends CapacityResult { + + private CapacityAvailable() { + } + + @Override + public T match(IMatcher matcher) { + return matcher.on(this); + } + + } + + public static class ThereAreNoValidPeriods extends CapacityResult { + + private final ICalendar specifiedCalendar; + + private final AvailabilityTimeLine specifiedAdditionalAvailability; + + private ThereAreNoValidPeriods(ICalendar specifiedCalendar, + AvailabilityTimeLine specifiedAdditionalAvailability) { + this.specifiedCalendar = specifiedCalendar; + this.specifiedAdditionalAvailability = specifiedAdditionalAvailability; + } + + public ICalendar getSpecifiedCalendar() { + return specifiedCalendar; + } + + public AvailabilityTimeLine getSpecifiedAdditionalAvailability() { + return specifiedAdditionalAvailability; + } + + @Override + public T match(IMatcher matcher) { + return matcher.on(this); + } + + } + + public static class ValidPeriodsDontHaveCapacity extends CapacityResult { + + private final List validPeriods; + + private final EffortDuration sumReached; + + private final EffortDuration effortNeeded; + + private ValidPeriodsDontHaveCapacity( + Collection validPeriods, + EffortDuration sumReached, EffortDuration effortNeeded) { + this.validPeriods = Collections + .unmodifiableList(new ArrayList(validPeriods)); + this.sumReached = sumReached; + this.effortNeeded = effortNeeded; + } + + public List getValidPeriods() { + return validPeriods; + } + + public EffortDuration getSumReached() { + return sumReached; + } + + public EffortDuration getEffortNeeded() { + return effortNeeded; + } + + @Override + public T match(IMatcher matcher) { + return matcher.on(this); + } + } + + public static class ResourcesPerDayIsZero extends CapacityResult { + + private ResourcesPerDayIsZero() { + } + + @Override + public T match(IMatcher matcher) { + return matcher.on(this); + } + + } + /** * Caculates if there are enough hours */ - public static boolean thereIsAvailableCapacityFor(ICalendar calendar, + public static CapacityResult thereIsAvailableCapacityFor( + ICalendar calendar, AvailabilityTimeLine availability, ResourcesPerDay resourcesPerDay, EffortDuration effortToAllocate) { if (effortToAllocate.isZero()) { - return true; + return new CapacityAvailable(); } if (resourcesPerDay.isZero()) { - return false; + return new ResourcesPerDayIsZero(); } AvailabilityTimeLine realAvailability = calendar.getAvailability() .and(availability); List validPeriods = realAvailability.getValidPeriods(); if (validPeriods.isEmpty()) { - return false; + return new ThereAreNoValidPeriods(calendar, availability); } Interval last = getLast(validPeriods); Interval first = validPeriods.get(0); final boolean isOpenEnded = last.getEnd().equals(EndOfTime.create()) || first.getStart().equals(StartOfTime.create()); - - return isOpenEnded - || thereAreCapacityOn(calendar, effortToAllocate, - resourcesPerDay, - validPeriods); + if (isOpenEnded) { + return new CapacityAvailable(); + } + return thereIsCapacityOn(calendar, effortToAllocate, resourcesPerDay, + validPeriods); } @@ -77,7 +206,7 @@ public class ThereAreHoursOnWorkHoursCalculator { return validPeriods.get(validPeriods.size() - 1); } - private static boolean thereAreCapacityOn(ICalendar calendar, + private static CapacityResult thereIsCapacityOn(ICalendar calendar, EffortDuration effortToAllocate, ResourcesPerDay resourcesPerDay, List validPeriods) { EffortDuration sum = zero(); @@ -88,10 +217,11 @@ public class ThereAreHoursOnWorkHoursCalculator { sum = sum.plus(sumDurationUntil(calendar, pending, resourcesPerDay, start.getDate(), end.getDate())); if (sum.compareTo(effortToAllocate) >= 0) { - return true; + return new CapacityAvailable(); } } - return false; + return new ValidPeriodsDontHaveCapacity(validPeriods, sum, + effortToAllocate); } private static EffortDuration sumDurationUntil(ICalendar calendar, diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/UntilFillingHoursAllocatorTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/UntilFillingHoursAllocatorTest.java index fbd9967f5..728962e5f 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/UntilFillingHoursAllocatorTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/UntilFillingHoursAllocatorTest.java @@ -457,7 +457,8 @@ public class UntilFillingHoursAllocatorTest { return ThereAreHoursOnWorkHoursCalculator .thereIsAvailableCapacityFor(result, availability, resourcesPerDay, - effortDuration); + effortDuration) + .thereIsCapacityAvailable(); } }).anyTimes(); replay(result);