ItEr45S12RFGravacionDatosHistoricosResponsabilidadesTraballoUnidadesPlanItEr44S18: Fix the historical statistics of the templates.

This commit is contained in:
Susana Montes Pedreira 2010-01-28 19:57:41 +01:00 committed by Javier Moran Rua
parent ac7d798332
commit 460a8cf5ad
9 changed files with 327 additions and 146 deletions

View file

@ -101,4 +101,16 @@ public interface IOrderElementDAO extends IGenericDAO<OrderElement, Long> {
List<OrderElement> findByTemplate(OrderElementTemplate template);
BigDecimal calculateAverageEstimatedHours(final List<OrderElement> list);
BigDecimal calculateAverageWorkedHours(final List<OrderElement> list);
BigDecimal calculateMaxEstimatedHours(final List<OrderElement> list);
BigDecimal calculateMinEstimatedHours(final List<OrderElement> list);
BigDecimal calculateMaxWorkedHours(final List<OrderElement> list);
BigDecimal calculateMinWorkedHours(final List<OrderElement> list);
}

View file

@ -252,4 +252,114 @@ public class OrderElementDAO extends GenericDAOHibernate<OrderElement, Long>
return c.list();
}
/**
* Methods to calculate estatistics with the estimated hours and worked
* hours of a set of order elements.
* @param List
* <{@link OrderElement}>
*/
public BigDecimal calculateAverageEstimatedHours(
final List<OrderElement> list) {
BigDecimal sum = sumEstimatedHours(list);
return average(new BigDecimal(list.size()), sum);
}
public BigDecimal calculateAverageWorkedHours(final List<OrderElement> list) {
BigDecimal sum = sumWorkedHours(list);
return average(new BigDecimal(list.size()), sum);
}
private BigDecimal average(BigDecimal divisor, BigDecimal sum) {
BigDecimal average = new BigDecimal(0);
if (sum.compareTo(new BigDecimal(0)) > 0) {
average = sum.divide(divisor);
}
return average;
}
private BigDecimal sumEstimatedHours(final List<OrderElement> list) {
BigDecimal sum = new BigDecimal(0);
for (OrderElement orderElement : list) {
sum = sum.add(new BigDecimal(orderElement.getWorkHours()));
}
return sum;
}
private BigDecimal sumWorkedHours(final List<OrderElement> list) {
BigDecimal sum = new BigDecimal(0);
for (OrderElement orderElement : list) {
sum = sum.add(new BigDecimal(getAssignedDirectHours(orderElement)));
}
return sum;
}
public BigDecimal calculateMaxEstimatedHours(final List<OrderElement> list) {
BigDecimal max = new BigDecimal(0);
if (!list.isEmpty()) {
max = new BigDecimal(list.get(0).getWorkHours());
for (OrderElement orderElement : list) {
BigDecimal value = new BigDecimal(orderElement.getWorkHours());
max = getMax(max, value);
}
}
return max;
}
private BigDecimal getMax(BigDecimal valueA, BigDecimal valueB) {
if (valueA.compareTo(valueB) < 0) {
return valueB;
} else if (valueA.compareTo(valueB) > 0) {
return valueA;
}
return valueA;
}
private BigDecimal getMin(BigDecimal valueA, BigDecimal valueB) {
if (valueA.compareTo(valueB) > 0) {
return valueB;
} else if (valueA.compareTo(valueB) < 0) {
return valueA;
}
return valueA;
}
public BigDecimal calculateMinEstimatedHours(final List<OrderElement> list) {
BigDecimal min = new BigDecimal(0);
if (!list.isEmpty()) {
min = new BigDecimal(list.get(0).getWorkHours());
for (OrderElement orderElement : list) {
BigDecimal value = new BigDecimal(orderElement.getWorkHours());
min = getMin(min, value);
}
}
return min;
}
public BigDecimal calculateMaxWorkedHours(final List<OrderElement> list) {
BigDecimal max = new BigDecimal(0);
if (!list.isEmpty()) {
max = new BigDecimal(getAssignedDirectHours(list.get(0)));
for (OrderElement orderElement : list) {
BigDecimal value = new BigDecimal(
getAssignedDirectHours(orderElement));
max = getMax(max, value);
}
}
return max;
}
public BigDecimal calculateMinWorkedHours(final List<OrderElement> list) {
BigDecimal min = new BigDecimal(0);
if (!list.isEmpty()) {
min = new BigDecimal(getAssignedDirectHours(list.get(0)));
for (OrderElement orderElement : list) {
BigDecimal value = new BigDecimal(
getAssignedDirectHours(orderElement));
min = getMin(min, value);
}
}
return min;
}
}

View file

@ -979,4 +979,59 @@ public abstract class OrderElement extends BaseEntity implements
return result;
}
/**
* Calculate if the tasks of the planification point has finished
*/
public boolean isFinishPlanificationPointTask() {
// look up into the order elements tree
TaskElement task = lookToUpAssignedTask();
if (task != null) {
return task.getOrderElement().isFinishedAdvance();
}
// look down into the order elements tree
List<TaskElement> listTask = lookToDownAssignedTask();
if (!listTask.isEmpty()) {
for (TaskElement taskElement : listTask) {
if (!taskElement.getOrderElement().isFinishedAdvance()) {
return false;
}
}
}
// not exist assigned task
IOrderElementDAO orderElementDAO = Registry.getOrderElementDAO();
return (orderElementDAO.loadOrderAvoidingProxyFor(this))
.isFinishedAdvance();
}
private TaskElement lookToUpAssignedTask() {
OrderElement current = this;
while (current != null) {
if (isSchedulingPoint()) {
return getAssociatedTaskElement();
}
current = current.getParent();
}
return null;
}
private List<TaskElement> lookToDownAssignedTask() {
List<TaskElement> resultTask = new ArrayList<TaskElement>();
for (OrderElement child : getAllChildren()) {
if (child.isSchedulingPoint()) {
TaskElement task = child.getAssociatedTaskElement();
if (task != null) {
resultTask.add(task);
}
}
}
return resultTask;
}
public boolean isFinishedAdvance() {
BigDecimal measuredProgress = getAdvancePercentage();
measuredProgress = (measuredProgress.setScale(0, BigDecimal.ROUND_UP)
.multiply(new BigDecimal(100)));
return (measuredProgress.compareTo(new BigDecimal(100)) == 0);
}
}

View file

@ -54,4 +54,5 @@ public interface IOrderTemplatesModel {
Set<QualityForm> getAllQualityForms();
OrderElementsOnConversation getOrderElementsOnConversation();
}

View file

@ -0,0 +1,74 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* 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.navalplanner.web.templates;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.navalplanner.business.orders.daos.IOrderElementDAO;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
/**
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*
*/
public class OrderElementsOnConversation {
private final IOrderElementDAO orderElementDAO;
private List<OrderElement> orderElements = new ArrayList<OrderElement>();
public OrderElementsOnConversation(IOrderElementDAO orderElementDAO) {
this.orderElementDAO = orderElementDAO;
}
public List<OrderElement> getOrderElements() {
return orderElements;
}
public void initialize(OrderElementTemplate template) {
if ((template != null) && (!template.isNewObject())) {
orderElements = new ArrayList<OrderElement>(orderElementDAO
.findByTemplate(template));
initialize(orderElements);
}
}
private void initialize(Collection<OrderElement> orderElements) {
for (OrderElement each : orderElements) {
initialize(each);
}
}
private void initialize(OrderElement orderElement) {
orderElement.getName();
(orderElementDAO.loadOrderAvoidingProxyFor(orderElement)).getName();
}
public void reattach() {
for (OrderElement each : orderElements) {
orderElementDAO.reattach(each);
(orderElementDAO.loadOrderAvoidingProxyFor(each)).getName();
}
}
}

View file

@ -28,6 +28,7 @@ import org.navalplanner.business.common.IAdHocTransactionService;
import org.navalplanner.business.common.IOnTransaction;
import org.navalplanner.business.labels.daos.ILabelDAO;
import org.navalplanner.business.labels.entities.Label;
import org.navalplanner.business.orders.daos.IOrderDAO;
import org.navalplanner.business.orders.daos.IOrderElementDAO;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.qualityforms.daos.IQualityFormDAO;
@ -53,6 +54,9 @@ public class OrderTemplatesModel implements IOrderTemplatesModel {
@Autowired
private IOrderElementDAO orderElementDAO;
@Autowired
private IOrderDAO orderDAO;
@Autowired
private IOrderElementTemplateDAO dao;
@ -88,6 +92,16 @@ public class OrderTemplatesModel implements IOrderTemplatesModel {
return qualityFormsOnConversation;
}
private OrderElementsOnConversation orderElementsOnConversation;
public OrderElementsOnConversation getOrderElementsOnConversation() {
if (orderElementsOnConversation == null) {
orderElementsOnConversation = new OrderElementsOnConversation(
orderElementDAO);
}
return orderElementsOnConversation;
}
@Override
public List<OrderElementTemplate> getRootTemplates() {
return dao.getRootTemplates();
@ -144,6 +158,7 @@ public class OrderTemplatesModel implements IOrderTemplatesModel {
private void loadAssociatedData(OrderElementTemplate template) {
loadAdvanceAssignments(template);
loadQualityForms(template);
getOrderElementsOnConversation().initialize(template);
}
private void loadQualityForms(OrderElementTemplate template) {

View file

@ -29,7 +29,6 @@ import javax.servlet.http.HttpServletRequest;
import org.navalplanner.business.common.IAdHocTransactionService;
import org.navalplanner.business.common.IOnTransaction;
import org.navalplanner.business.orders.daos.IOrderDAO;
import org.navalplanner.business.orders.daos.IOrderElementDAO;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.orders.entities.OrderElement;
@ -53,12 +52,12 @@ public class OrderElementHistoricalAssignmentComponent extends HtmlMacroComponen
private IOrderTemplatesModel model;
private List<OrderElement> orderElements;
private IAdHocTransactionService adHocTransactionService;
private IOrderElementDAO orderElementDAO;
private IOrderDAO orderDAO;
private IGlobalViewEntryPoints globalView;
@Transactional(readOnly = true)
@ -66,13 +65,14 @@ public class OrderElementHistoricalAssignmentComponent extends HtmlMacroComponen
super.afterCompose();
this.adHocTransactionService = (IAdHocTransactionService) getBean("adHocTransactionService");
this.orderElementDAO = (IOrderElementDAO) getBean("orderElementDAO");
this.orderDAO = (IOrderDAO) getBean("orderDAO");
}
public void useModel(IOrderTemplatesModel model,
IGlobalViewEntryPoints globalView) {
template = model.getTemplate();
this.model = model;
this.orderElements = model.getOrderElementsOnConversation()
.getOrderElements();
this.globalView = globalView;
}
@ -83,8 +83,7 @@ public class OrderElementHistoricalAssignmentComponent extends HtmlMacroComponen
return this.adHocTransactionService.runOnReadOnlyTransaction(new IOnTransaction<List<OrderElementHistoricAssignmentDTO>>() {
@Override
public List<OrderElementHistoricAssignmentDTO> execute() {
final List<OrderElement> orderElements = new ArrayList<OrderElement>(
orderElementDAO.findByTemplate(template));
model.getOrderElementsOnConversation().reattach();
return createOrderElementHistoricAssignmentDTOs(orderElements);
}
});

View file

@ -31,7 +31,6 @@ import org.navalplanner.business.common.IAdHocTransactionService;
import org.navalplanner.business.common.IOnTransaction;
import org.navalplanner.business.orders.daos.IOrderElementDAO;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.planner.entities.TaskElement;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
import org.navalplanner.web.templates.IOrderTemplatesModel;
import org.springframework.transaction.annotation.Transactional;
@ -57,12 +56,16 @@ public class OrderElementHistoricalStatisticsComponent extends
private List<OrderElement> orderElements = new ArrayList<OrderElement>();
private List<OrderElement> finishedOrderElements = new ArrayList<OrderElement>();
public String applications = "0";
public String finishApplications = "0";
public String averageEstimatedHours = "0";
public String averageWorkedHours = "0";
public String differentialEstimatedHours = "0";
public String differentialWorkedHours = "0";
public String maxEstimatedHours = "0";
public String maxWorkedHours = "0";
public String minEstimatedHours = "0";
public String minWorkedHours = "0";
@Transactional(readOnly = true)
public void afterCompose() {
@ -73,6 +76,8 @@ public class OrderElementHistoricalStatisticsComponent extends
public void useModel(IOrderTemplatesModel model) {
template = model.getTemplate();
orderElements = model.getOrderElementsOnConversation()
.getOrderElements();
this.model = model;
calculateTemplateHistoricalStatistics();
}
@ -84,7 +89,9 @@ public class OrderElementHistoricalStatisticsComponent extends
.runOnReadOnlyTransaction(new IOnTransaction<Void>() {
@Override
public Void execute() {
orderElements = getOrderElementsWithThisAssignedTemplate();
model.getOrderElementsOnConversation().reattach();
finishedOrderElements = getFinishedApplications();
applications = getApplicationsNumber().toString();
finishApplications = getFinishedApplicationsNumber()
.toString();
@ -92,9 +99,13 @@ public class OrderElementHistoricalStatisticsComponent extends
.toString();
averageWorkedHours = calculateAverageWorkedHours()
.toString();
differentialEstimatedHours = calculateEstimatedDifferential()
maxEstimatedHours = calculateMaxEstimatedHours()
.toString();
differentialWorkedHours = calculateWorkedDifferential()
maxWorkedHours = calculateMaxWorkedHours()
.toString();
minEstimatedHours = calculateMinEstimatedHours()
.toString();
minWorkedHours = calculateMinWorkedHours()
.toString();
return null;
}
@ -102,14 +113,6 @@ public class OrderElementHistoricalStatisticsComponent extends
}
}
public List<OrderElement> getOrderElementsWithThisAssignedTemplate() {
orderElements.clear();
if ((model != null) && (template != null) && (!template.isNewObject())) {
orderElements.addAll(orderElementDAO.findByTemplate(template));
}
return orderElements;
}
public String getApplications() {
return applications;
}
@ -126,12 +129,20 @@ public class OrderElementHistoricalStatisticsComponent extends
return averageWorkedHours;
}
public String getDifferentialEstimatedHours() {
return differentialEstimatedHours;
public String getMaxEstimatedHours() {
return maxEstimatedHours;
}
public String getDifferentialWorkedHours() {
return differentialWorkedHours;
public String getMaxWorkedHours() {
return maxWorkedHours;
}
public String getMinEstimatedHours() {
return minEstimatedHours;
}
public String getMinWorkedHours() {
return minWorkedHours;
}
/**
@ -147,146 +158,42 @@ public class OrderElementHistoricalStatisticsComponent extends
}
public BigDecimal calculateAverageEstimatedHours() {
BigDecimal sum = new BigDecimal(0);
BigDecimal average = new BigDecimal(0);
final List<OrderElement> list = getFinishedApplications();
for (OrderElement orderElement : list) {
sum = sum.add(new BigDecimal(orderElement.getWorkHours()));
}
if (sum.compareTo(new BigDecimal(0)) > 0) {
average = sum.divide(new BigDecimal(list.size()));
}
return average;
return orderElementDAO.calculateAverageEstimatedHours(orderElements);
}
public BigDecimal calculateAverageWorkedHours() {
BigDecimal sum = new BigDecimal(0);
BigDecimal average = new BigDecimal(0);
final List<OrderElement> list = getFinishedApplications();
for (OrderElement orderElement : list) {
sum = sum.add(new BigDecimal(orderElementDAO
.getAssignedDirectHours(orderElement)));
}
if (sum.compareTo(new BigDecimal(0)) > 0) {
average = sum.divide(new BigDecimal(list.size()));
}
return average;
return orderElementDAO.calculateAverageWorkedHours(list);
}
public BigDecimal calculateEstimatedDifferential() {
BigDecimal average = new BigDecimal(0);
final List<OrderElement> list = getFinishedApplications();
if (!list.isEmpty()) {
BigDecimal initValue = new BigDecimal(list.get(0).getWorkHours());
BigDecimal max = initValue.setScale(2);
BigDecimal min = initValue.setScale(2);
for (OrderElement orderElement : list) {
BigDecimal value = new BigDecimal(orderElement.getWorkHours());
if (max.compareTo(value) < 0) {
max = value.setScale(2);
}
if (min.compareTo(value) > 0) {
min = value.setScale(2);
}
}
if (max.compareTo(new BigDecimal(0)) > 0) {
average = max.divide(min).setScale(2);
}
}
return average;
public BigDecimal calculateMaxEstimatedHours() {
return orderElementDAO.calculateMaxEstimatedHours(orderElements);
}
public BigDecimal calculateWorkedDifferential() {
BigDecimal average = new BigDecimal(0);
final List<OrderElement> list = getFinishedApplications();
if (!list.isEmpty()) {
BigDecimal initValue = new BigDecimal(orderElementDAO
.getAssignedDirectHours(list.get(0)));
BigDecimal max = initValue.setScale(2);
BigDecimal min = initValue.setScale(2);
public BigDecimal calculateMinEstimatedHours() {
return orderElementDAO.calculateMinEstimatedHours(orderElements);
}
for (OrderElement orderElement : list) {
BigDecimal value = new BigDecimal(orderElementDAO
.getAssignedDirectHours(orderElement));
if (max.compareTo(value) < 0) {
max = value.setScale(2);
}
if (min.compareTo(value) > 0) {
min = value.setScale(2);
}
}
if (max.compareTo(new BigDecimal(0)) > 0) {
average = max.divide(min).setScale(2);
}
}
return average;
public BigDecimal calculateMaxWorkedHours() {
final List<OrderElement> list = getFinishedApplications();
return orderElementDAO.calculateMaxWorkedHours(list);
}
public BigDecimal calculateMinWorkedHours() {
final List<OrderElement> list = getFinishedApplications();
return orderElementDAO.calculateMinWorkedHours(list);
}
private List<OrderElement> getFinishedApplications() {
List<OrderElement> result = new ArrayList<OrderElement>();
for (OrderElement orderElement : orderElements) {
if (isFinishApplication(orderElement)) {
if (orderElement.isFinishPlanificationPointTask()) {
result.add(orderElement);
}
}
return result;
}
private boolean isFinishApplication(OrderElement orderElement) {
// look up into the order elements tree
TaskElement task = lookToUpAssignedTask(orderElement);
if (task != null) {
return isFinished(task.getOrderElement());
}
// look down into the order elements tree
List<TaskElement> listTask = lookToDownAssignedTask(orderElement);
if (!listTask.isEmpty()) {
for (TaskElement taskElement : listTask) {
if (!isFinished(taskElement.getOrderElement())) {
return false;
}
}
}
// not exist assigned task
return isFinished(orderElementDAO
.loadOrderAvoidingProxyFor(orderElement));
}
private TaskElement lookToUpAssignedTask(OrderElement current) {
OrderElement result = current;
while (current != null) {
if (current.isSchedulingPoint()) {
return current.getAssociatedTaskElement();
}
result = current;
current = current.getParent();
}
return null;
}
private List<TaskElement> lookToDownAssignedTask(OrderElement current) {
List<TaskElement> resultTask = new ArrayList<TaskElement>();
for (OrderElement child : current.getAllChildren()) {
if (child.isSchedulingPoint()) {
TaskElement task = child.getAssociatedTaskElement();
if (task != null) {
resultTask.add(task);
}
}
}
return resultTask;
}
private boolean isFinished(OrderElement orderElement) {
BigDecimal measuredProgress = orderElement.getAdvancePercentage();
measuredProgress = (measuredProgress.setScale(0, BigDecimal.ROUND_UP)
.multiply(new BigDecimal(100)));
return (measuredProgress.compareTo(new BigDecimal(100)) == 0);
}
private Object getBean(String classname) {
HttpServletRequest servletRequest = (HttpServletRequest) Executions
.getCurrent().getNativeRequest();

View file

@ -52,11 +52,19 @@
</row>
<row>
<label value="${i18n:_('Maximum/minimum of the estimated hours')}"/>
<label value="@{historicalStatistics.differentialEstimatedHours}"/>
<hbox>
<label value="@{historicalStatistics.maxEstimatedHours}"/>
<label value=" / "/>
<label value="@{historicalStatistics.minEstimatedHours}"/>
</hbox>
</row>
<row>
<label value="${i18n:_('Maximum/minimum of the worked hours')}"/>
<label value="@{historicalStatistics.differentialWorkedHours}"/>
<hbox>
<label value="@{historicalStatistics.maxWorkedHours}"/>
<label value=" / "/>
<label value="@{historicalStatistics.minWorkedHours}"/>
</hbox>
</row>
</rows>
</grid>