Refactor code

Moved code for calculating resource load values related with an Order to
new class: OrderResourceLoadCalculator

FEA: ItEr76S15OrganizingPerProjectDashboard
This commit is contained in:
Diego Pino 2012-05-09 13:25:15 +02:00
parent 27baee6450
commit dc4da28f90
3 changed files with 295 additions and 97 deletions

View file

@ -0,0 +1,49 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2012 Igalia, S.L.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.libreplan.business.planner.entities;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.planner.chart.ContiguousDaysLine;
import org.libreplan.business.resources.entities.IAssignmentsOnResourceCalculator;
import org.libreplan.business.workingday.EffortDuration;
/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*
* Utility class for calculating 'Resource Load' values from an Order
*/
public interface IOrderResourceLoadCalculator {
void setOrder(Order order,
IAssignmentsOnResourceCalculator assignmentsOnResourceCalculator);
ContiguousDaysLine<EffortDuration> getMaxCapacityOnResources();
ContiguousDaysLine<EffortDuration> getOrderLoad();
ContiguousDaysLine<EffortDuration> getAllLoad();
ContiguousDaysLine<EffortDuration> getOrderOverload();
ContiguousDaysLine<EffortDuration> getAllOverload();
}

View file

@ -0,0 +1,218 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2012 Igalia, S.L.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.libreplan.business.planner.entities;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.joda.time.LocalDate;
import org.libreplan.business.calendars.entities.AvailabilityTimeLine;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.planner.chart.ContiguousDaysLine;
import org.libreplan.business.planner.chart.ContiguousDaysLine.OnDay;
import org.libreplan.business.planner.chart.ResourceLoadChartData;
import org.libreplan.business.planner.entities.DayAssignment.FilterType;
import org.libreplan.business.resources.entities.IAssignmentsOnResourceCalculator;
import org.libreplan.business.resources.entities.Resource;
import org.libreplan.business.workingday.EffortDuration;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
@Component
@Scope(BeanDefinition.SCOPE_SINGLETON)
public class OrderResourceLoadCalculator implements IOrderResourceLoadCalculator {
private Order order;
private IAssignmentsOnResourceCalculator assignmentsOnResourceCalculator;
private ContiguousDaysLine<List<DayAssignment>> orderAssignments;
private ContiguousDaysLine<List<DayAssignment>> filteredAssignments;
private ContiguousDaysLine<EffortDuration> maxCapacityOnResources;
private ContiguousDaysLine<EffortDuration> orderLoad;
private ContiguousDaysLine<EffortDuration> allLoad;
private ContiguousDaysLine<EffortDuration> orderOverload;
private ContiguousDaysLine<EffortDuration> allOverload;
@Override
public void setOrder(Order order,
IAssignmentsOnResourceCalculator assignmentsOnResourceCalculator) {
this.order = order;
this.assignmentsOnResourceCalculator = assignmentsOnResourceCalculator;
initializeValues();
}
private void initializeValues() {
orderAssignments = null;
filteredAssignments = null;
maxCapacityOnResources = null;
orderLoad = null;
allLoad = null;
orderOverload = null;
allOverload = null;
}
@Override
public ContiguousDaysLine<EffortDuration> getMaxCapacityOnResources() {
if (maxCapacityOnResources == null) {
maxCapacityOnResources = getOrderAssignments()
.transform(ResourceLoadChartData
.extractAvailabilityOnAssignedResources());
}
return maxCapacityOnResources;
}
private ContiguousDaysLine<List<DayAssignment>> getOrderAssignments() {
if (orderAssignments == null) {
List<DayAssignment> orderDayAssignments = order
.getDayAssignments(FilterType.WITHOUT_DERIVED);
orderAssignments = ContiguousDaysLine.byDay(orderDayAssignments);
}
return orderAssignments;
}
@Override
public ContiguousDaysLine<EffortDuration> getOrderLoad() {
if (orderLoad == null) {
orderLoad = getOrderAssignments()
.transform(ResourceLoadChartData.extractLoad());
}
return orderLoad;
}
@Override
public ContiguousDaysLine<EffortDuration> getAllLoad() {
if (allLoad == null) {
allLoad = getFilteredAssignments()
.transform(ResourceLoadChartData.extractLoad());
}
return allLoad;
}
private ContiguousDaysLine<List<DayAssignment>> getFilteredAssignments() {
if (filteredAssignments == null) {
ContiguousDaysLine<List<DayAssignment>> allAssignments = allAssignments(getOrderAssignments());
filteredAssignments = filterAllAssignmentsByOrderResources(
allAssignments, getOrderAssignments());
}
return filteredAssignments;
}
private ContiguousDaysLine<List<DayAssignment>> filterAllAssignmentsByOrderResources(
ContiguousDaysLine<List<DayAssignment>> allAssignments,
ContiguousDaysLine<List<DayAssignment>> orderAssignments) {
List<DayAssignment> filteredAssignments = new ArrayList<DayAssignment>();
Iterator<OnDay<List<DayAssignment>>> iterator = orderAssignments
.iterator();
while (iterator.hasNext()) {
OnDay<List<DayAssignment>> onDay = iterator.next();
Set<Resource> resources = getResources(onDay.getValue());
filteredAssignments.addAll(filterAssignmentsByResource(
allAssignments.get(onDay.getDay()), resources));
}
return ContiguousDaysLine.byDay(filteredAssignments);
}
private List<DayAssignment> filterAssignmentsByResource(
List<DayAssignment> list, Set<Resource> resources) {
List<DayAssignment> result = new ArrayList<DayAssignment>();
for (DayAssignment each : list) {
if (resources.contains(each.getResource())) {
result.add(each);
}
}
return result;
}
private Set<Resource> getResources(List<DayAssignment> dayAssignments) {
Set<Resource> resources = new HashSet<Resource>();
for (DayAssignment each : dayAssignments) {
resources.add(each.getResource());
}
return resources;
}
private ContiguousDaysLine<List<DayAssignment>> allAssignments(
ContiguousDaysLine<List<DayAssignment>> orderAssignments) {
if (orderAssignments.isNotValid()) {
return ContiguousDaysLine.<List<DayAssignment>> invalid();
}
return allAssignmentsOnResourcesAt(orderAssignments.getStart(),
orderAssignments.getEndExclusive());
}
private ContiguousDaysLine<List<DayAssignment>> allAssignmentsOnResourcesAt(
LocalDate startInclusive, LocalDate endExclusive) {
AvailabilityTimeLine.Interval interval = AvailabilityTimeLine.Interval
.create(startInclusive, endExclusive);
List<DayAssignment> resourcesDayAssignments = new ArrayList<DayAssignment>();
for (Resource resource : order.getResources(FilterType.WITHOUT_DERIVED)) {
resourcesDayAssignments.addAll(insideInterval(interval,
assignmentsOnResourceCalculator.getAssignments(resource)));
}
return ContiguousDaysLine.byDay(resourcesDayAssignments);
}
private List<DayAssignment> insideInterval(
AvailabilityTimeLine.Interval interval,
List<DayAssignment> assignments) {
List<DayAssignment> result = new ArrayList<DayAssignment>();
for (DayAssignment each : assignments) {
if (interval.includes(each.getDay())) {
result.add(each);
}
}
return result;
}
@Override
public ContiguousDaysLine<EffortDuration> getOrderOverload() {
if (orderOverload == null) {
orderOverload = getOrderAssignments()
.transform(ResourceLoadChartData.extractOverload());
}
return orderOverload;
}
@Override
public ContiguousDaysLine<EffortDuration> getAllOverload() {
if (allOverload == null) {
allOverload = getFilteredAssignments()
.transform(ResourceLoadChartData.extractOverload());
}
return allOverload;
}
}

View file

@ -34,7 +34,6 @@ import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -44,7 +43,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.libreplan.business.calendars.entities.AvailabilityTimeLine;
import org.libreplan.business.common.AdHocTransactionService;
import org.libreplan.business.common.IAdHocTransactionService;
import org.libreplan.business.common.IOnTransaction;
@ -56,12 +54,9 @@ import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderStatusEnum;
import org.libreplan.business.planner.chart.ContiguousDaysLine;
import org.libreplan.business.planner.chart.ContiguousDaysLine.OnDay;
import org.libreplan.business.planner.chart.ResourceLoadChartData;
import org.libreplan.business.planner.entities.DayAssignment;
import org.libreplan.business.planner.entities.DayAssignment.FilterType;
import org.libreplan.business.planner.entities.ICostCalculator;
import org.libreplan.business.planner.entities.IOrderEarnedValueCalculator;
import org.libreplan.business.planner.entities.IOrderResourceLoadCalculator;
import org.libreplan.business.planner.entities.TaskElement;
import org.libreplan.business.planner.entities.TaskGroup;
import org.libreplan.business.resources.entities.CriterionSatisfaction;
@ -262,6 +257,9 @@ public class OrderPlanningModel implements IOrderPlanningModel {
@Autowired
private IOrderEarnedValueCalculator earnedValueCalculator;
@Autowired
private IOrderResourceLoadCalculator resourceLoadCalculator;
private List<Checkbox> earnedValueChartConfigurationCheckboxes = new ArrayList<Checkbox>();
private List<IChartVisibilityChangedListener> keepAliveChartVisibilityListeners = new ArrayList<IChartVisibilityChangedListener>();
@ -1193,10 +1191,20 @@ public class OrderPlanningModel implements IOrderPlanningModel {
});
}
public static final String COLOR_ASSIGNED_LOAD_GLOBAL = "#E0F3D3"; // Soft
// green
public static final String COLOR_OVERLOAD_GLOBAL = "#FFD4C2"; // Soft red
// Soft green
public static final String COLOR_ASSIGNED_LOAD_GLOBAL = "#E0F3D3";
// Soft red
public static final String COLOR_OVERLOAD_GLOBAL = "#FFD4C2";
/**
*
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*
* Calculates 'Resource Load' values and set them in the Order
* 'Resource Load' chart
*/
private class OrderLoadChartFiller extends LoadChartFiller {
private final Order order;
@ -1212,25 +1220,18 @@ public class OrderPlanningModel implements IOrderPlanningModel {
@Override
protected Plotinfo[] getPlotInfos(Interval interval) {
List<DayAssignment> orderDayAssignments = order
.getDayAssignments(FilterType.WITHOUT_DERIVED);
ContiguousDaysLine<List<DayAssignment>> orderAssignments = ContiguousDaysLine
.byDay(orderDayAssignments);
ContiguousDaysLine<List<DayAssignment>> allAssignments = allAssignments(orderAssignments);
ContiguousDaysLine<List<DayAssignment>> filteredAssignments = filterAllAssignmentsByOrderResources(
allAssignments, orderAssignments);
resourceLoadCalculator.setOrder(order, planningState.getAssignmentsCalculator());
ContiguousDaysLine<EffortDuration> maxCapacityOnResources = orderAssignments
.transform(ResourceLoadChartData
.extractAvailabilityOnAssignedResources());
ContiguousDaysLine<EffortDuration> orderLoad = orderAssignments
.transform(ResourceLoadChartData.extractLoad());
ContiguousDaysLine<EffortDuration> allLoad = filteredAssignments
.transform(ResourceLoadChartData.extractLoad());
ContiguousDaysLine<EffortDuration> orderOverload = orderAssignments
.transform(ResourceLoadChartData.extractOverload());
ContiguousDaysLine<EffortDuration> allOverload = filteredAssignments
.transform(ResourceLoadChartData.extractOverload());
ContiguousDaysLine<EffortDuration> maxCapacityOnResources = resourceLoadCalculator
.getMaxCapacityOnResources();
ContiguousDaysLine<EffortDuration> orderLoad = resourceLoadCalculator
.getOrderLoad();
ContiguousDaysLine<EffortDuration> allLoad = resourceLoadCalculator
.getAllLoad();
ContiguousDaysLine<EffortDuration> orderOverload = resourceLoadCalculator
.getOrderOverload();
ContiguousDaysLine<EffortDuration> allOverload = resourceLoadCalculator
.getAllOverload();
Plotinfo plotOrderLoad = createPlotinfoFromDurations(
groupAsNeededByZoom(toSortedMap(ContiguousDaysLine.min(
@ -1272,76 +1273,6 @@ public class OrderPlanningModel implements IOrderPlanningModel {
plotMaxCapacity, plotOtherLoad, plotOrderLoad };
}
private ContiguousDaysLine<List<DayAssignment>> filterAllAssignmentsByOrderResources(
ContiguousDaysLine<List<DayAssignment>> allAssignments,
ContiguousDaysLine<List<DayAssignment>> orderAssignments) {
List<DayAssignment> filteredAssignments = new ArrayList<DayAssignment>();
Iterator<OnDay<List<DayAssignment>>> iterator = orderAssignments
.iterator();
while (iterator.hasNext()) {
OnDay<List<DayAssignment>> onDay = iterator.next();
Set<Resource> resources = getResources(onDay.getValue());
filteredAssignments.addAll(filterAssignmentsByResource(
allAssignments.get(onDay.getDay()), resources));
}
return ContiguousDaysLine.byDay(filteredAssignments);
}
private List<DayAssignment> filterAssignmentsByResource(
List<DayAssignment> list, Set<Resource> resources) {
List<DayAssignment> result = new ArrayList<DayAssignment>();
for (DayAssignment each : list) {
if (resources.contains(each.getResource())) {
result.add(each);
}
}
return result;
}
private Set<Resource> getResources(List<DayAssignment> dayAssignments) {
Set<Resource> resources = new HashSet<Resource>();
for (DayAssignment each : dayAssignments) {
resources.add(each.getResource());
}
return resources;
}
private ContiguousDaysLine<List<DayAssignment>> allAssignments(
ContiguousDaysLine<List<DayAssignment>> orderAssignments) {
if (orderAssignments.isNotValid()) {
return ContiguousDaysLine.<List<DayAssignment>> invalid();
}
return allAssignmentsOnResourcesAt(orderAssignments.getStart(),
orderAssignments.getEndExclusive());
}
private ContiguousDaysLine<List<DayAssignment>> allAssignmentsOnResourcesAt(
LocalDate startInclusive, LocalDate endExclusive) {
AvailabilityTimeLine.Interval interval = AvailabilityTimeLine.Interval
.create(startInclusive, endExclusive);
List<DayAssignment> resourcesDayAssignments = new ArrayList<DayAssignment>();
for (Resource resource : order
.getResources(FilterType.WITHOUT_DERIVED)) {
resourcesDayAssignments.addAll(insideInterval(interval,
planningState.getAssignmentsCalculator()
.getAssignments(resource)));
}
return ContiguousDaysLine.byDay(resourcesDayAssignments);
}
private List<DayAssignment> insideInterval(
AvailabilityTimeLine.Interval interval,
List<DayAssignment> assignments) {
List<DayAssignment> result = new ArrayList<DayAssignment>();
for (DayAssignment each : assignments) {
if (interval.includes(each.getDay())) {
result.add(each);
}
}
return result;
}
}
/**