From 460a8cf5ad976d194a830a3f58535caf362d6568 Mon Sep 17 00:00:00 2001 From: Susana Montes Pedreira Date: Thu, 28 Jan 2010 19:57:41 +0100 Subject: [PATCH] ItEr45S12RFGravacionDatosHistoricosResponsabilidadesTraballoUnidadesPlanItEr44S18: Fix the historical statistics of the templates. --- .../orders/daos/IOrderElementDAO.java | 12 ++ .../business/orders/daos/OrderElementDAO.java | 110 +++++++++++ .../orders/entities/OrderElement.java | 55 ++++++ .../web/templates/IOrderTemplatesModel.java | 1 + .../OrderElementsOnConversation.java | 74 +++++++ .../web/templates/OrderTemplatesModel.java | 15 ++ ...rElementHistoricalAssignmentComponent.java | 11 +- ...rElementHistoricalStatisticsComponent.java | 183 +++++------------- .../templates/_historicalStatistics.zul | 12 +- 9 files changed, 327 insertions(+), 146 deletions(-) create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/templates/OrderElementsOnConversation.java diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/IOrderElementDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/IOrderElementDAO.java index 0952b7bc3..d17c47ead 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/IOrderElementDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/IOrderElementDAO.java @@ -101,4 +101,16 @@ public interface IOrderElementDAO extends IGenericDAO { List findByTemplate(OrderElementTemplate template); + BigDecimal calculateAverageEstimatedHours(final List list); + + BigDecimal calculateAverageWorkedHours(final List list); + + BigDecimal calculateMaxEstimatedHours(final List list); + + BigDecimal calculateMinEstimatedHours(final List list); + + BigDecimal calculateMaxWorkedHours(final List list); + + BigDecimal calculateMinWorkedHours(final List list); + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/OrderElementDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/OrderElementDAO.java index dd881c80d..3be08ed99 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/OrderElementDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/OrderElementDAO.java @@ -252,4 +252,114 @@ public class OrderElementDAO extends GenericDAOHibernate 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 list) { + BigDecimal sum = sumEstimatedHours(list); + return average(new BigDecimal(list.size()), sum); + } + + public BigDecimal calculateAverageWorkedHours(final List 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 list) { + BigDecimal sum = new BigDecimal(0); + for (OrderElement orderElement : list) { + sum = sum.add(new BigDecimal(orderElement.getWorkHours())); + } + return sum; + } + + private BigDecimal sumWorkedHours(final List list) { + BigDecimal sum = new BigDecimal(0); + for (OrderElement orderElement : list) { + sum = sum.add(new BigDecimal(getAssignedDirectHours(orderElement))); + } + return sum; + } + + public BigDecimal calculateMaxEstimatedHours(final List 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 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 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 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; + } + } \ No newline at end of file diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderElement.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderElement.java index 3607f775d..2678aebf7 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderElement.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderElement.java @@ -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 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 lookToDownAssignedTask() { + List resultTask = new ArrayList(); + 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); + } } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/IOrderTemplatesModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/IOrderTemplatesModel.java index 302e07fb9..d98c695bc 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/IOrderTemplatesModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/IOrderTemplatesModel.java @@ -54,4 +54,5 @@ public interface IOrderTemplatesModel { Set getAllQualityForms(); + OrderElementsOnConversation getOrderElementsOnConversation(); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/OrderElementsOnConversation.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/OrderElementsOnConversation.java new file mode 100644 index 000000000..3682dcc89 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/OrderElementsOnConversation.java @@ -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 . + */ +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 + * + */ +public class OrderElementsOnConversation { + + private final IOrderElementDAO orderElementDAO; + + private List orderElements = new ArrayList(); + + public OrderElementsOnConversation(IOrderElementDAO orderElementDAO) { + this.orderElementDAO = orderElementDAO; + } + + public List getOrderElements() { + return orderElements; + } + + public void initialize(OrderElementTemplate template) { + if ((template != null) && (!template.isNewObject())) { + orderElements = new ArrayList(orderElementDAO + .findByTemplate(template)); + initialize(orderElements); + } + } + + private void initialize(Collection 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(); + } + } + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/OrderTemplatesModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/OrderTemplatesModel.java index 699fa3ecb..501bc30c3 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/OrderTemplatesModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/OrderTemplatesModel.java @@ -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 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) { diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/historicalAssignment/OrderElementHistoricalAssignmentComponent.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/historicalAssignment/OrderElementHistoricalAssignmentComponent.java index 80fedf2cc..1d454e96f 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/historicalAssignment/OrderElementHistoricalAssignmentComponent.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/historicalAssignment/OrderElementHistoricalAssignmentComponent.java @@ -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 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>() { @Override public List execute() { - final List orderElements = new ArrayList( - orderElementDAO.findByTemplate(template)); + model.getOrderElementsOnConversation().reattach(); return createOrderElementHistoricAssignmentDTOs(orderElements); } }); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/historicalStatistics/OrderElementHistoricalStatisticsComponent.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/historicalStatistics/OrderElementHistoricalStatisticsComponent.java index f76339b79..8ed9ba539 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/historicalStatistics/OrderElementHistoricalStatisticsComponent.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/historicalStatistics/OrderElementHistoricalStatisticsComponent.java @@ -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 orderElements = new ArrayList(); + private List finishedOrderElements = new ArrayList(); + 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() { @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 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 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 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 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 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 list = getFinishedApplications(); + return orderElementDAO.calculateMaxWorkedHours(list); + } + + public BigDecimal calculateMinWorkedHours() { + final List list = getFinishedApplications(); + return orderElementDAO.calculateMinWorkedHours(list); } private List getFinishedApplications() { List result = new ArrayList(); 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 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 lookToDownAssignedTask(OrderElement current) { - List resultTask = new ArrayList(); - 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(); diff --git a/navalplanner-webapp/src/main/webapp/templates/_historicalStatistics.zul b/navalplanner-webapp/src/main/webapp/templates/_historicalStatistics.zul index 4ccb5b4bc..68bb34b73 100644 --- a/navalplanner-webapp/src/main/webapp/templates/_historicalStatistics.zul +++ b/navalplanner-webapp/src/main/webapp/templates/_historicalStatistics.zul @@ -52,11 +52,19 @@