diff --git a/libreplan-business/src/main/java/org/libreplan/business/orders/entities/Order.java b/libreplan-business/src/main/java/org/libreplan/business/orders/entities/Order.java index 2cc90525e..b8859374e 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/orders/entities/Order.java +++ b/libreplan-business/src/main/java/org/libreplan/business/orders/entities/Order.java @@ -248,7 +248,7 @@ public class Order extends OrderLineGroup implements Comparable { this.materialsBudget = materialsBudget; } - public BigDecimal getTotalBudget() { + public BigDecimal getTotalManualBudget() { return getWorkBudget().add(getMaterialsBudget()); } diff --git a/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderElement.java b/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderElement.java index 367ec5bce..7878190d6 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderElement.java +++ b/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderElement.java @@ -49,11 +49,16 @@ import org.libreplan.business.advance.entities.DirectAdvanceAssignment; import org.libreplan.business.advance.entities.IndirectAdvanceAssignment; import org.libreplan.business.advance.exceptions.DuplicateAdvanceAssignmentForOrderElementException; import org.libreplan.business.advance.exceptions.DuplicateValueTrueReportGlobalAdvanceException; +import org.libreplan.business.common.IOnTransaction; import org.libreplan.business.common.IntegrationEntity; import org.libreplan.business.common.Registry; import org.libreplan.business.common.daos.IIntegrationEntityDAO; +import org.libreplan.business.common.entities.Configuration; import org.libreplan.business.common.entities.PredefinedConnectorProperties; +import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.common.exceptions.ValidationException; +import org.libreplan.business.costcategories.entities.CostCategory; +import org.libreplan.business.costcategories.entities.TypeOfWorkHours; import org.libreplan.business.labels.entities.Label; import org.libreplan.business.materials.entities.MaterialAssignment; import org.libreplan.business.orders.daos.IOrderDAO; @@ -1693,4 +1698,85 @@ public abstract class OrderElement extends IntegrationEntity implements return false; } + + public BigDecimal getTotalBudget() { + return getBudget().add(getResourcesBudget()); + } + + public BigDecimal getResourcesBudget() { + BigDecimal result = new BigDecimal(0); + Configuration configuration = Registry + .getConfigurationDAO() + .getConfiguration(); + if (configuration == null) { + return result; + } + if (configuration.isEnabledAutomaticBudget()) { + result = Registry.getTransactionService().runOnReadOnlyTransaction( + new IOnTransaction() { + + @Override + public BigDecimal execute() { + return calculateBudgetFromCriteriaAndCostCategories(); + } + }); + } + return result; + } + + public BigDecimal calculateBudgetFromCriteriaAndCostCategories() { + BigDecimal totalBudget = new BigDecimal(0); + BigDecimal costPerHour = new BigDecimal(0); + Configuration configuration = Registry.getConfigurationDAO() + .getConfiguration(); + TypeOfWorkHours typeofWorkHours = configuration + .getBudgetDefaultTypeOfWorkHours(); + + if (typeofWorkHours == null) { + return totalBudget; + } + + // FIXME: This workarounds LazyException when adding new + // criteria but disables the refresh on changes + for (CriterionRequirement requirement : getCriterionRequirements()) { + BigDecimal hours = new BigDecimal(getWorkHours()); + try { + totalBudget = totalBudget.add(costPerHour.multiply(hours)); + + costPerHour = requirement.getCriterion().getCostCategory() + .getHourCostByCode(typeofWorkHours.getCode()) + .getPriceCost(); + totalBudget = totalBudget.add(costPerHour.multiply(hours)); + + } catch (InstanceNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + totalBudget = totalBudget.add(costPerHour.multiply(hours)); + } + + for (HoursGroup hoursGroup : getHoursGroups()) { + BigDecimal hours = new BigDecimal(hoursGroup.getWorkingHours()); + + for (CriterionRequirement crit : hoursGroup + .getCriterionRequirements()) { + CostCategory costcat = crit.getCriterion().getCostCategory(); + + if (costcat != null) { + try { + costPerHour = costcat + .getPriceCostByTypeOfWorkHour(typeofWorkHours + .getCode()); + } catch (InstanceNotFoundException e) { + // Default values to 0 + costPerHour = new BigDecimal(0); + } + } + } + totalBudget = totalBudget.add(costPerHour.multiply(hours)); + } + + return totalBudget; + } + } diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/TaskElement.java b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/TaskElement.java index 767781861..16cc2144e 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/TaskElement.java +++ b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/TaskElement.java @@ -791,6 +791,13 @@ public abstract class TaskElement extends BaseEntity { return null; } + public BigDecimal getResourcesBudget() { + if ((taskSource != null) && (taskSource.getOrderElement() != null)) { + return taskSource.getOrderElement().getResourcesBudget(); + } + return null; + } + public ExternalCompany getSubcontractedCompany() { return null; } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/orders/IOrderElementModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/orders/IOrderElementModel.java index c71f8b0c4..f0cde9068 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/orders/IOrderElementModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/orders/IOrderElementModel.java @@ -54,6 +54,4 @@ public interface IOrderElementModel { boolean isCodeAutogenerated(); - BigDecimal getTotalBudget(); - } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderCRUDController.java b/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderCRUDController.java index 125ba6e5d..05fd3ac10 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderCRUDController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderCRUDController.java @@ -23,6 +23,7 @@ package org.libreplan.web.orders; import static org.libreplan.web.I18nHelper._; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.ConcurrentModificationException; @@ -40,6 +41,8 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.LogFactory; import org.joda.time.LocalDate; import org.libreplan.business.calendars.entities.BaseCalendar; +import org.libreplan.business.common.IOnTransaction; +import org.libreplan.business.common.Registry; import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.externalcompanies.entities.DeadlineCommunication; import org.libreplan.business.externalcompanies.entities.DeliverDateComparator; @@ -1316,7 +1319,8 @@ public class OrderCRUDController extends GenericForwardComposer { appendDate(row, order.getInitDate()); appendDate(row, order.getDeadline()); appendCustomer(row, order.getCustomer()); - appendObject(row, Util.addCurrencySymbol(order.getTotalBudget())); + appendObject(row, + Util.addCurrencySymbol(order.getTotalManualBudget())); appendObject(row, order.getTotalHours()); appendObject(row, _(order.getState().toString())); appendOperations(row, order); @@ -1893,4 +1897,20 @@ public class OrderCRUDController extends GenericForwardComposer { } } + public BigDecimal getResourcesBudget() { + return Registry.getTransactionService() + .runOnAnotherReadOnlyTransaction( + new IOnTransaction() { + + @Override + public BigDecimal execute() { + return getOrderElementModel().getOrderElement() + .getResourcesBudget(); + } + }); + } + + public BigDecimal getTotalBudget() { + return getOrder().getBudget().add(getResourcesBudget()); + } } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderElementModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderElementModel.java index 498ec0bd5..2ff1c3452 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderElementModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderElementModel.java @@ -166,63 +166,4 @@ public class OrderElementModel implements IOrderElementModel { return order.isCodeAutogenerated(); } - @Override - @Transactional(readOnly = true) - public BigDecimal getTotalBudget() { - BigDecimal totalBudget = new BigDecimal(0); - BigDecimal costPerHour = new BigDecimal(0); - - TypeOfWorkHours typeofWorkHours = configurationDAO.getConfiguration() - .getBudgetDefaultTypeOfWorkHours(); - - if (typeofWorkHours == null) { - return totalBudget; - } - - // FIXME: This workarounds LazyException when adding new - // criteria but disables the refresh on changes - for (CriterionRequirement requirement : getOrderElement() - .getCriterionRequirements()) { - BigDecimal hours = new BigDecimal(getOrderElement().getWorkHours()); - try { - totalBudget = totalBudget.add(costPerHour.multiply(hours)); - - costPerHour = requirement.getCriterion().getCostCategory() - .getHourCostByCode(typeofWorkHours.getCode()) - .getPriceCost(); - totalBudget = totalBudget.add(costPerHour.multiply(hours)); - - } catch (InstanceNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - totalBudget = totalBudget.add(costPerHour.multiply(hours)); - } - - for (HoursGroup hoursGroup : getOrderElement().getHoursGroups()) { - BigDecimal hours = new BigDecimal(hoursGroup.getWorkingHours()); - - for (CriterionRequirement crit : hoursGroup - .getCriterionRequirements()) { - CostCategory costcat = crit.getCriterion().getCostCategory(); - - - if (costcat != null) { - try { - costPerHour = costcat - .getPriceCostByTypeOfWorkHour(typeofWorkHours - .getCode()); - } catch (InstanceNotFoundException e) { - // Default values to 0 - costPerHour = new BigDecimal(0); - } - } - } - totalBudget = totalBudget.add(costPerHour.multiply(hours)); - } - - - return totalBudget; - } - } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderElementTreeController.java b/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderElementTreeController.java index a84ca5038..97e75de6c 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderElementTreeController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderElementTreeController.java @@ -39,13 +39,15 @@ import javax.annotation.Resource; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.LogFactory; import org.aspectj.weaver.ICrossReferenceHandler; +import org.libreplan.business.common.IAdHocTransactionService; +import org.libreplan.business.common.IOnTransaction; +import org.libreplan.business.common.Registry; import org.libreplan.business.common.daos.IConfigurationDAO; import org.libreplan.business.common.daos.IConnectorDAO; import org.libreplan.business.common.entities.Connector; import org.libreplan.business.common.entities.EntitySequence; import org.libreplan.business.common.entities.PredefinedConnectorProperties; import org.libreplan.business.common.entities.PredefinedConnectors; -import org.libreplan.business.orders.entities.HoursGroup; import org.libreplan.business.orders.entities.Order; import org.libreplan.business.orders.entities.OrderElement; import org.libreplan.business.orders.entities.OrderLine; @@ -64,14 +66,12 @@ import org.libreplan.web.common.components.bandboxsearch.BandboxSearch; import org.libreplan.web.common.components.finders.FilterPair; import org.libreplan.web.common.components.finders.OrderElementFilterEnum; import org.libreplan.web.common.components.finders.TaskElementFilterEnum; -import org.libreplan.web.materials.UnitTypeModel; import org.libreplan.web.orders.assigntemplates.TemplateFinderPopup; import org.libreplan.web.orders.assigntemplates.TemplateFinderPopup.IOnResult; import org.libreplan.web.security.SecurityUtils; import org.libreplan.web.templates.IOrderTemplatesControllerEntryPoints; import org.libreplan.web.tree.TreeController; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; import org.zkoss.ganttz.IPredicate; import org.zkoss.ganttz.util.ComponentsFinder; import org.zkoss.zk.ui.Component; @@ -84,7 +84,6 @@ import org.zkoss.zul.Button; import org.zkoss.zul.Checkbox; import org.zkoss.zul.Constraint; import org.zkoss.zul.Datebox; -import org.zkoss.zul.Label; import org.zkoss.zul.Popup; import org.zkoss.zul.Tab; import org.zkoss.zul.Textbox; @@ -141,6 +140,9 @@ public class OrderElementTreeController extends TreeController { @Autowired private ICriterionDAO criterionDAO; + @Autowired + private IAdHocTransactionService transactionService; + private static final org.apache.commons.logging.Log LOG = LogFactory .getLog(OrderElementTreeController.class); @@ -622,11 +624,18 @@ public class OrderElementTreeController extends TreeController { super.removeCodeTextbox(key); } - public void addAutoBudgetCell(OrderElement currentElement) { - IOrderElementModel model = orderModel - .getOrderElementModel(currentElement); - Textbox autoBudgetCell = new Textbox(Util.addCurrencySymbol(model - .getTotalBudget())); + public void addResourcesBudgetCell(final OrderElement currentElement) { + BigDecimal value = Registry.getTransactionService() + .runOnAnotherReadOnlyTransaction( + new IOnTransaction() { + + @Override + public BigDecimal execute() { + return currentElement.getResourcesBudget(); + } + }); + // BigDecimal value = currentElement.getResourcesBudget(); + Textbox autoBudgetCell = new Textbox(Util.addCurrencySymbol(value)); autoBudgetCell.setDisabled(true); addCell(autoBudgetCell); } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrdersTreeComponent.java b/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrdersTreeComponent.java index 1de028990..867960469 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrdersTreeComponent.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrdersTreeComponent.java @@ -44,9 +44,6 @@ import org.zkoss.zul.Treeitem; */ public class OrdersTreeComponent extends TreeComponent { - @Autowired - private IConfigurationDAO configurationDAO; - abstract class OrdersTreeColumn extends Column { OrdersTreeColumn(String label, String cssClass, String tooltip) { super(label, cssClass, tooltip); @@ -86,7 +83,7 @@ public class OrdersTreeComponent extends TreeComponent { } }); - columns.add(new OrdersTreeColumn(_("Budget"), "budget", + columns.add(new OrdersTreeColumn(_("Expenses"), "budget", _("Total task budget")) { @Override @@ -98,13 +95,13 @@ public class OrdersTreeComponent extends TreeComponent { }); // Pending to add condition with configuration.isEnabledAutomaticBudget - columns.add(new OrdersTreeColumn(_("autobudget"), "autobudget", - _("autobudget")) { + columns.add(new OrdersTreeColumn(_("Resources"), "autobudget", + _("resources")) { @Override protected void doCell(OrderElementTreeitemRenderer treeRenderer, OrderElement currentElement) { - treeRenderer.addAutoBudgetCell(currentElement); + treeRenderer.addResourcesBudgetCell(currentElement); } }); diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/TaskElementAdapter.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/TaskElementAdapter.java index aea1dfc86..7e13cc72f 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/TaskElementAdapter.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/TaskElementAdapter.java @@ -609,7 +609,7 @@ public class TaskElementAdapter { @Override public BigDecimal getMoneyCostBarPercentage() { return MoneyCostCalculator.getMoneyCostProportion( - getMoneyCost(), getBudget()); + getMoneyCost(), getTotalCalculatedBudget()); } private BigDecimal getBudget() { @@ -620,6 +620,30 @@ public class TaskElementAdapter { return taskElement.getOrderElement().getBudget(); } + private BigDecimal getTotalCalculatedBudget() { + if ((taskElement == null) + || (taskElement.getOrderElement() == null)) { + return BigDecimal.ZERO; + } + return transactionService + .runOnReadOnlyTransaction(new IOnTransaction() { + + @Override + public BigDecimal execute() { + return taskElement.getOrderElement() + .getTotalBudget(); + } + }); + } + + private BigDecimal getTotalBudget() { + if ((taskElement == null) + || (taskElement.getOrderElement() == null)) { + return BigDecimal.ZERO; + } + return taskElement.getOrderElement().getResourcesBudget(); + } + private BigDecimal getMoneyCost() { if ((taskElement == null) || (taskElement.getOrderElement() == null)) { @@ -895,7 +919,8 @@ public class TaskElementAdapter { if (taskElement.getOrderElement() instanceof Order) { result.append(_("State") + ": ").append(getOrderState()); } else { - String budget = Util.addCurrencySymbol(getBudget()); + String budget = Util + .addCurrencySymbol(getTotalCalculatedBudget()); String moneyCost = Util.addCurrencySymbol(getMoneyCost()); String costHours = Util.addCurrencySymbol(getHoursMoneyCost()); diff --git a/libreplan-webapp/src/main/webapp/orders/_edition.zul b/libreplan-webapp/src/main/webapp/orders/_edition.zul index 0602b6c0d..82c2c4462 100644 --- a/libreplan-webapp/src/main/webapp/orders/_edition.zul +++ b/libreplan-webapp/src/main/webapp/orders/_edition.zul @@ -156,7 +156,7 @@ - + @@ -182,15 +182,28 @@ format="@{controller.moneyFormat}"/>