diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/CompanyEarnedValueCalculator.java b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/CompanyEarnedValueCalculator.java
new file mode 100644
index 000000000..40fdef895
--- /dev/null
+++ b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/CompanyEarnedValueCalculator.java
@@ -0,0 +1,159 @@
+/*
+ * 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 .
+ */
+
+package org.libreplan.business.planner.entities;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.joda.time.LocalDate;
+import org.libreplan.business.calendars.entities.AvailabilityTimeLine;
+import org.libreplan.business.calendars.entities.AvailabilityTimeLine.Interval;
+import org.libreplan.business.hibernate.notification.PredefinedDatabaseSnapshots;
+import org.libreplan.business.workreports.entities.WorkReportLine;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * @author Diego Pino García
+ */
+@Component
+@Scope(BeanDefinition.SCOPE_SINGLETON)
+public class CompanyEarnedValueCalculator implements ICompanyEarnedValueCalculator {
+
+ @Autowired
+ private PredefinedDatabaseSnapshots databaseSnapshots;
+
+ @Override
+ @Transactional(readOnly = true)
+ public SortedMap calculateBudgetedCostWorkScheduled(AvailabilityTimeLine.Interval interval) {
+ Map> estimatedCostPerTask = databaseSnapshots
+ .snapshotEstimatedCostPerTask();
+ Collection list = filterTasksByDate(
+ estimatedCostPerTask.keySet(), interval);
+ SortedMap estimatedCost = new TreeMap();
+
+ for (TaskElement each : list) {
+ addCost(estimatedCost, estimatedCostPerTask.get(each));
+ }
+ return accumulateResult(estimatedCost);
+ }
+
+ private List filterTasksByDate(
+ Collection tasks,
+ AvailabilityTimeLine.Interval interval) {
+ List result = new ArrayList();
+ for(TaskElement task : tasks) {
+ if (interval.includes(task.getStartAsLocalDate())
+ || interval.includes(task.getEndAsLocalDate())) {
+ result.add(task);
+ }
+ }
+ return result;
+ }
+
+ private List filterWorkReportLinesByDate(
+ Collection lines,
+ AvailabilityTimeLine.Interval interval) {
+ List result = new ArrayList();
+ for(WorkReportLine line: lines) {
+ if (interval.includes(line.getLocalDate())) {
+ result.add(line);
+ }
+ }
+ return result;
+ }
+
+ private void addCost(SortedMap currentCost,
+ SortedMap additionalCost) {
+ for (LocalDate day : additionalCost.keySet()) {
+ if (!currentCost.containsKey(day)) {
+ currentCost.put(day, BigDecimal.ZERO);
+ }
+ currentCost.put(day, currentCost.get(day).add(
+ additionalCost.get(day)));
+ }
+ }
+
+ private SortedMap accumulateResult(
+ SortedMap map) {
+ SortedMap result = new TreeMap();
+ if (map.isEmpty()) {
+ return result;
+ }
+
+ BigDecimal accumulatedResult = BigDecimal.ZERO;
+ for (LocalDate day : map.keySet()) {
+ BigDecimal value = map.get(day);
+ accumulatedResult = accumulatedResult.add(value);
+ result.put(day, accumulatedResult);
+ }
+
+ return result;
+ }
+
+ @Override
+ public SortedMap calculateActualCostWorkPerformed(
+ Interval interval) {
+ SortedMap result = new TreeMap();
+ Collection workReportLines = filterWorkReportLinesByDate(
+ databaseSnapshots.snapshotWorkReportLines(),
+ interval);
+
+ if (workReportLines.isEmpty()) {
+ return result;
+ }
+
+ for (WorkReportLine workReportLine : workReportLines) {
+ LocalDate day = new LocalDate(workReportLine.getDate());
+ BigDecimal cost = workReportLine.getEffort()
+ .toHoursAsDecimalWithScale(2);
+
+ if (!result.containsKey(day)) {
+ result.put(day, BigDecimal.ZERO);
+ }
+ result.put(day, result.get(day).add(cost));
+ }
+ return accumulateResult(result);
+ }
+
+ @Override
+ public SortedMap calculateBudgetedCostWorkPerformed(
+ Interval interval) {
+ Map> advanceCostPerTask = databaseSnapshots
+ .snapshotAdvanceCostPerTask();
+ Collection tasks = filterTasksByDate(
+ advanceCostPerTask.keySet(), interval);
+
+ SortedMap result = new TreeMap();
+ for (TaskElement each : tasks) {
+ addCost(result, advanceCostPerTask.get(each));
+ }
+ return result;
+ }
+
+}
diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/ICompanyEarnedValueCalculator.java b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/ICompanyEarnedValueCalculator.java
new file mode 100644
index 000000000..9c13eee49
--- /dev/null
+++ b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/ICompanyEarnedValueCalculator.java
@@ -0,0 +1,44 @@
+/*
+ * 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 .
+ */
+
+package org.libreplan.business.planner.entities;
+
+import java.math.BigDecimal;
+import java.util.SortedMap;
+
+import org.joda.time.LocalDate;
+import org.libreplan.business.calendars.entities.AvailabilityTimeLine;
+
+/**
+ * @author Diego Pino García
+ *
+ * Utility class for calculating all 'Earned Value' measurements
+ */
+public interface ICompanyEarnedValueCalculator {
+
+ SortedMap calculateBudgetedCostWorkScheduled(
+ AvailabilityTimeLine.Interval interval);
+
+ SortedMap calculateActualCostWorkPerformed(
+ AvailabilityTimeLine.Interval interval);
+
+ SortedMap calculateBudgetedCostWorkPerformed(
+ AvailabilityTimeLine.Interval interval);
+
+}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/chart/ChartFiller.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/chart/ChartFiller.java
index eaac867bf..bd25935b7 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/chart/ChartFiller.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/chart/ChartFiller.java
@@ -508,6 +508,12 @@ public abstract class ChartFiller implements IChartFiller {
return result;
}
+ protected SortedMap calculatedValueForEveryDay(
+ SortedMap values, Interval interval) {
+ return calculatedValueForEveryDay(values, interval.getStart(),
+ interval.getFinish());
+ }
+
protected SortedMap calculatedValueForEveryDay(
SortedMap map, Date start, Date finish) {
return calculatedValueForEveryDay(map, new LocalDate(start),
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/chart/EarnedValueChartFiller.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/chart/EarnedValueChartFiller.java
index b4dffbd2d..13e7073c7 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/chart/EarnedValueChartFiller.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/chart/EarnedValueChartFiller.java
@@ -418,4 +418,10 @@ public abstract class EarnedValueChartFiller extends ChartFiller {
}
}
+ public void setIndicatorInInterval(EarnedValueType type,
+ Interval interval, SortedMap values) {
+ addZeroBeforeTheFirstValue(values);
+ indicators.put(type, calculatedValueForEveryDay(values, interval));
+ }
+
}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/company/CompanyPlanningModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/company/CompanyPlanningModel.java
index eebdf859b..e6bfe65bf 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/company/CompanyPlanningModel.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/company/CompanyPlanningModel.java
@@ -38,8 +38,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
import org.joda.time.LocalDate;
import org.libreplan.business.calendars.entities.AvailabilityTimeLine;
@@ -55,6 +53,7 @@ import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderStatusEnum;
import org.libreplan.business.planner.chart.ILoadChartData;
import org.libreplan.business.planner.chart.ResourceLoadChartData;
+import org.libreplan.business.planner.entities.ICompanyEarnedValueCalculator;
import org.libreplan.business.planner.entities.TaskElement;
import org.libreplan.business.planner.entities.TaskGroup;
import org.libreplan.business.planner.entities.TaskMilestone;
@@ -62,7 +61,6 @@ import org.libreplan.business.scenarios.IScenarioManager;
import org.libreplan.business.scenarios.entities.Scenario;
import org.libreplan.business.users.daos.IUserDAO;
import org.libreplan.business.users.entities.User;
-import org.libreplan.business.workreports.entities.WorkReportLine;
import org.libreplan.web.planner.TaskElementAdapter;
import org.libreplan.web.planner.TaskGroupPredicate;
import org.libreplan.web.planner.chart.Chart;
@@ -132,6 +130,9 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
@Autowired
private IAdHocTransactionService transactionService;
+ @Autowired
+ private ICompanyEarnedValueCalculator earnedValueCalculator;
+
private List keepAliveZoomListeners = new ArrayList();
private List earnedValueChartConfigurationCheckboxes = new ArrayList();
@@ -275,6 +276,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
setupChart(chartLoadTimeplot, new CompanyLoadChartFiller(), planner);
chartComponent.getTabs().getLastChild().addEventListener(Events.ON_SELECT, new EventListener() {
+ @Override
public void onEvent(Event event) throws Exception {
createOnDemandEarnedValueTimePlot(chartComponent, planner);
event.getTarget().removeEventListener(Events.ON_SELECT, this);
@@ -783,75 +785,33 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
}
+ /**
+ *
+ * @author Manuel Rego Casasnovas
+ * @author Diego Pino García
+ *
+ */
private class CompanyEarnedValueChartFiller extends EarnedValueChartFiller {
+ @Override
protected void calculateBudgetedCostWorkScheduled(Interval interval) {
- Map> estimatedCostPerTask =
- databaseSnapshots.snapshotEstimatedCostPerTask();
- Collection list = filterTasksByDate(
- estimatedCostPerTask.keySet(), getFilterInterval());
-
- SortedMap estimatedCost = new TreeMap();
-
- for (TaskElement taskElement : list) {
- addCost(estimatedCost, estimatedCostPerTask.get(taskElement));
- }
-
- estimatedCost = accumulateResult(estimatedCost);
- addZeroBeforeTheFirstValue(estimatedCost);
- indicators.put(EarnedValueType.BCWS, calculatedValueForEveryDay(
- estimatedCost, interval.getStart(), interval.getFinish()));
+ setIndicatorInInterval(EarnedValueType.BCWS, interval,
+ earnedValueCalculator
+ .calculateBudgetedCostWorkScheduled(getFilterInterval()));
}
+ @Override
protected void calculateActualCostWorkPerformed(Interval interval) {
- SortedMap workReportCost = getWorkReportCost();
-
- workReportCost = accumulateResult(workReportCost);
- addZeroBeforeTheFirstValue(workReportCost);
- indicators.put(EarnedValueType.ACWP, calculatedValueForEveryDay(
- workReportCost, interval.getStart(), interval.getFinish()));
- }
-
- private SortedMap getWorkReportCost() {
- SortedMap result = new TreeMap();
-
- Collection workReportLines = filterWorkReportLinesByDate(
- databaseSnapshots.snapshotWorkReportLines(),
- getFilterInterval());
-
- if (workReportLines.isEmpty()) {
- return result;
- }
-
- for (WorkReportLine workReportLine : workReportLines) {
- LocalDate day = new LocalDate(workReportLine.getDate());
- BigDecimal cost = workReportLine.getEffort()
- .toHoursAsDecimalWithScale(2);
-
- if (!result.containsKey(day)) {
- result.put(day, BigDecimal.ZERO);
- }
- result.put(day, result.get(day).add(cost));
- }
-
- return result;
+ setIndicatorInInterval(EarnedValueType.ACWP, interval,
+ earnedValueCalculator
+ .calculateActualCostWorkPerformed(getFilterInterval()));
}
+ @Override
protected void calculateBudgetedCostWorkPerformed(Interval interval) {
- Map> advanceCostPerTask =
- databaseSnapshots.snapshotAdvanceCostPerTask();
- Collection list = filterTasksByDate(
- advanceCostPerTask.keySet(), getFilterInterval());
-
- SortedMap advanceCost = new TreeMap();
-
- for (TaskElement taskElement : list) {
- addCost(advanceCost, advanceCostPerTask.get(taskElement));
- }
-
- addZeroBeforeTheFirstValue(advanceCost);
- indicators.put(EarnedValueType.BCWP, calculatedValueForEveryDay(
- advanceCost, interval.getStart(), interval.getFinish()));
+ setIndicatorInInterval(EarnedValueType.BCWP, interval,
+ earnedValueCalculator
+ .calculateBudgetedCostWorkPerformed(getFilterInterval()));
}
@Override
@@ -859,33 +819,9 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
return getEarnedValueSelectedIndicators();
}
- private List filterTasksByDate(
- Collection tasks,
- AvailabilityTimeLine.Interval interval) {
- List result = new ArrayList();
- for(TaskElement task : tasks) {
- if (interval.includes(task.getStartAsLocalDate())
- || interval.includes(task.getEndAsLocalDate())) {
- result.add(task);
- }
- }
- return result;
- }
-
-
- private List filterWorkReportLinesByDate(
- Collection lines,
- AvailabilityTimeLine.Interval interval) {
- List result = new ArrayList();
- for(WorkReportLine line: lines) {
- if (interval.includes(line.getLocalDate())) {
- result.add(line);
- }
- }
- return result;
- }
}
+ @Override
@Transactional(readOnly=true)
public ProgressType getProgressTypeFromConfiguration() {
return configurationDAO.getConfiguration().getProgressType();
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/order/OrderPlanningModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/order/OrderPlanningModel.java
index f21c4019f..e6ff9c8a0 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/order/OrderPlanningModel.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/order/OrderPlanningModel.java
@@ -38,7 +38,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.SortedMap;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
@@ -1389,6 +1388,12 @@ public class OrderPlanningModel implements IOrderPlanningModel {
}
+ /**
+ *
+ * @author Manuel Rego Casasnovas
+ * @author Diego Pino García
+ *
+ */
class OrderEarnedValueChartFiller extends EarnedValueChartFiller {
private Order order;
@@ -1418,18 +1423,6 @@ public class OrderPlanningModel implements IOrderPlanningModel {
.calculateBudgetedCostWorkPerformed(order));
}
- private void setIndicatorInInterval(EarnedValueType type,
- Interval interval, SortedMap values) {
- addZeroBeforeTheFirstValue(values);
- indicators.put(type, calculatedValueForEveryDay(values, interval));
- }
-
- private SortedMap calculatedValueForEveryDay(
- SortedMap values, Interval interval) {
- return calculatedValueForEveryDay(values, interval.getStart(),
- interval.getFinish());
- }
-
@Override
protected Set getSelectedIndicators() {
return getEarnedValueSelectedIndicators();