Modify the Project cost report to include a new area called

Expenses, per OrderElement.

FEA: ItEr76S24AdapatingProjectsToExpenses
This commit is contained in:
Susana Montes Pedreira 2012-05-07 08:08:59 +01:00
parent df19131dd4
commit 4da11d0f19
18 changed files with 1259 additions and 283 deletions

View file

@ -29,6 +29,7 @@ import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.planner.entities.Task;
import org.libreplan.business.reports.dtos.CostExpenseSheetDTO;
import org.libreplan.business.reports.dtos.OrderCostsPerResourceDTO;
import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.scenarios.entities.Scenario;
@ -101,4 +102,7 @@ public interface IOrderDAO extends IIntegrationEntityDAO<Order> {
boolean existsByNameAnotherTransaction(String name);
List<Order> getActiveOrders();
List<CostExpenseSheetDTO> getCostExpenseSheet(List<Order> orders, Date startingDate,
Date endingDate, List<Criterion> criterions);
}

View file

@ -43,6 +43,7 @@ import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderStatusEnum;
import org.libreplan.business.planner.daos.ITaskSourceDAO;
import org.libreplan.business.planner.entities.Task;
import org.libreplan.business.reports.dtos.CostExpenseSheetDTO;
import org.libreplan.business.reports.dtos.OrderCostsPerResourceDTO;
import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.scenarios.entities.Scenario;
@ -57,6 +58,7 @@ import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* Dao for {@link Order}
*
@ -161,6 +163,7 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
// Attach ordername value
each.setOrderName(order.getName());
each.setOrderCode(order.getCode());
// Attach calculated pricePerHour
BigDecimal pricePerHour = CostCategoryDAO
.getPriceByResourceDateAndHourType(each.getWorker(),
@ -423,4 +426,56 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
return criteria.list();
}
@Override
public List<CostExpenseSheetDTO> getCostExpenseSheet(List<Order> orders, Date startingDate,
Date endingDate, List<Criterion> criterions) {
String strQuery = "SELECT new org.libreplan.business.reports.dtos.CostExpenseSheetDTO(expense) "
+ "FROM OrderElement orderElement, ExpenseSheetLine expense "
+ "LEFT OUTER JOIN expense.orderElement exp_ord "
+ "WHERE orderElement.id = exp_ord.id ";
if (!orders.isEmpty()) {
strQuery += "AND orderElement.parent IN (:orders) ";
}
if (startingDate != null && endingDate != null) {
strQuery += "AND wrl.date BETWEEN :startingDate AND :endingDate ";
}
if (startingDate != null && endingDate == null) {
strQuery += "AND wrl.date >= :startingDate ";
}
if (startingDate == null && endingDate != null) {
strQuery += "AND wrl.date <= :endingDate ";
}
// Order by date
strQuery += "ORDER BY expense.date";
Query query = getSession().createQuery(strQuery);
// Set parameters
if (!orders.isEmpty()) {
query.setParameterList("orders", orders);
}
if (startingDate != null) {
query.setParameter("startingDate", startingDate);
}
if (endingDate != null) {
query.setParameter("endingDate", endingDate);
}
List<CostExpenseSheetDTO> list = query.list();
List<CostExpenseSheetDTO> filteredList = new ArrayList<CostExpenseSheetDTO>();
for (CostExpenseSheetDTO each : list) {
Order order = loadOrderAvoidingProxyFor(each.getOrderElement());
// Apply filtering
if (matchFilterCriterion(each.getOrderElement(), criterions)) {
each.setOrder(order);
filteredList.add(each);
}
}
return filteredList;
}
}

View file

@ -0,0 +1,114 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2012 WirelessGalcia 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 <http://www.gnu.org/licenses/>.
*/
package org.libreplan.business.reports.dtos;
import java.math.BigDecimal;
import java.util.Date;
import org.libreplan.business.expensesheet.entities.ExpenseSheetLine;
import org.libreplan.business.orders.entities.Order;
/**
* Note: this class has a natural ordering that is inconsistent with equals.
*/
/**
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
public class CostExpenseSheetDTO extends ReportPerOrderElementDTO implements
Comparable<CostExpenseSheetDTO> {
private Date date;
private String concept;
private String resource;
private BigDecimal value;
private String orderElementCode;
private Order order;
public CostExpenseSheetDTO(ExpenseSheetLine bean) {
super(bean.getOrderElement());
this.date = bean.getDate().toDateTimeAtStartOfDay().toDate();
this.concept = bean.getConcept();
if (bean.getResource() != null) {
this.resource = bean.getResource().getShortDescription();
}
this.value = bean.getValue();
this.setOrderElementCode(bean.getOrderElement().getCode());
}
public void setConcept(String concept) {
this.concept = concept;
}
public String getConcept() {
return concept;
}
public void setResource(String resource) {
this.resource = resource;
}
public String getResource() {
return resource;
}
public void setDate(Date date) {
this.date = date;
}
public Date getDate() {
return date;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public BigDecimal getValue() {
return value;
}
@Override
public int compareTo(CostExpenseSheetDTO o) {
if (date == null) {
return -1;
}
if (o.getDate() == null) {
return 1;
}
return date.compareTo(o.getDate());
}
public void setOrder(Order order) {
this.order = order;
}
public Order getOrder() {
return order;
}
public void setOrderElementCode(String orderElementCode) {
this.orderElementCode = orderElementCode;
}
public String getOrderElementCode() {
return orderElementCode;
}
}

View file

@ -0,0 +1,245 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2012 WirelessGalcia 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 <http://www.gnu.org/licenses/>.
*/
package org.libreplan.business.reports.dtos;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Set;
import org.joda.time.LocalTime;
import org.libreplan.business.labels.entities.Label;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.resources.entities.Worker;
import org.libreplan.business.workreports.entities.WorkReportLine;
import org.libreplan.business.workreports.valueobjects.DescriptionValue;
/**
* Note: this class has a natural ordering that is inconsistent with equals.
*/
/**
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
public class CostWorkReportLineDTO implements Comparable<CostWorkReportLineDTO> {
private OrderElement orderElement;
private String workerName;
private Date date;
private LocalTime clockStart;
private LocalTime clockFinish;
private BigDecimal numHours;
private String descriptionValues;
private String labels;
private String hoursType;
private String hoursTypeCode;
// Attached outside the DTO
private BigDecimal cost;
// Attached outside the DTO
private BigDecimal costPerHour;
private Worker worker;
private Boolean costTypeHours = Boolean.TRUE;
public CostWorkReportLineDTO(Worker worker, WorkReportLine workReportLine) {
this.workerName = worker.getName();
if (workReportLine.getLocalDate() != null) {
this.date = workReportLine.getLocalDate().toDateTimeAtStartOfDay().toDate();
}
this.clockStart = workReportLine.getClockStart();
this.clockFinish = workReportLine.getClockFinish();
this.numHours = workReportLine.getEffort().toHoursAsDecimalWithScale(2);
this.descriptionValues = descriptionValuesAsString(workReportLine.getDescriptionValues());
this.labels = labelsAsString(workReportLine.getLabels());
this.hoursType = workReportLine.getTypeOfWorkHours().getName();
this.hoursTypeCode = workReportLine.getTypeOfWorkHours().getCode();
this.worker = worker;
}
public CostWorkReportLineDTO(OrderCostsPerResourceDTO dto) {
this.workerName = dto.getWorkerName();
this.date = dto.getDate();
this.clockStart = dto.getClockStart();
this.clockFinish = dto.getClockFinish();
this.numHours = dto.getNumHours();
this.descriptionValues = dto.getDescriptionValues();
this.labels = dto.getLabels();
this.hoursType = dto.getHoursType();
this.hoursTypeCode = dto.getHoursTypeCode();
this.worker = dto.getWorker();
}
private String labelsAsString(Set<Label> labels) {
String result = "";
for (Label label : labels) {
result = label.getType().getName() + ": " + label.getName() + ", ";
}
return (result.length() > 0) ? result.substring(0, result.length() - 2) : result;
}
private String descriptionValuesAsString(Set<DescriptionValue> descriptionValues) {
String result = "";
for (DescriptionValue descriptionValue : descriptionValues) {
result = descriptionValue.getFieldName() + ": " + descriptionValue.getValue() + ", ";
}
return (result.length() > 0) ? result.substring(0, result.length() - 2) : result;
}
public BigDecimal getNumHours() {
return numHours;
}
public void setNumHours(BigDecimal numHours) {
this.numHours = numHours;
}
public LocalTime getClockStart() {
return clockStart;
}
public void setClockStart(LocalTime clockStart) {
this.clockStart = clockStart;
}
public LocalTime getClockFinish() {
return clockFinish;
}
public void setClockFinish(LocalTime clockFinish) {
this.clockFinish = clockFinish;
}
public String getWorkerName() {
return workerName;
}
public void setWorkerName(String workerName) {
this.workerName = workerName;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getDescriptionValues() {
return descriptionValues;
}
public void setDescriptionValues(String descriptionValues) {
this.descriptionValues = descriptionValues;
}
public String getLabels() {
return labels;
}
public void setLabels(String labels) {
this.labels = labels;
}
public String getHoursType() {
return hoursType;
}
public void setHoursType(String hoursType) {
this.hoursType = hoursType;
}
public BigDecimal getCost() {
return cost;
}
public void setCost(BigDecimal cost) {
this.cost = cost;
}
public BigDecimal getCostPerHour() {
return costPerHour;
}
public void setCostPerHour(BigDecimal costPerHour) {
this.costPerHour = costPerHour;
}
public Worker getWorker() {
return worker;
}
public void setWorker(Worker worker) {
this.worker = worker;
}
public int compareTo(CostWorkReportLineDTO o) {
String comparator = this.workerName;
int result = comparator.compareToIgnoreCase(o.workerName);
if (result == 0) {
if ((this.date != null) && (o.getDate() != null)) {
if (this.date.compareTo(o.getDate()) == 0) {
return this.hoursType.compareToIgnoreCase(o.getHoursType());
}
return this.date.compareTo(o.getDate());
} else {
return -1;
}
}
return result;
}
public void setHoursTypeCode(String hoursTypeCode) {
this.hoursTypeCode = hoursTypeCode;
}
public String getHoursTypeCode() {
return hoursTypeCode;
}
public void setCostTypeHours(Boolean costTypeHours) {
this.costTypeHours = costTypeHours;
}
public Boolean getCostTypeHours() {
return costTypeHours;
}
public void setOrderElement(OrderElement orderElement) {
this.orderElement = orderElement;
}
public OrderElement getOrderElement() {
return orderElement;
}
}

View file

@ -0,0 +1,131 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2012 WirelessGalicia, 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 <http://www.gnu.org/licenses/>.
*/
package org.libreplan.business.reports.dtos;
import org.libreplan.business.orders.entities.OrderElement;
/**
* Note: this class has a natural ordering that is inconsistent with equals.
*/
/**
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
public class OrderCostMasterDTO implements Comparable<OrderCostMasterDTO> {
private String orderElementName;
private String orderElementCode;
// Attached outside the DTO
private String orderName;
// Attached outside the DTO
private String orderCode;
private OrderElement orderElement;
/*
* type net.sf.jasperreports.engine.JRDataSource;
*/
private Object listExpensesDTO;
/*
* type net.sf.jasperreports.engine.JRDataSource;
*/
private Object listWorkReportLineDTO;
public OrderCostMasterDTO(OrderElement orderElement, Object dsWRL, Object dsES) {
this.orderElement = orderElement;
this.orderElementCode = orderElement.getCode();
this.orderElementName = orderElement.getName();
this.listExpensesDTO = dsES;
this.listWorkReportLineDTO = dsWRL;
}
public String getOrderElementCode() {
return orderElementCode;
}
public void setOrderElementCode(String orderElementCode) {
this.orderElementCode = orderElementCode;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public OrderElement getOrderElement() {
return orderElement;
}
public void setOrderElement(OrderElement orderElement) {
this.orderElement = orderElement;
}
public void setOrderElementName(String orderElementName) {
this.orderElementName = orderElementName;
}
public String getOrderElementName() {
return orderElementName;
}
public void setOrderCode(String orderCode) {
this.orderCode = orderCode;
}
public String getOrderCode() {
return orderCode;
}
public void setListExpensesDTO(Object listExpensesDTO) {
this.listExpensesDTO = listExpensesDTO;
}
public Object getListExpensesDTO() {
return listExpensesDTO;
}
@Override
public int compareTo(OrderCostMasterDTO o) {
String comparator = this.orderElementName;
int result = comparator.compareToIgnoreCase(o.getOrderElementName());
if (result == 0) {
comparator = this.orderElementCode;
result = comparator.compareToIgnoreCase(o.getOrderElementCode());
}
return result;
}
public void setListWorkReportLineDTO(Object listWorkReportLineDTO) {
this.listWorkReportLineDTO = listWorkReportLineDTO;
}
public Object getListWorkReportLineDTO() {
return listWorkReportLineDTO;
}
}

View file

@ -27,7 +27,6 @@ import java.util.Set;
import org.joda.time.LocalTime;
import org.libreplan.business.labels.entities.Label;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.resources.entities.Worker;
import org.libreplan.business.workreports.entities.WorkReportLine;
import org.libreplan.business.workreports.valueobjects.DescriptionValue;
@ -36,7 +35,7 @@ import org.libreplan.business.workreports.valueobjects.DescriptionValue;
/**
* Note: this class has a natural ordering that is inconsistent with equals.
*/
public class OrderCostsPerResourceDTO implements
public class OrderCostsPerResourceDTO extends ReportPerOrderElementDTO implements
Comparable<OrderCostsPerResourceDTO> {
private String workerName;
@ -73,13 +72,18 @@ public class OrderCostsPerResourceDTO implements
// Attached outside the DTO
private String orderCode;
private OrderElement orderElement;
private Worker worker;
private Boolean costTypeHours = Boolean.TRUE;
/*
* type net.sf.jasperreports.engine.JRDataSource;
*/
private Object listExpensesDTO;
public OrderCostsPerResourceDTO(Worker worker,
WorkReportLine workReportLine) {
super(workReportLine.getOrderElement());
this.workerName = worker.getName();
if (workReportLine.getLocalDate() != null) {
this.date = workReportLine.getLocalDate().toDateTimeAtStartOfDay()
@ -92,7 +96,7 @@ public class OrderCostsPerResourceDTO implements
this.labels = labelsAsString(workReportLine.getLabels());
this.hoursType = workReportLine.getTypeOfWorkHours().getName();
this.hoursTypeCode = workReportLine.getTypeOfWorkHours().getCode();
this.orderElement = workReportLine.getOrderElement();
this.orderElementCode = workReportLine.getOrderElement().getCode();
this.orderElementName = workReportLine.getOrderElement().getName();
this.worker = worker;
@ -202,14 +206,6 @@ public class OrderCostsPerResourceDTO implements
this.cost = cost;
}
public OrderElement getOrderElement() {
return orderElement;
}
public void setOrderElement(OrderElement orderElement) {
this.orderElement = orderElement;
}
public BigDecimal getCostPerHour() {
return costPerHour;
}
@ -268,4 +264,20 @@ public class OrderCostsPerResourceDTO implements
return orderCode;
}
public void setCostTypeHours(Boolean costTypeHours) {
this.costTypeHours = costTypeHours;
}
public Boolean getCostTypeHours() {
return costTypeHours;
}
public void setListExpensesDTO(Object listExpensesDTO) {
this.listExpensesDTO = listExpensesDTO;
}
public Object getListExpensesDTO() {
return listExpensesDTO;
}
}

View file

@ -0,0 +1,45 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2012 WirelessGalcia 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 <http://www.gnu.org/licenses/>.
*/
package org.libreplan.business.reports.dtos;
import org.libreplan.business.orders.entities.OrderElement;
/**
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
public abstract class ReportPerOrderElementDTO {
private OrderElement orderElement;
public ReportPerOrderElementDTO() {
}
public ReportPerOrderElementDTO(OrderElement orderElement) {
this.orderElement = orderElement;
}
public OrderElement getOrderElement() {
return this.orderElement;
}
public void setOrderElement(OrderElement orderElement) {
this.orderElement = orderElement;
}
}

View file

@ -0,0 +1,3 @@
# Resource Bundle file.
#
key=value

View file

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="report1" pageWidth="595" pageHeight="842" columnWidth="535" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" resourceBundle="orderCostsPerResource">
<reportFont name="FreeSans" isDefault="true" fontName="FreeSans" size="9"/>
<subDataset name="dataset1"/>
<field name="date" class="java.util.Date"/>
<field name="value" class="java.math.BigDecimal"/>
<field name="concept" class="java.lang.String"/>
<field name="resource" class="java.lang.String"/>
<field name="orderElementCode" class="java.lang.String"/>
<variable name="sumValuePerTask" class="java.math.BigDecimal" calculation="Sum">
<variableExpression><![CDATA[$F{value}]]></variableExpression>
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<group name="Task">
<groupExpression><![CDATA[$F{orderElementCode}]]></groupExpression>
<groupHeader>
<band/>
</groupHeader>
<groupFooter>
<band height="23" splitType="Stretch">
<line>
<reportElement positionType="FixRelativeToBottom" x="0" y="3" width="555" height="1"/>
<graphicElement>
<pen lineWidth="0.5" lineColor="#999999"/>
</graphicElement>
</line>
<textField>
<reportElement x="40" y="0" width="269" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total.task}]]></textFieldExpression>
</textField>
<textField evaluationTime="Report" pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="422" y="0" width="110" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumValuePerTask}]]></textFieldExpression>
</textField>
</band>
</groupFooter>
</group>
<background>
<band splitType="Stretch"/>
</background>
<pageHeader>
<band height="21" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="293" height="20"/>
<textElement markup="none">
<font size="13" isItalic="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{expense.subtitle}]]></textFieldExpression>
</textField>
</band>
</pageHeader>
<columnHeader>
<band height="25" splitType="Stretch">
<textField>
<reportElement mode="Opaque" x="93" y="3" width="168" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.expense.column2}]]></textFieldExpression>
</textField>
<textField>
<reportElement mode="Opaque" x="261" y="3" width="173" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.expense.column3}]]></textFieldExpression>
</textField>
<textField>
<reportElement mode="Opaque" x="2" y="3" width="91" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.expense.column1}]]></textFieldExpression>
</textField>
<textField>
<reportElement mode="Opaque" x="434" y="3" width="98" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.expense.column4}]]></textFieldExpression>
</textField>
</band>
</columnHeader>
<detail>
<band height="17" splitType="Stretch">
<textField pattern="dd-MMM-yy" isBlankWhenNull="true">
<reportElement x="2" y="0" width="91" height="14"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.util.Date"><![CDATA[$F{date}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="93" y="0" width="168" height="14"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{concept}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="261" y="0" width="173" height="14"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{resource}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="434" y="0" width="98" height="14"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$F{value}]]></textFieldExpression>
</textField>
</band>
</detail>
<columnFooter>
<band/>
</columnFooter>
<pageFooter>
<band/>
</pageFooter>
<summary>
<band splitType="Stretch"/>
</summary>
</jasperReport>

View file

@ -0,0 +1,238 @@
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="report1" pageWidth="595" pageHeight="842" columnWidth="535" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" resourceBundle="orderCostsPerResource">
<reportFont name="FreeSans" isDefault="true" fontName="FreeSans" size="9"/>
<subDataset name="dataset1"/>
<field name="workerName" class="java.lang.String"/>
<field name="date" class="java.util.Date"/>
<field name="clockStart" class="java.util.Date"/>
<field name="clockFinish" class="java.util.Date"/>
<field name="numHours" class="java.math.BigDecimal"/>
<field name="orderElementCode" class="java.lang.String"/>
<field name="descriptionValues" class="java.lang.String"/>
<field name="labels" class="java.lang.String"/>
<field name="orderName" class="java.lang.String"/>
<field name="cost" class="java.math.BigDecimal"/>
<field name="hoursType" class="java.lang.String"/>
<field name="costPerHour" class="java.math.BigDecimal"/>
<variable name="sumHoursPerTask" class="java.math.BigDecimal" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<variable name="sumCostsPerTask" class="java.math.BigDecimal" calculation="Sum">
<variableExpression><![CDATA[$F{cost}]]></variableExpression>
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<variable name="sumHoursPerWorker" class="java.math.BigDecimal" resetType="Group" resetGroup="Worker" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<variable name="sumCosts" class="java.math.BigDecimal" resetType="Group" resetGroup="Worker" calculation="Sum">
<variableExpression><![CDATA[$F{cost}]]></variableExpression>
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<variable name="sumHoursPerWorkerandCost" class="java.math.BigDecimal" resetType="Group" resetGroup="HoursType Group" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<variable name="sumCostsPerWorkerandCost" class="java.math.BigDecimal" resetType="Group" resetGroup="HoursType Group" calculation="Sum">
<variableExpression><![CDATA[$F{cost}]]></variableExpression>
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<group name="Task">
<groupExpression><![CDATA[$F{orderElementCode}]]></groupExpression>
<groupHeader>
<band/>
</groupHeader>
<groupFooter>
<band height="22">
<line>
<reportElement positionType="FixRelativeToBottom" x="0" y="3" width="555" height="1"/>
<graphicElement>
<pen lineWidth="0.5" lineColor="#999999"/>
</graphicElement>
</line>
<textField>
<reportElement x="57" y="2" width="258" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total.task}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 h">
<reportElement x="315" y="2" width="93" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumHoursPerTask}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="408" y="2" width="119" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumCostsPerTask}]]></textFieldExpression>
</textField>
</band>
</groupFooter>
</group>
<group name="Worker">
<groupExpression><![CDATA[$F{workerName}]]></groupExpression>
<groupHeader>
<band height="50">
<textField evaluationTime="Group" evaluationGroup="Worker" pattern="" isBlankWhenNull="true">
<reportElement x="70" y="12" width="469" height="17"/>
<textElement>
<font size="11"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{workerName}]]></textFieldExpression>
</textField>
<textField>
<reportElement mode="Opaque" x="408" y="29" width="119" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.column5}]]></textFieldExpression>
</textField>
<textField>
<reportElement mode="Opaque" x="315" y="29" width="93" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.column4}]]></textFieldExpression>
</textField>
<textField>
<reportElement mode="Opaque" x="237" y="29" width="78" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.column3}]]></textFieldExpression>
</textField>
<textField>
<reportElement mode="Opaque" x="96" y="29" width="141" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.column1}]]></textFieldExpression>
</textField>
<textField>
<reportElement mode="Opaque" x="1" y="29" width="95" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.column2}]]></textFieldExpression>
</textField>
</band>
</groupHeader>
<groupFooter>
<band height="28">
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="408" y="2" width="119" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumCosts}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="57" y="2" width="258" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font isBold="false"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total.worker}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 h">
<reportElement x="315" y="2" width="93" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumHoursPerWorker}]]></textFieldExpression>
</textField>
</band>
</groupFooter>
</group>
<group name="Date Group">
<groupExpression><![CDATA[$F{date}]]></groupExpression>
<groupHeader>
<band/>
</groupHeader>
<groupFooter>
<band/>
</groupFooter>
</group>
<group name="HoursType Group">
<groupExpression><![CDATA[$F{hoursType}]]></groupExpression>
<groupHeader>
<band/>
</groupHeader>
<groupFooter>
<band height="15">
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="409" y="0" width="119" height="14"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumCostsPerWorkerandCost}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 h">
<reportElement x="316" y="0" width="93" height="14"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumHoursPerWorkerandCost}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €/h;-###0.00 €/h" isBlankWhenNull="true">
<reportElement x="238" y="0" width="78" height="14"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$F{costPerHour}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="96" y="0" width="141" height="14"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{hoursType}]]></textFieldExpression>
</textField>
<textField pattern="dd-MMM-yy" isBlankWhenNull="true">
<reportElement x="1" y="0" width="95" height="14"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.util.Date"><![CDATA[$F{date}]]></textFieldExpression>
</textField>
</band>
</groupFooter>
</group>
<background>
<band splitType="Stretch"/>
</background>
<detail>
<band/>
</detail>
<columnFooter>
<band/>
</columnFooter>
<pageFooter>
<band/>
</pageFooter>
<summary>
<band splitType="Stretch"/>
</summary>
</jasperReport>

View file

@ -7,48 +7,25 @@
<parameter name="logo" class="java.lang.String"/>
<parameter name="criteria" class="java.lang.String"/>
<parameter name="labels" class="java.lang.String"/>
<field name="workerName" class="java.lang.String"/>
<field name="date" class="java.util.Date"/>
<field name="clockStart" class="java.util.Date"/>
<field name="clockFinish" class="java.util.Date"/>
<field name="numHours" class="java.math.BigDecimal"/>
<parameter name="subReportWRL" class="java.lang.String"/>
<parameter name="subReportES" class="java.lang.String"/>
<field name="orderElementCode" class="java.lang.String"/>
<field name="descriptionValues" class="java.lang.String"/>
<field name="labels" class="java.lang.String"/>
<field name="orderName" class="java.lang.String"/>
<field name="cost" class="java.math.BigDecimal"/>
<field name="hoursType" class="java.lang.String"/>
<field name="costPerHour" class="java.math.BigDecimal"/>
<field name="orderElementName" class="java.lang.String"/>
<field name="orderCode" class="java.lang.String"/>
<variable name="sumHoursPerTask" class="java.math.BigDecimal" resetType="Group" resetGroup="Task" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<field name="listWorkReportLineDTO" class="net.sf.jasperreports.engine.JRDataSource"/>
<field name="listExpensesDTO" class="net.sf.jasperreports.engine.JRDataSource"/>
<variable name="sumTotalCosts" class="java.math.BigDecimal" resetType="Group" resetGroup="OrderCode">
<variableExpression><![CDATA[$V{sumTotalCostsByHours}.add($V{sumTotalExpenses})]]></variableExpression>
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<variable name="sumHoursPerWorker" class="java.math.BigDecimal" resetType="Group" resetGroup="Worker" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<variable name="sumTotalCostsByHours" class="java.math.BigDecimal" resetType="Group" resetGroup="OrderCode" calculation="System">
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<variable name="sumCosts" class="java.math.BigDecimal" resetType="Group" resetGroup="Worker" calculation="Sum">
<variableExpression><![CDATA[$F{cost}]]></variableExpression>
<variable name="sumTotalHours" class="java.math.BigDecimal" resetType="Group" resetGroup="OrderCode" calculation="System">
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<variable name="sumTotalCosts" class="java.math.BigDecimal" resetType="Group" resetGroup="OrderCode" calculation="Sum">
<variableExpression><![CDATA[$F{cost}]]></variableExpression>
</variable>
<variable name="sumTotalHours" class="java.math.BigDecimal" resetType="Group" resetGroup="OrderCode" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
</variable>
<variable name="sumCostsPerTask" class="java.math.BigDecimal" resetType="Group" resetGroup="Task" calculation="Sum">
<variableExpression><![CDATA[$F{cost}]]></variableExpression>
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<variable name="sumHoursPerWorkerandCost" class="java.math.BigDecimal" resetType="Group" resetGroup="HoursType Group" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<variable name="sumCostsPerWorkerandCost" class="java.math.BigDecimal" resetType="Group" resetGroup="HoursType Group" calculation="Sum">
<variableExpression><![CDATA[$F{cost}]]></variableExpression>
<variable name="sumTotalExpenses" class="java.math.BigDecimal" resetType="Group" resetGroup="OrderCode" calculation="System">
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<group name="OrderCode">
@ -75,27 +52,68 @@
</band>
</groupHeader>
<groupFooter>
<band height="35">
<band height="101">
<textField>
<reportElement x="71" y="2" width="258" height="20"/>
<reportElement x="287" y="25" width="135" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total.time.money}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="423" y="45" width="130" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumTotalExpenses}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="true" pattern="###0.00 h">
<reportElement x="287" y="5" width="135" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumTotalHours}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="423" y="65" width="130" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumTotalCosts}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="287" y="45" width="135" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total.expense.money}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="287" y="65" width="135" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total.money}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="146" y="5" width="141" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{time.spend.subtitle}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="146" y="25" width="141" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{money.spend.subtitle}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="4" y="5" width="138" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 h">
<reportElement x="329" y="2" width="93" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font isBold="true"/>
</textElement>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumTotalHours}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €;-###0.00 €">
<reportElement x="422" y="2" width="119" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font isBold="true"/>
</textElement>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumTotalCosts}]]></textFieldExpression>
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="423" y="25" width="130" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumTotalCostsByHours}]]></textFieldExpression>
</textField>
</band>
</groupFooter>
@ -103,7 +121,7 @@
<group name="Task">
<groupExpression><![CDATA[$F{orderElementCode}]]></groupExpression>
<groupHeader>
<band height="45">
<band height="126">
<textField evaluationTime="Group" evaluationGroup="Task" isBlankWhenNull="true">
<reportElement x="330" y="10" width="175" height="20"/>
<textElement>
@ -121,179 +139,28 @@
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{orderElementName}]]></textFieldExpression>
</textField>
<subreport>
<reportElement key="subreport" positionType="Float" x="2" y="31" width="490" height="47"/>
<dataSourceExpression><![CDATA[$F{listWorkReportLineDTO}]]></dataSourceExpression>
<returnValue subreportVariable="sumCostsPerTask" toVariable="sumTotalCostsByHours" calculation="Sum"/>
<returnValue subreportVariable="sumHoursPerTask" toVariable="sumTotalHours" calculation="Sum"/>
<subreportExpression class="java.lang.String"><![CDATA[$P{subReportWRL}]]></subreportExpression>
</subreport>
<subreport isUsingCache="true">
<reportElement key="subreport" positionType="Float" x="2" y="78" width="490" height="47">
<printWhenExpression><![CDATA[$F{listExpensesDTO} != null]]></printWhenExpression>
</reportElement>
<dataSourceExpression><![CDATA[$F{listExpensesDTO}]]></dataSourceExpression>
<returnValue subreportVariable="sumValuePerTask" toVariable="sumTotalExpenses" calculation="Sum"/>
<subreportExpression class="java.lang.String"><![CDATA[$P{subReportES}]]></subreportExpression>
</subreport>
</band>
</groupHeader>
<groupFooter>
<band height="30">
<textField>
<reportElement x="71" y="2" width="258" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total.task}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 h">
<reportElement x="329" y="2" width="93" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumHoursPerTask}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="422" y="2" width="119" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumCostsPerTask}]]></textFieldExpression>
</textField>
</band>
</groupFooter>
</group>
<group name="Worker">
<groupExpression><![CDATA[$F{workerName}]]></groupExpression>
<groupHeader>
<band height="50">
<textField evaluationTime="Group" evaluationGroup="Worker" pattern="" isBlankWhenNull="true">
<reportElement x="70" y="12" width="469" height="17"/>
<textElement>
<font size="11"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{workerName}]]></textFieldExpression>
</textField>
<textField>
<reportElement mode="Opaque" x="422" y="29" width="119" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.column5}]]></textFieldExpression>
</textField>
<textField>
<reportElement mode="Opaque" x="329" y="29" width="93" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.column4}]]></textFieldExpression>
</textField>
<textField>
<reportElement mode="Opaque" x="251" y="29" width="78" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.column3}]]></textFieldExpression>
</textField>
<textField>
<reportElement mode="Opaque" x="110" y="29" width="141" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.column1}]]></textFieldExpression>
</textField>
<textField>
<reportElement mode="Opaque" x="15" y="29" width="95" height="21" backcolor="#E0E4FB"/>
<box>
<pen lineWidth="1.0"/>
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font size="10" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{headers.column2}]]></textFieldExpression>
</textField>
</band>
</groupHeader>
<groupFooter>
<band height="28">
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="422" y="2" width="119" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumCosts}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="71" y="2" width="258" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle" markup="none">
<font isBold="false"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total.worker}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 h">
<reportElement x="329" y="2" width="93" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumHoursPerWorker}]]></textFieldExpression>
</textField>
</band>
</groupFooter>
</group>
<group name="Date Group">
<groupExpression><![CDATA[$F{date}]]></groupExpression>
<groupHeader>
<band/>
</groupHeader>
<groupFooter>
<band/>
</groupFooter>
</group>
<group name="HoursType Group">
<groupExpression><![CDATA[$F{hoursType}]]></groupExpression>
<groupHeader>
<band/>
</groupHeader>
<groupFooter>
<band height="15">
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="423" y="0" width="119" height="14"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumCostsPerWorkerandCost}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 h">
<reportElement x="330" y="0" width="93" height="14"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumHoursPerWorkerandCost}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €/h;-###0.00 €/h" isBlankWhenNull="true">
<reportElement x="252" y="0" width="78" height="14"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$F{costPerHour}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="110" y="0" width="141" height="14"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{hoursType}]]></textFieldExpression>
</textField>
<textField pattern="dd-MMM-yy" isBlankWhenNull="true">
<reportElement x="15" y="0" width="95" height="14"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.util.Date"><![CDATA[$F{date}]]></textFieldExpression>
</textField>
</band>
</groupFooter>
</group>
<background>
<band splitType="Stretch"/>
</background>

View file

@ -15,3 +15,14 @@ total.worker = Total per worker:
total = Project Total:
page = page
of = of
expense.subtitle = Expenses sheet
headers.expense.column1 = Date
headers.expense.column2 = Concept
headers.expense.column3 = Resource
headers.expense.column4 = Value
time.spend.subtitle = Time spend:
money.spend.subtitle = Money spend:
total.numhours = Total number of hours:
total.time.money = Because of hours:
total.expense.money = Because of expenses:
total.money = Total:

View file

@ -15,3 +15,14 @@ total.worker = Total per worker:
total = Project Total:
page = page
of = of
expense.subtitle = Hoja de gastos
headers.expense.column1 = Fecha
headers.expense.column2 = Concepto
headers.expense.column3 = Recurso
headers.expense.column4 = Valor
time.spend.subtitle = Tiempo empleado:
money.spend.subtitle = Dinero empleado:
total.numhours = Número total de horas:
total.time.money = Por causa de las horas:
total.expense.money = Por causa de los gastos:
total.money = Total:

View file

@ -349,7 +349,7 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
subItem(_("Work And Progress Per Project"),"/reports/schedulingProgressPerOrderReport.zul", "15-3-work-progress-per-project.html"),
subItem(_("Work And Progress Per Task"),"/reports/workingProgressPerTaskReport.zul", "15-informes.html"),
subItem(_("Estimated/Planned Hours Per Task"),"/reports/completedEstimatedHoursPerTask.zul", "15-informes.html"),
subItem(_("Project Costs Per Resource"),"/reports/orderCostsPerResource.zul", "15-informes.html"),
subItem(_("Project Costs"), "/reports/orderCostsPerResource.zul", "15-informes.html"),
subItem(_("Task Scheduling Status In Project"),"/reports/workingArrangementsPerOrderReport.zul","15-informes.html"),
subItem(_("Materials Needs At Date"),"/reports/timeLineMaterialReport.zul","15-informes.html"));

View file

@ -40,7 +40,6 @@ import org.libreplan.business.expensesheet.entities.ExpenseSheet;
import org.libreplan.business.expensesheet.entities.ExpenseSheetLine;
import org.libreplan.business.expensesheet.entities.ExpenseSheetLineComparator;
import org.libreplan.business.orders.daos.IOrderDAO;
import org.libreplan.business.orders.daos.IOrderElementDAO;
import org.libreplan.business.orders.daos.ISumExpensesDAO;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderElement;
@ -70,9 +69,6 @@ public class ExpenseSheetModel extends IntegrationEntityModel implements IExpens
@Autowired
private IOrderDAO orderDAO;
@Autowired
private IOrderElementDAO orderElementDAO;
@Autowired
private IExpenseSheetDAO expenseSheetDAO;

View file

@ -68,4 +68,5 @@ public interface IOrderCostsPerResourceModel {
String getSelectedCriteria();
String getSelectedLabel();
}

View file

@ -88,7 +88,8 @@ public class OrderCostsPerResourceController extends LibrePlanReportController {
result.put("endingDate", getEndingDate());
result.put("criteria", getParameterCriterions());
result.put("labels", getParameterLabels());
result.put("subReportWRL", "costWorkReportLinesReport.jasper");
result.put("subReportES", "costExpenseSheetLinesReport.jasper");
return result;
}

View file

@ -27,16 +27,20 @@ import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.joda.time.LocalDate;
import org.libreplan.business.costcategories.entities.TypeOfWorkHours;
import org.libreplan.business.expensesheet.entities.ExpenseSheetLine;
import org.libreplan.business.labels.daos.ILabelDAO;
import org.libreplan.business.labels.entities.Label;
import org.libreplan.business.orders.daos.IOrderDAO;
@ -44,7 +48,10 @@ import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderLine;
import org.libreplan.business.planner.daos.ITaskElementDAO;
import org.libreplan.business.reports.dtos.CostExpenseSheetDTO;
import org.libreplan.business.reports.dtos.OrderCostMasterDTO;
import org.libreplan.business.reports.dtos.OrderCostsPerResourceDTO;
import org.libreplan.business.reports.dtos.ReportPerOrderElementDTO;
import org.libreplan.business.resources.daos.ICriterionTypeDAO;
import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.resources.entities.CriterionType;
@ -106,54 +113,149 @@ public class OrderCostsPerResourceModel implements IOrderCostsPerResourceModel {
@Override
@Transactional(readOnly = true)
public JRDataSource getOrderReport(final List<Order> orders,
Date startingDate,
public JRDataSource getOrderReport(final List<Order> orders, Date startingDate,
Date endingDate, List<Label> labels, List<Criterion> criterions) {
reattachLabels();
// list to the master report
List<OrderCostMasterDTO> listOrderCostMasterDTO = new ArrayList<OrderCostMasterDTO>();
// list to the WorkReportLine subreport
List<OrderCostsPerResourceDTO> workingHoursPerWorkerList = orderDAO
.getOrderCostsPerResource(orders, startingDate, endingDate,
criterions);
workingHoursPerWorkerList = filteredOrderElementsByLabels(
workingHoursPerWorkerList, labels);
.getOrderCostsPerResource(orders, startingDate, endingDate, criterions);
filteredOrderElementsByLabels(workingHoursPerWorkerList, labels);
Collections.sort(workingHoursPerWorkerList);
Map<OrderElement, List<OrderCostsPerResourceDTO>> mapWRL = groupWorkReportLinesByOrderElment(workingHoursPerWorkerList);
if (workingHoursPerWorkerList.isEmpty()) {
Worker emptyWorker = createFictitiousWorker();
WorkReportLine wrl = createEmptyWorkReportLine(emptyWorker);
// list to the ExpenseSheet subreport
List<CostExpenseSheetDTO> costExpenseSheetList = orderDAO.getCostExpenseSheet(orders,
startingDate, endingDate, criterions);
filteredOrderElementsByLabels(costExpenseSheetList, labels);
Map<OrderElement, List<CostExpenseSheetDTO>> mapES = groupExpensesByOrderElment(costExpenseSheetList);
if (orders.isEmpty()) {
Order order = Order.create();
order.setName(_("All projects"));
workingHoursPerWorkerList.add(createEmptyDTO(order,
emptyWorker, wrl));
} else {
for (Order order : orders) {
workingHoursPerWorkerList.add(createEmptyDTO(order,
emptyWorker, wrl));
Set<OrderElement> listOrderElement = new HashSet<OrderElement>(mapWRL.keySet());
listOrderElement.addAll(mapES.keySet());
if (listOrderElement.isEmpty()) {
listOrderCostMasterDTO.add(createEmptyOrderCostMasterDTO());
} else {
for (OrderElement orderElement : listOrderElement) {
List<OrderCostsPerResourceDTO> listWorkReportLineDTO = mapWRL.get(orderElement);
if (listWorkReportLineDTO == null || listWorkReportLineDTO.isEmpty()) {
Order order = Order.create();
order.setName(_("All projects"));
listWorkReportLineDTO = createEmptyWorkReportLineList(order);
}
JRDataSource dsWRL = new JRBeanCollectionDataSource(listWorkReportLineDTO);
List<CostExpenseSheetDTO> listExpenseSheetDTO = mapES.get(orderElement);
JRDataSource dsES = null;
if (listExpenseSheetDTO != null && !listExpenseSheetDTO.isEmpty()) {
dsES = new JRBeanCollectionDataSource(listExpenseSheetDTO);
}
OrderCostMasterDTO orderCostMasterDTO = new OrderCostMasterDTO(orderElement, dsWRL,
dsES);
initOrderInOrderCostMasterDTO(orderCostMasterDTO, listWorkReportLineDTO,
listExpenseSheetDTO);
listOrderCostMasterDTO.add(orderCostMasterDTO);
}
}
if (workingHoursPerWorkerList != null && !workingHoursPerWorkerList.isEmpty()) {
return new JRBeanCollectionDataSource(workingHoursPerWorkerList);
if (listOrderCostMasterDTO != null && !listOrderCostMasterDTO.isEmpty()) {
Collections.sort(listOrderCostMasterDTO);
return new JRBeanCollectionDataSource(listOrderCostMasterDTO);
} else {
return new JREmptyDataSource();
}
}
private OrderCostsPerResourceDTO createEmptyDTO(Order order,
private void initOrderInOrderCostMasterDTO(OrderCostMasterDTO orderCostMasterDTO,
List<OrderCostsPerResourceDTO> listWorkReportLineDTO,
List<CostExpenseSheetDTO> listExpenseSheetDTO) {
if (listExpenseSheetDTO != null && !listExpenseSheetDTO.isEmpty()) {
Order order = listExpenseSheetDTO.get(0).getOrder();
orderCostMasterDTO.setOrderCode(order.getCode());
orderCostMasterDTO.setOrderName(order.getName());
} else if (listWorkReportLineDTO != null && !listWorkReportLineDTO.isEmpty()) {
orderCostMasterDTO.setOrderCode(listWorkReportLineDTO.get(0).getOrderCode());
orderCostMasterDTO.setOrderName(listWorkReportLineDTO.get(0).getOrderName());
}
}
private Map<OrderElement, List<OrderCostsPerResourceDTO>> groupWorkReportLinesByOrderElment(
List<OrderCostsPerResourceDTO> workingHoursPerWorkerList) {
Map<OrderElement, List<OrderCostsPerResourceDTO>> mapWRL = new HashMap<OrderElement, List<OrderCostsPerResourceDTO>>();
for (OrderCostsPerResourceDTO dto : workingHoursPerWorkerList) {
OrderElement orderElement = dto.getOrderElement();
if (mapWRL.get(orderElement) == null) {
mapWRL.put(orderElement, new ArrayList<OrderCostsPerResourceDTO>());
}
mapWRL.get(orderElement).add(dto);
}
return mapWRL;
}
private Map<OrderElement, List<CostExpenseSheetDTO>> groupExpensesByOrderElment(
List<CostExpenseSheetDTO> costExpenseSheetList) {
Map<OrderElement, List<CostExpenseSheetDTO>> mapES = new HashMap<OrderElement, List<CostExpenseSheetDTO>>();
for (CostExpenseSheetDTO dto : costExpenseSheetList) {
OrderElement orderElement = dto.getOrderElement();
if (mapES.get(orderElement) == null) {
mapES.put(orderElement, new ArrayList<CostExpenseSheetDTO>());
}
mapES.get(orderElement).add(dto);
}
return mapES;
}
private List<OrderCostsPerResourceDTO> createEmptyWorkReportLineList(Order order) {
List<OrderCostsPerResourceDTO> listWorkReportLineDTO = new ArrayList<OrderCostsPerResourceDTO>();
Worker emptyWorker = createFictitiousWorker();
WorkReportLine wrl = createEmptyWorkReportLine(emptyWorker);
listWorkReportLineDTO.add(createEmptyOrderCostsPerResourceDTO(order, emptyWorker, wrl));
return listWorkReportLineDTO;
}
private OrderCostsPerResourceDTO createEmptyOrderCostsPerResourceDTO(Order order,
Worker emptyWorker, WorkReportLine wrl) {
OrderCostsPerResourceDTO emptyDTO = new OrderCostsPerResourceDTO(
emptyWorker, wrl);
OrderCostsPerResourceDTO emptyDTO = new OrderCostsPerResourceDTO(emptyWorker, wrl);
emptyDTO.setOrderName(order.getName());
emptyDTO.setOrderCode(order.getCode());
emptyDTO.setCost(new BigDecimal(0));
return emptyDTO;
}
private List<CostExpenseSheetDTO> createEmptyExpenseSheetLineList(Order order) {
List<CostExpenseSheetDTO> listES = new ArrayList<CostExpenseSheetDTO>();
listES.add(createEmptyExpenseSheetDTO(order));
return listES;
}
private CostExpenseSheetDTO createEmptyExpenseSheetDTO(OrderElement orderElement) {
ExpenseSheetLine emptyBean = ExpenseSheetLine.create(BigDecimal.ZERO, "Expense concept",
new LocalDate(), orderElement);
CostExpenseSheetDTO emptyDTO = new CostExpenseSheetDTO(emptyBean);
return emptyDTO;
}
private OrderCostMasterDTO createEmptyOrderCostMasterDTO() {
// create empty order
Order order = Order.create();
order.setName(_("All projects"));
// create empty subreport to expense sheets
JRDataSource emptyES = new JRBeanCollectionDataSource(
createEmptyExpenseSheetLineList(order));
// create empty subreport to work report lines
JRDataSource emptyWRL = new JRBeanCollectionDataSource(createEmptyWorkReportLineList(order));
OrderCostMasterDTO emptyDTO = new OrderCostMasterDTO(order, emptyWRL, emptyES);
return emptyDTO;
}
private void loadAllOrders() {
this.allOrders = orderDAO.getOrders();
Collections.sort(this.allOrders);
@ -222,22 +324,19 @@ public class OrderCostsPerResourceModel implements IOrderCostsPerResourceModel {
}
@Transactional(readOnly = true)
private List<OrderCostsPerResourceDTO> filteredOrderElementsByLabels(
List<OrderCostsPerResourceDTO> workingHoursPerWorkerList,
List<Label> labels) {
if (labels != null && !labels.isEmpty()) {
List<OrderCostsPerResourceDTO> result = new ArrayList<OrderCostsPerResourceDTO>();
for (OrderCostsPerResourceDTO dto : workingHoursPerWorkerList) {
List<Label> inheritedLabels = getInheritedLabels(dto
.getOrderElement());
private void filteredOrderElementsByLabels(
List<? extends ReportPerOrderElementDTO> listExpenses, List<Label> labels) {
List<ReportPerOrderElementDTO> listExpensesCopy = new ArrayList<ReportPerOrderElementDTO>(
listExpenses);
if (containsAny(labels, inheritedLabels)) {
result.add(dto);
if (labels != null && !labels.isEmpty()) {
for (ReportPerOrderElementDTO dto : listExpensesCopy) {
List<Label> inheritedLabels = getInheritedLabels(dto.getOrderElement());
if (!containsAny(labels, inheritedLabels)) {
listExpenses.remove(dto);
}
}
return result;
} else {
return workingHoursPerWorkerList;
}
}
@ -319,8 +418,7 @@ public class OrderCostsPerResourceModel implements IOrderCostsPerResourceModel {
}
}
private static Set<Criterion> getDirectCriterions(
CriterionType criterionType) {
private static Set<Criterion> getDirectCriterions(CriterionType criterionType) {
Set<Criterion> criterions = new HashSet<Criterion>();
for (Criterion criterion : criterionType.getCriterions()) {
if (criterion.getParent() == null) {
@ -341,8 +439,7 @@ public class OrderCostsPerResourceModel implements IOrderCostsPerResourceModel {
}
private List<CriterionType> getCriterionTypes() {
return criterionTypeDAO
.getCriterionTypesByResources(applicableResources);
return criterionTypeDAO.getCriterionTypesByResources(applicableResources);
}
@Override
@ -376,12 +473,10 @@ public class OrderCostsPerResourceModel implements IOrderCostsPerResourceModel {
Iterator<Label> iterator = this.selectedLabels.iterator();
if (iterator.hasNext()) {
this.selectedLabel = new String();
this.selectedLabel = this.selectedLabel.concat(iterator.next()
.getName());
this.selectedLabel = this.selectedLabel.concat(iterator.next().getName());
}
while (iterator.hasNext()) {
this.selectedLabel = this.selectedLabel.concat(", "
+ iterator.next().getName());
this.selectedLabel = this.selectedLabel.concat(", " + iterator.next().getName());
}
hasChangeLabels = false;
}
@ -398,8 +493,7 @@ public class OrderCostsPerResourceModel implements IOrderCostsPerResourceModel {
Iterator<Criterion> iterator = this.selectedCriterions.iterator();
if (iterator.hasNext()) {
this.selectedCriteria = new String();
this.selectedCriteria = this.selectedCriteria.concat(iterator
.next().getName());
this.selectedCriteria = this.selectedCriteria.concat(iterator.next().getName());
}
while (iterator.hasNext()) {
this.selectedCriteria = this.selectedCriteria.concat(", "
@ -409,5 +503,4 @@ public class OrderCostsPerResourceModel implements IOrderCostsPerResourceModel {
}
return selectedCriteria;
}
}