diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/StretchesFunction.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/StretchesFunction.java index 506f298f4..818cce830 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/StretchesFunction.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/StretchesFunction.java @@ -82,9 +82,8 @@ public class StretchesFunction extends AssignmentFunction { public static double[] getHoursPointsFor(int totalHours, List intervalsDefinedByStreches) { - double[] result = new double[intervalsDefinedByStreches.size() + 1]; - int i = 1; - result[0] = 0; + double[] result = new double[intervalsDefinedByStreches.size()]; + int i = 0; int accumulated = 0; for (Interval each : intervalsDefinedByStreches) { accumulated += each.getHoursFor(totalHours); @@ -95,9 +94,8 @@ public class StretchesFunction extends AssignmentFunction { public static double[] getDayPointsFor(LocalDate start, List intervalsDefinedByStreches) { - double[] result = new double[intervalsDefinedByStreches.size() + 1]; - result[0] = 0; - int i = 1; + double[] result = new double[intervalsDefinedByStreches.size()]; + int i = 0; for (Interval each : intervalsDefinedByStreches) { result[i++] = Days.daysBetween(start, each.getEnd()).getDays(); } @@ -429,16 +427,6 @@ public class StretchesFunction extends AssignmentFunction { return getStretchesPlusConsolidated().size() >= 2; } - public boolean checkFirstIntervalIsPosteriorToDate(LocalDate date) { - List intervals = StretchesFunction.intervalsFor( - resourceAllocation, getStretchesPlusConsolidated()); - if (intervals.isEmpty()) { - return false; - } - Interval first = intervals.get(0); - return first.getEnd().compareTo(date) > 0; - } - public boolean isInterpolated() { return getDesiredType().equals(StretchesFunctionTypeEnum.INTERPOLATED); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/allocation/streches/GraphicForStreches.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/allocation/streches/GraphicForStreches.java index d405c217f..236e59aeb 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/allocation/streches/GraphicForStreches.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/allocation/streches/GraphicForStreches.java @@ -164,14 +164,13 @@ public abstract class GraphicForStreches implements IGraphicGenerator { @Override public boolean areChartsEnabled(IStretchesFunctionModel model) { - return canComputeChartFrom(model.getResourceAllocation(), - model.getStretchesPlusConsolidated()); + return canComputeChartFrom(model.getStretchesPlusConsolidated()); } @Override protected XYModel getAccumulatedHoursChartData(List stretches, ResourceAllocation allocation, BigDecimal taskHours) { - if (!canComputeChartFrom(allocation, stretches)) { + if (!canComputeChartFrom(stretches)) { return new SimpleXYModel(); } int[] hoursForEachDayUsingSplines = hoursForEachDayInterpolatedUsingSplines( @@ -184,7 +183,7 @@ public abstract class GraphicForStreches implements IGraphicGenerator { protected XYModel getDedicationChart(List stretches, ResourceAllocation allocation, BigDecimal totalHours, BaseCalendar taskCalendar) { - if (!canComputeChartFrom(allocation, stretches)) { + if (!canComputeChartFrom(stretches)) { return new SimpleXYModel(); } int[] dataForChart = hoursForEachDayInterpolatedUsingSplines( @@ -192,10 +191,8 @@ public abstract class GraphicForStreches implements IGraphicGenerator { return createModelFrom(allocation.getStartDate(), dataForChart); } - private boolean canComputeChartFrom(ResourceAllocation allocation, - List stretches) { - return StretchesFunctionModel.areValidForInterpolation(allocation, - stretches); + private boolean canComputeChartFrom(List stretches) { + return StretchesFunctionModel.areValidForInterpolation(stretches); } private int[] hoursForEachDayInterpolatedUsingSplines( diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/allocation/streches/StretchesFunctionModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/allocation/streches/StretchesFunctionModel.java index 32196a582..aec814c8b 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/allocation/streches/StretchesFunctionModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/allocation/streches/StretchesFunctionModel.java @@ -27,6 +27,7 @@ import java.math.BigDecimal; import java.text.DateFormat; import java.util.Collections; import java.util.Date; +import java.util.Iterator; import java.util.List; import org.joda.time.LocalDate; @@ -39,7 +40,6 @@ import org.navalplanner.business.planner.entities.AssignmentFunction; import org.navalplanner.business.planner.entities.ResourceAllocation; import org.navalplanner.business.planner.entities.Stretch; import org.navalplanner.business.planner.entities.StretchesFunction; -import org.navalplanner.business.planner.entities.StretchesFunction.Interval; import org.navalplanner.business.planner.entities.StretchesFunctionTypeEnum; import org.navalplanner.business.planner.entities.Task; import org.springframework.beans.factory.annotation.Autowired; @@ -182,10 +182,6 @@ public class StretchesFunctionModel implements IStretchesFunctionModel { throw new ValidationException( _("There must be at least 2 stretches for doing interpolation")); } - if (!stretchesFunction.checkFirstIntervalIsPosteriorToDate(getTaskStartDate())) { - throw new ValidationException( - _("The first stretch must be after the first day for doing interpolation")); - } } if (originalStretchesFunction != null) { originalStretchesFunction @@ -197,26 +193,36 @@ public class StretchesFunctionModel implements IStretchesFunctionModel { } } - public static boolean areValidForInterpolation( - ResourceAllocation resourceAllocation, List stretches) { - return atLeastTwoStreches(stretches) - && theFirstIntervalIsPosteriorToFirstDay(resourceAllocation, - stretches); + public static boolean areValidForInterpolation(List stretches) { + return atLeastThreeStreches(stretches) + && areStretchesSortedAndWithIncrements(stretches); } - private static boolean atLeastTwoStreches(List stretches) { - return stretches.size() >= 2; + private static boolean atLeastThreeStreches(List stretches) { + return stretches.size() >= 3; } - private static boolean theFirstIntervalIsPosteriorToFirstDay( - ResourceAllocation resourceAllocation, List stretches) { - List intervals = StretchesFunction.intervalsFor( - resourceAllocation, stretches); - if (intervals.isEmpty()) { + private static boolean areStretchesSortedAndWithIncrements( + List stretches) { + if (stretches.isEmpty()) { return false; } - Interval first = intervals.get(0); - return first.getEnd().compareTo(resourceAllocation.getStartDate()) > 0; + + Iterator iterator = stretches.iterator(); + Stretch previous = iterator.next(); + while (iterator.hasNext()) { + Stretch current = iterator.next(); + if (current.getLengthPercentage().compareTo( + previous.getLengthPercentage()) <= 0) { + return false; + } + if (current.getAmountWorkPercentage().compareTo( + previous.getAmountWorkPercentage()) <= 0) { + return false; + } + previous = current; + } + return true; } @Override