Moved criteria based budget calculation methods to OrderElement to use them from the OrderCRUD

FEA: ItEr77S17AutomaticBudgeting
This commit is contained in:
Lorenzo Tilve Álvaro 2013-06-11 12:55:24 +02:00
parent 5df152a9bd
commit 4baa93d790
11 changed files with 183 additions and 87 deletions

View file

@ -248,7 +248,7 @@ public class Order extends OrderLineGroup implements Comparable {
this.materialsBudget = materialsBudget;
}
public BigDecimal getTotalBudget() {
public BigDecimal getTotalManualBudget() {
return getWorkBudget().add(getMaterialsBudget());
}

View file

@ -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<BigDecimal>() {
@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;
}
}

View file

@ -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;
}

View file

@ -54,6 +54,4 @@ public interface IOrderElementModel {
boolean isCodeAutogenerated();
BigDecimal getTotalBudget();
}

View file

@ -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<BigDecimal>() {
@Override
public BigDecimal execute() {
return getOrderElementModel().getOrderElement()
.getResourcesBudget();
}
});
}
public BigDecimal getTotalBudget() {
return getOrder().getBudget().add(getResourcesBudget());
}
}

View file

@ -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;
}
}

View file

@ -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<OrderElement> {
@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<OrderElement> {
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<BigDecimal>() {
@Override
public BigDecimal execute() {
return currentElement.getResourcesBudget();
}
});
// BigDecimal value = currentElement.getResourcesBudget();
Textbox autoBudgetCell = new Textbox(Util.addCurrencySymbol(value));
autoBudgetCell.setDisabled(true);
addCell(autoBudgetCell);
}

View file

@ -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);
}
});

View file

@ -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<BigDecimal>() {
@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());

View file

@ -156,7 +156,7 @@
</grid>
</groupbox>
<groupbox style="margin-top: 5px" sclass="assignedresources" closable="false">
<caption label="${i18n:_('Cost')}" />
<caption label="${i18n:_('Budget')}" />
<separator spacing="10px"/>
@ -182,15 +182,28 @@
format="@{controller.moneyFormat}"/>
<separator bar="false" spacing="15px" orient="vertical"/>
<label value=" ${i18n:_('Total')} :" />
<label id="txtTotalBudget" value="@{controller.order.totalBudget}"/>
<label id="txtTotalBudget" value="@{controller.order.totalManualBudget}"/>
<label value="@{controller.currencySymbol}"/>
</hbox>
</row>
<row>
<label value="${i18n:_('Calculated budget')}" />
<label value="${i18n:_('WBS calculated budget')}" />
<hbox>
<label id="budget" value="@{controller.order.budget}" />
<label value="@{controller.currencySymbol}"/>
<hbox>
<label value="${i18n:_('Expenses')}:" />
<label id="budget" value="@{controller.order.budget}" />
<label value="@{controller.currencySymbol}"/>
</hbox>
<hbox>
<label value="${i18n:_('Resources')}:" />
<label id="resourcesBudget" value="@{controller.resourcesBudget}" />
<label value="@{controller.currencySymbol}"/>
</hbox>
<hbox>
<label value="${i18n:_('Total')}:" />
<label id="totalCalculated" value="@{controller.totalBudget}" />
<label value="@{controller.currencySymbol}"/>
</hbox>
</hbox>
</row>
<row>

View file

@ -212,7 +212,7 @@ public class SubcontractServiceTest {
assertThat(order.getName(), equalTo(orderName));
assertThat(order.getCustomerReference(),
equalTo(orderCustomerReference));
assertThat(order.getTotalBudget(), equalTo(orderBudget));
assertThat(order.getResourcesBudget(), equalTo(orderBudget));
List<OrderElement> children = order.getChildren();
assertThat(children.size(), equalTo(1));