diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/chart/ResourceLoadChartData.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/chart/ResourceLoadChartData.java index 943dfa13b..e10f7d756 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/chart/ResourceLoadChartData.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/chart/ResourceLoadChartData.java @@ -81,11 +81,11 @@ public class ResourceLoadChartData implements ILoadChartData { this.availability = toSortedMap(availabilityOnAllResources); } - private IValueTransformer, EffortDuration> extractOverload() { + public static IValueTransformer, EffortDuration> extractOverload() { return compound(effortByResource(), calculateOverload()); } - private IValueTransformer, Map> effortByResource() { + private static IValueTransformer, Map> effortByResource() { return new IValueTransformer, Map>() { @Override @@ -104,7 +104,7 @@ public class ResourceLoadChartData implements ILoadChartData { }; } - private IValueTransformer, EffortDuration> calculateOverload() { + public static IValueTransformer, EffortDuration> calculateOverload() { return new IValueTransformer, EffortDuration>() { @Override @@ -128,7 +128,7 @@ public class ResourceLoadChartData implements ILoadChartData { }; } - private IValueTransformer, EffortDuration> extractLoad() { + public static IValueTransformer, EffortDuration> extractLoad() { return new IValueTransformer, EffortDuration>() { @Override @@ -139,7 +139,7 @@ public class ResourceLoadChartData implements ILoadChartData { }; } - private IValueTransformer, EffortDuration> extractAvailabilityOnAssignedResources() { + public static IValueTransformer, EffortDuration> extractAvailabilityOnAssignedResources() { return new IValueTransformer, EffortDuration>() { @Override diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/OrderPlanningModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/OrderPlanningModel.java index 955f531f8..60ee689b0 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/OrderPlanningModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/OrderPlanningModel.java @@ -21,8 +21,9 @@ package org.navalplanner.web.planner.order; -import static org.navalplanner.business.workingday.EffortDuration.min; -import static org.navalplanner.business.workingday.EffortDuration.zero; +import static org.navalplanner.business.planner.chart.ContiguousDaysLine.min; +import static org.navalplanner.business.planner.chart.ContiguousDaysLine.sum; +import static org.navalplanner.business.planner.chart.ContiguousDaysLine.toSortedMap; import static org.navalplanner.web.I18nHelper._; import java.math.BigDecimal; @@ -44,6 +45,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.joda.time.DateTime; import org.joda.time.LocalDate; +import org.navalplanner.business.calendars.entities.AvailabilityTimeLine; import org.navalplanner.business.common.AdHocTransactionService; import org.navalplanner.business.common.IAdHocTransactionService; import org.navalplanner.business.common.IOnTransaction; @@ -55,6 +57,8 @@ import org.navalplanner.business.orders.entities.HoursGroup; import org.navalplanner.business.orders.entities.Order; import org.navalplanner.business.orders.entities.OrderElement; import org.navalplanner.business.orders.entities.OrderStatusEnum; +import org.navalplanner.business.planner.chart.ContiguousDaysLine; +import org.navalplanner.business.planner.chart.ResourceLoadChartData; import org.navalplanner.business.planner.entities.DayAssignment; import org.navalplanner.business.planner.entities.ICostCalculator; import org.navalplanner.business.planner.entities.Task; @@ -72,8 +76,6 @@ import org.navalplanner.business.users.entities.OrderAuthorizationType; import org.navalplanner.business.users.entities.User; import org.navalplanner.business.users.entities.UserRole; import org.navalplanner.business.workingday.EffortDuration; -import org.navalplanner.business.workingday.EffortDuration.IEffortFrom; -import org.navalplanner.business.workingday.IntraDayDate.PartialDay; import org.navalplanner.web.calendars.BaseCalendarModel; import org.navalplanner.web.common.ViewSwitcher; import org.navalplanner.web.planner.ITaskElementAdapter; @@ -1128,12 +1130,6 @@ public class OrderPlanningModel implements IOrderPlanningModel { private final Order order; - private SortedMap mapOrderLoad = new TreeMap(); - private SortedMap mapOrderOverload = new TreeMap(); - private SortedMap mapMaxCapacity = new TreeMap(); - private SortedMap mapOtherLoad = new TreeMap(); - private SortedMap mapOtherOverload = new TreeMap(); - public OrderLoadChartFiller(Order orderReloaded) { this.order = orderReloaded; } @@ -1147,34 +1143,45 @@ public class OrderPlanningModel implements IOrderPlanningModel { Clients.evalJavaScript(javascript); resetMinimumAndMaximumValueForChart(); - resetMaps(); List orderDayAssignments = order.getDayAssignments(); - SortedMap> orderDayAssignmentsGrouped = groupDurationsByDayAndResource(orderDayAssignments); + ContiguousDaysLine> orderAssignments = ContiguousDaysLine + .byDay(orderDayAssignments); + ContiguousDaysLine> allAssignments = allAssignments(orderAssignments); - List resourcesDayAssignments = new ArrayList(); - for (Resource resource : order.getResources()) { - resourcesDayAssignments.addAll(planningState - .getAssignmentsCalculator().getAssignments(resource)); - } - SortedMap> resourceDayAssignmentsGrouped = groupDurationsByDayAndResource(resourcesDayAssignments); - - fillMaps(orderDayAssignmentsGrouped, resourceDayAssignmentsGrouped); - convertAsNeededByZoomMaps(); + ContiguousDaysLine maxCapacityOnResources = orderAssignments + .transform(ResourceLoadChartData + .extractAvailabilityOnAssignedResources()); + ContiguousDaysLine orderLoad = orderAssignments + .transform(ResourceLoadChartData.extractLoad()); + ContiguousDaysLine allLoad = allAssignments + .transform(ResourceLoadChartData.extractLoad()); + ContiguousDaysLine orderOverload = orderAssignments + .transform(ResourceLoadChartData.extractOverload()); + ContiguousDaysLine allOverload = allAssignments + .transform(ResourceLoadChartData.extractOverload()); Plotinfo plotOrderLoad = createPlotinfoFromDurations( - mapOrderLoad, interval); - Plotinfo plotOrderOverload = createPlotinfoFromDurations( - mapOrderOverload, - interval); - Plotinfo plotMaxCapacity = createPlotinfoFromDurations( - mapMaxCapacity, interval); + groupAsNeededByZoom(toSortedMap(ContiguousDaysLine.min( + orderLoad, maxCapacityOnResources))), interval); + Plotinfo plotOtherLoad = createPlotinfoFromDurations( - mapOtherLoad, interval); - Plotinfo plotOtherOverload = createPlotinfoFromDurations( - mapOtherOverload, + groupAsNeededByZoom(toSortedMap(min(allLoad, + maxCapacityOnResources))), interval); + Plotinfo plotMaxCapacity = createPlotinfoFromDurations( + groupAsNeededByZoom(toSortedMap(maxCapacityOnResources)), + interval); + + Plotinfo plotOrderOverload = createPlotinfoFromDurations( + groupAsNeededByZoom(toSortedMap(sum(orderOverload, + maxCapacityOnResources))), interval); + + Plotinfo plotOtherOverload = createPlotinfoFromDurations( + groupAsNeededByZoom(toSortedMap(sum(allOverload, + maxCapacityOnResources))), interval); + plotOrderLoad.setFillColor(COLOR_ASSIGNED_LOAD_SPECIFIC); plotOrderLoad.setLineWidth(0); @@ -1209,109 +1216,38 @@ public class OrderPlanningModel implements IOrderPlanningModel { chart.setHeight("150px"); } - private void resetMaps() { - mapOrderLoad.clear(); - mapOrderOverload.clear(); - mapMaxCapacity.clear(); - mapOtherLoad.clear(); - mapOtherOverload.clear(); - } - - private void convertAsNeededByZoomMaps() { - mapOrderLoad = groupAsNeededByZoom(mapOrderLoad); - mapOrderOverload = groupAsNeededByZoom(mapOrderOverload); - mapMaxCapacity = groupAsNeededByZoom(mapMaxCapacity); - mapOtherLoad = groupAsNeededByZoom(mapOtherLoad); - mapOtherOverload = groupAsNeededByZoom(mapOtherOverload); - } - - private void fillMaps( - SortedMap> orderDayAssignmentsGrouped, - SortedMap> resourceDayAssignmentsGrouped) { - - for (LocalDate date : orderDayAssignmentsGrouped.keySet()) { - final EffortDuration maxCapacity = getSumCapacities( - orderDayAssignmentsGrouped, date); - final PartialDay day = PartialDay.wholeDay(date); - EffortDuration orderLoad = zero(); - EffortDuration orderOverload = zero(); - EffortDuration otherLoad = zero(); - EffortDuration otherOverload = zero(); - - for (Resource resource : orderDayAssignmentsGrouped.get(date) - .keySet()) { - final EffortDuration resourceCapacityHours = calendarCapacityFor( - resource, day); - - final EffortDuration durationAtOrder = orderDayAssignmentsGrouped - .get(date).get(resource); - - final EffortDuration totalDurationForResource; - totalDurationForResource = retrieveTotalDurationForResource( - resourceDayAssignmentsGrouped, date, resource); - - final EffortDuration durationOther; - durationOther = totalDurationForResource.minus(min( - durationAtOrder, totalDurationForResource)); - - final EffortDuration allDuration = durationAtOrder - .plus(durationOther); - - final EffortDuration orderLoadIncrement; - orderLoadIncrement = min(durationAtOrder, - resourceCapacityHours); - - final EffortDuration orderOverloadIncrement; - orderOverloadIncrement = durationAtOrder - .minus(orderLoadIncrement); - - final EffortDuration otherLoadIncrement; - otherLoadIncrement = min(allDuration, resourceCapacityHours) - .minus(min(resourceCapacityHours, durationAtOrder)); - - final EffortDuration otherOverloadIncrement; - otherOverloadIncrement = durationOther - .minus(otherLoadIncrement); - - orderLoad = orderLoad.plus(orderLoadIncrement); - orderOverload = orderOverload.plus(orderOverloadIncrement); - otherLoad = otherLoad.plus(otherLoadIncrement); - otherOverload = otherOverload.plus(otherOverloadIncrement); - } - mapMaxCapacity.put(date, maxCapacity); - mapOrderLoad.put(date, orderLoad); - mapOrderOverload.put(date, orderOverload.plus(maxCapacity)); - mapOtherLoad.put(date, otherLoad.plus(orderLoad)); - mapOtherOverload.put(date, otherOverload.plus(orderOverload) - .plus(maxCapacity)); + private ContiguousDaysLine> allAssignments( + ContiguousDaysLine> orderAssignments) { + if (orderAssignments.isNotValid()) { + return ContiguousDaysLine.> invalid(); } + return allAssignmentsOnResourcesAt(orderAssignments.getStart(), + orderAssignments.getEndExclusive()); } - private EffortDuration getSumCapacities( - SortedMap> orderDayAssignmentsGrouped, - LocalDate date) { - - final PartialDay day = PartialDay.wholeDay(date); - - return EffortDuration.sum(orderDayAssignmentsGrouped.get(date) - .keySet(), new IEffortFrom() { - - @Override - public EffortDuration from(Resource resource) { - return calendarCapacityFor(resource, day); - } - }); - } - - private EffortDuration retrieveTotalDurationForResource( - SortedMap> resourceDayAssignmentsGrouped, - LocalDate day, Resource resource) { - // FIXME review why is null sometimes - if (resourceDayAssignmentsGrouped.get(day) != null - && resourceDayAssignmentsGrouped.get(day).get(resource) != null) { - return resourceDayAssignmentsGrouped.get(day).get(resource); + private ContiguousDaysLine> allAssignmentsOnResourcesAt( + LocalDate startInclusive, LocalDate endExclusive) { + AvailabilityTimeLine.Interval interval = AvailabilityTimeLine.Interval + .create(startInclusive, endExclusive); + List resourcesDayAssignments = new ArrayList(); + for (Resource resource : order.getResources()) { + resourcesDayAssignments.addAll(insideInterval(interval, + planningState.getAssignmentsCalculator() + .getAssignments(resource))); } - return zero(); + return ContiguousDaysLine.byDay(resourcesDayAssignments); + } + + private List insideInterval( + AvailabilityTimeLine.Interval interval, + List assignments) { + List result = new ArrayList(); + for (DayAssignment each : assignments) { + if (interval.includes(each.getDay())) { + result.add(each); + } + } + return result; } }