ItEr41S14CUInformeTraballadorCustesHoraItEr40S19: Order costs per resource report

This commit is contained in:
Lorenzo Tilve 2010-01-08 12:01:34 +01:00 committed by Javier Moran Rua
parent 9225d13df6
commit 217f702d6f
15 changed files with 1107 additions and 17 deletions

View file

@ -20,16 +20,22 @@
package org.navalplanner.business.costcategories.daos;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.joda.time.LocalDate;
import org.navalplanner.business.common.daos.GenericDAOHibernate;
import org.navalplanner.business.costcategories.entities.CostCategory;
import org.navalplanner.business.costcategories.entities.HourCost;
import org.navalplanner.business.costcategories.entities.ResourcesCostCategoryAssignment;
import org.navalplanner.business.resources.entities.Resource;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
/**
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
@ -39,7 +45,6 @@ import org.springframework.stereotype.Repository;
public class CostCategoryDAO extends GenericDAOHibernate<CostCategory, Long>
implements ICostCategoryDAO {
@Override
public List<CostCategory> findActive() {
@ -50,4 +55,25 @@ public class CostCategoryDAO extends GenericDAOHibernate<CostCategory, Long>
list.addAll(c.list());
return list;
}
@Transactional(readOnly = true)
public static BigDecimal getPriceByResourceDateAndHourType(
Resource resource,
LocalDate date, String type) {
for (ResourcesCostCategoryAssignment each : resource
.getResourcesCostCategoryAssignments()) {
if ((date.isAfter(each.getInitDate()))
&& (!date.isBefore(each.getInitDate()))) {
for (HourCost hourCost : each.getCostCategory().getHourCosts()) {
if (hourCost.isActiveAtDate(date)
&& hourCost.getType().getCode().equals(type)) {
return hourCost.getPriceCost();
}
}
}
}
return null;
}
}

View file

@ -109,6 +109,14 @@ public class HourCost extends BaseEntity {
category.addHourCost(this);
}
public boolean isActiveAtDate(LocalDate date) {
if ((date.isAfter(this.getInitDate()))
&& (!date.isBefore(this.getInitDate()))) {
return true;
}
return false;
}
@AssertTrue(message="The end date cannot be before the init date")
public boolean checkPositiveTimeInterval() {
if (endDate == null) {

View file

@ -97,4 +97,5 @@ public class ResourcesCostCategoryAssignment extends BaseEntity {
}
return (endDate.isAfter(initDate) || initDate.equals(endDate));
}
}

View file

@ -20,22 +20,32 @@
package org.navalplanner.business.orders.daos;
import java.util.Date;
import java.util.List;
import org.navalplanner.business.common.daos.IGenericDAO;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.reports.dtos.OrderCostsPerResourceDTO;
/**
* Contract for {@link OrderDAO}
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
public interface IOrderDAO extends IGenericDAO<Order, Long> {
/**
* Gets all the orders.
*
* @return A {@link List} of {@link Order} objects
*/
List<Order> getOrders();
/**
* Builds contents for OrderCostsPerResource report
* @return A {@link List} of {@link OrderCostsPerResourceDTO} objects for
* reporting
*/
List<OrderCostsPerResourceDTO> getOrderCostsPerResource(List<Order> orders,
Date startingDate, Date endingDate);
}

View file

@ -20,21 +20,32 @@
package org.navalplanner.business.orders.daos;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.joda.time.LocalDate;
import org.navalplanner.business.common.daos.GenericDAOHibernate;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.costcategories.daos.CostCategoryDAO;
import org.navalplanner.business.costcategories.daos.ITypeOfWorkHoursDAO;
import org.navalplanner.business.costcategories.entities.TypeOfWorkHours;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.orders.entities.TaskSource;
import org.navalplanner.business.planner.daos.ITaskSourceDAO;
import org.navalplanner.business.reports.dtos.OrderCostsPerResourceDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
/**
* Dao for {@link Order}
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
@Repository
@Scope(BeanDefinition.SCOPE_SINGLETON)
@ -44,6 +55,9 @@ public class OrderDAO extends GenericDAOHibernate<Order, Long> implements
@Autowired
private ITaskSourceDAO taskSourceDAO;
@Autowired
private ITypeOfWorkHoursDAO typeOfWorkHoursDAO;
@Override
public List<Order> getOrders() {
return list(Order.class);
@ -59,4 +73,69 @@ public class OrderDAO extends GenericDAOHibernate<Order, Long> implements
super.remove(id);
}
private boolean isOrderNameContained(String code, List<Order> orders) {
for (Order each:orders) {
if (each.getCode().equals(code)) {
return true;
}
}
return false;
}
@Override
@Transactional(readOnly = true)
public List<OrderCostsPerResourceDTO> getOrderCostsPerResource(
List<Order> orders, Date startingDate, Date endingDate) {
String orderStrQuery = "FROM Order order ";
Query orderQuery = getSession().createQuery(orderStrQuery);
List<Order> orderList = orderQuery.list();
String strQuery = "SELECT new org.navalplanner.business.reports.dtos.OrderCostsPerResourceDTO(worker, wrl) "
+ "FROM Worker worker, WorkReportLine wrl "
+ "LEFT OUTER JOIN wrl.resource resource "
+ "WHERE resource.id = worker.id ";
// Order by
strQuery += "ORDER BY worker.id, wrl.date";
Query query = getSession().createQuery(strQuery);
List<OrderCostsPerResourceDTO> list = query.list();
List<OrderCostsPerResourceDTO> filteredList = new ArrayList<OrderCostsPerResourceDTO>();
for (OrderCostsPerResourceDTO each : list) {
Order order = each.getOrderElement().getOrder();
// Apply filtering
if (orders.isEmpty()
|| isOrderNameContained(order.getCode(), orders)) {
// Attach ordername value
each.setOrderName(order.getName());
// Attach calculated pricePerHour
BigDecimal pricePerHour = CostCategoryDAO
.getPriceByResourceDateAndHourType(each.getWorker(),
new LocalDate(each.getDate()), each
.getHoursType());
if (pricePerHour == null) {
for (TypeOfWorkHours defaultprice : typeOfWorkHoursDAO
.list(TypeOfWorkHours.class)) {
if (defaultprice.getCode().equals(each.getHoursType())) {
pricePerHour = defaultprice.getDefaultPrice();
}
}
}
each.setCostPerHour(pricePerHour);
each.setCost(each.getCostPerHour().multiply(
new BigDecimal(each.getNumHours())));
filteredList.add(each);
}
}
return filteredList;
}
}

View file

@ -234,6 +234,11 @@ public class Order extends OrderLineGroup {
return true;
}
@Override
public Order getOrder() {
return this;
}
@Override
public OrderTemplate createTemplate() {
return OrderTemplate.create(this);

View file

@ -718,15 +718,13 @@ public abstract class OrderElement extends BaseEntity implements
}
public Order getOrder() {
if (this instanceof Order) {
return (Order) this;
Order order;
try {
order = parent.getOrder();
} catch (Exception e) {
throw new RuntimeException(e);
}
if (parent != null) {
return parent.getOrder();
}
return null;
return order;
}
@Valid

View file

@ -0,0 +1,217 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.business.reports.dtos;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Set;
import org.navalplanner.business.labels.entities.Label;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.business.workreports.entities.WorkReportLine;
import org.navalplanner.business.workreports.valueobjects.DescriptionValue;
public class OrderCostsPerResourceDTO implements
Comparable<OrderCostsPerResourceDTO> {
private String workerName;
private Date date;
private Date clockStart;
private Date clockFinish;
private Integer numHours;
private String orderElementCode;
private String descriptionValues;
private String labels;
private String hoursType;
// Attached outside the DTO
private BigDecimal cost;
// Attached outside the DTO
private BigDecimal costPerHour;
// Attached outside the DTO
private String orderName;
private OrderElement orderElement;
private Worker worker;
public OrderCostsPerResourceDTO(Worker worker,
WorkReportLine workReportLine) {
this.workerName = worker.getName();
this.date = workReportLine.getDate();
this.clockStart = workReportLine.getClockStart();
this.clockFinish = workReportLine.getClockFinish();
this.numHours = workReportLine.getNumHours();
this.descriptionValues = descriptionValuesAsString(workReportLine.getDescriptionValues());
this.labels = labelsAsString(workReportLine.getLabels());
this.hoursType = workReportLine.getTypeOfWorkHours().getCode();
this.orderElement = workReportLine.getOrderElement();
this.orderElementCode = workReportLine.getOrderElement().getCode();
this.worker = worker;
}
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 Integer getNumHours() {
return numHours;
}
public void setNumHours(Integer numHours) {
this.numHours = numHours;
}
public Date getClockStart() {
return clockStart;
}
public void setClockStart(Date clockStart) {
this.clockStart = clockStart;
}
public Date getClockFinish() {
return clockFinish;
}
public void setClockFinish(Date 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 getOrderElementCode() {
return orderElementCode;
}
public void setOrderElementCode(String orderElementCode) {
this.orderElementCode = orderElementCode;
}
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 getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
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 OrderElement getOrderElement() {
return orderElement;
}
public void setOrderElement(OrderElement orderElement) {
this.orderElement = orderElement;
}
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(OrderCostsPerResourceDTO o) {
String comparator = this.orderName + this.orderElementCode;
return comparator.compareToIgnoreCase(o.orderName
+ o.getOrderElementCode());
}
}

View file

@ -0,0 +1,313 @@
<?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">
<style name="Title" isDefault="false" fontName="Arial" fontSize="26" isBold="true" pdfFontName="Helvetica-Bold"/>
<style name="SubTitle" isDefault="false" forecolor="#666666" fontName="Arial" fontSize="18"/>
<style name="Column header" isDefault="false" forecolor="#666666" fontName="Arial" fontSize="12" isBold="true"/>
<style name="Detail" isDefault="false" fontName="Arial" fontSize="12"/>
<subDataset name="dataset1"/>
<parameter name="startingDate" class="java.util.Date"/>
<parameter name="endingDate" class="java.util.Date"/>
<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.lang.Integer"/>
<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.lang.Integer" resetType="Group" resetGroup="Task" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<initialValueExpression><![CDATA[new Integer(0)]]></initialValueExpression>
</variable>
<variable name="sumHoursPerWorker" class="java.lang.Integer" resetType="Group" resetGroup="Worker" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<initialValueExpression><![CDATA[new Integer(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="sumTotalCosts" class="java.math.BigDecimal" resetType="Group" resetGroup="OrderName" calculation="Sum">
<variableExpression><![CDATA[$F{cost}]]></variableExpression>
</variable>
<variable name="sumTotalHours" class="java.lang.Integer" resetType="Group" resetGroup="OrderName" 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.lang.Integer" resetType="Group" resetGroup="CostPerHour" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<initialValueExpression><![CDATA[new Integer(0)]]></initialValueExpression>
</variable>
<variable name="sumCostsPerWorkerandCost" class="java.math.BigDecimal" resetType="Group" resetGroup="CostPerHour" calculation="Sum">
<variableExpression><![CDATA[$F{cost}]]></variableExpression>
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<group name="OrderName">
<groupExpression><![CDATA[$F{orderName}]]></groupExpression>
<groupHeader>
<band height="36">
<textField evaluationTime="Group" evaluationGroup="OrderName" isBlankWhenNull="true">
<reportElement x="2" y="0" width="551" height="26"/>
<textElement verticalAlignment="Middle">
<font size="12" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{orderName}]]></textFieldExpression>
</textField>
<line>
<reportElement x="2" y="26" width="553" height="1"/>
</line>
</band>
</groupHeader>
<groupFooter>
<band height="38">
<staticText>
<reportElement x="70" y="5" width="258" height="22"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif" size="10" isBold="true"/>
</textElement>
<text><![CDATA[ORDER TOTALS:]]></text>
</staticText>
<textField pattern="###0 h">
<reportElement x="328" y="5" width="93" height="22"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif" isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{sumTotalHours}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €;-###0.00 €">
<reportElement x="421" y="5" width="117" height="22"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif" isBold="true"/>
</textElement>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumTotalCosts}]]></textFieldExpression>
</textField>
</band>
</groupFooter>
</group>
<group name="Task">
<groupExpression><![CDATA[$F{orderElementCode}]]></groupExpression>
<groupHeader>
<band height="23">
<textField evaluationTime="Group" evaluationGroup="Task" isBlankWhenNull="true">
<reportElement x="34" y="0" width="505" height="20"/>
<textElement>
<font size="12"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{orderElementCode}]]></textFieldExpression>
</textField>
<line>
<reportElement x="34" y="20" width="504" height="1"/>
</line>
</band>
</groupHeader>
<groupFooter>
<band height="31">
<staticText>
<reportElement x="70" y="9" width="258" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif" size="10" isBold="true"/>
</textElement>
<text><![CDATA[Totals per task:]]></text>
</staticText>
<textField pattern="###0 h">
<reportElement x="328" y="9" width="93" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif"/>
</textElement>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{sumHoursPerTask}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="421" y="9" width="118" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif"/>
</textElement>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumCostsPerTask}]]></textFieldExpression>
</textField>
</band>
</groupFooter>
</group>
<group name="Worker">
<groupExpression><![CDATA[$F{workerName}]]></groupExpression>
<groupHeader>
<band height="38">
<textField evaluationTime="Group" evaluationGroup="Worker" pattern="" isBlankWhenNull="true">
<reportElement x="70" y="0" width="469" height="17"/>
<textElement>
<font size="11"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{workerName}]]></textFieldExpression>
</textField>
<staticText>
<reportElement style="Column header" mode="Opaque" x="422" y="17" width="119" height="21" backcolor="#E0E4FB"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif" size="10" isBold="true"/>
</textElement>
<text><![CDATA[Cost ]]></text>
</staticText>
<staticText>
<reportElement style="Column header" mode="Opaque" x="329" y="17" width="93" height="21" backcolor="#E0E4FB"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif" size="10" isBold="true"/>
</textElement>
<text><![CDATA[Hours ]]></text>
</staticText>
<staticText>
<reportElement style="Column header" mode="Opaque" x="251" y="17" width="78" height="21" backcolor="#E0E4FB"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif" size="10" isBold="true"/>
</textElement>
<text><![CDATA[Salary ]]></text>
</staticText>
<staticText>
<reportElement style="Column header" mode="Opaque" x="71" y="17" width="180" height="21" backcolor="#E0E4FB"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif" size="10" isBold="true"/>
</textElement>
<text><![CDATA[Type of hours ]]></text>
</staticText>
</band>
</groupHeader>
<groupFooter>
<band height="22">
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="422" y="2" width="118" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif"/>
</textElement>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumCosts}]]></textFieldExpression>
</textField>
<textField pattern="###0 h">
<reportElement x="328" y="2" width="93" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif"/>
</textElement>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{sumHoursPerWorker}]]></textFieldExpression>
</textField>
<staticText>
<reportElement x="70" y="2" width="258" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif" isBold="false"/>
</textElement>
<text><![CDATA[Totals per worker:]]></text>
</staticText>
</band>
</groupFooter>
</group>
<group name="CostPerHour">
<groupExpression><![CDATA[$F{costPerHour}]]></groupExpression>
<groupHeader>
<band/>
</groupHeader>
<groupFooter>
<band height="15">
<textField pattern="###0 h">
<reportElement x="328" y="1" width="93" height="14"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif"/>
</textElement>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{sumHoursPerWorkerandCost}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<reportElement x="422" y="1" width="117" height="14"/>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="SansSerif"/>
</textElement>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumCostsPerWorkerandCost}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €/h;-###0.00 €/h" isBlankWhenNull="true">
<reportElement x="250" y="1" width="78" height="14"/>
<textElement textAlignment="Right">
<font fontName="SansSerif"/>
</textElement>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$F{costPerHour}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="70" y="1" width="180" height="14"/>
<textElement textAlignment="Right">
<font fontName="SansSerif"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{hoursType}]]></textFieldExpression>
</textField>
</band>
</groupFooter>
</group>
<background>
<band splitType="Stretch"/>
</background>
<title>
<band height="94" splitType="Stretch">
<staticText>
<reportElement style="Title" x="0" y="13" width="263" height="33"/>
<textElement verticalAlignment="Middle">
<font fontName="SansSerif"/>
</textElement>
<text><![CDATA[Order report]]></text>
</staticText>
<staticText>
<reportElement style="SubTitle" x="34" y="46" width="240" height="22"/>
<textElement>
<font fontName="SansSerif"/>
</textElement>
<text><![CDATA[Costs per Resource]]></text>
</staticText>
<image scaleImage="RealHeight">
<reportElement x="316" y="3" width="237" height="65"/>
<imageExpression class="java.lang.String"><![CDATA["logos/navalpro_logo.gif"]]></imageExpression>
</image>
</band>
</title>
<pageHeader>
<band splitType="Stretch"/>
</pageHeader>
<columnHeader>
<band splitType="Stretch"/>
</columnHeader>
<detail>
<band splitType="Stretch"/>
</detail>
<columnFooter>
<band height="34" splitType="Stretch">
<line>
<reportElement positionType="FixRelativeToBottom" x="0" y="3" width="555" height="1"/>
<graphicElement>
<pen lineWidth="0.5" lineColor="#999999"/>
</graphicElement>
</line>
</band>
</columnFooter>
<pageFooter>
<band height="20" splitType="Stretch">
<textField>
<reportElement style="Column header" x="433" y="0" width="80" height="20"/>
<textElement textAlignment="Right">
<font fontName="SansSerif" size="10" isBold="false"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA["Page "+$V{PAGE_NUMBER}+" of"]]></textFieldExpression>
</textField>
<textField evaluationTime="Report">
<reportElement style="Column header" x="513" y="0" width="40" height="20"/>
<textElement>
<font fontName="SansSerif" size="10" isBold="false"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[" " + $V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
<textField pattern="EEEEE dd MMMMM yyyy">
<reportElement style="Column header" x="0" y="0" width="197" height="20"/>
<textElement>
<font fontName="SansSerif" size="10" isBold="false"/>
</textElement>
<textFieldExpression class="java.util.Date"><![CDATA[new java.util.Date()]]></textFieldExpression>
</textField>
</band>
</pageFooter>
<summary>
<band splitType="Stretch"/>
</summary>
</jasperReport>

View file

@ -229,13 +229,11 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
subItem(_("Manage user accounts"), "/users/users.zul",""),
subItem(_("Manage external companies"), "/externalcompanies/externalcompanies.zul",""));
}
topItem(_("Reports"), "", "",
subItem(_("Hours worked per worker"),
"/reports/hoursWorkedPerWorkerReport.zul", ""),
subItem(_("Completed estimated hours per task"),
"/reports/completedEstimatedHoursPerTask.zul", ""),
subItem(_("Working progress per task"),
"/reports/workingProgressPerTaskReport.zul", ""));
topItem(_("Reports"), "", "",
subItem(_("Hours worked per worker"),"/reports/hoursWorkedPerWorkerReport.zul", ""),
subItem(_("Completed estimated hours"),"/reports/completedEstimatedHoursPerTask.zul", ""),
subItem(_("Working progress per task"),"/reports/workingProgressPerTaskReport.zul", ""),
subItem(_("Order costs per resource"),"/reports/orderCostsPerResource.zul", ""));
}
private Vbox getRegisteredItemsInsertionPoint() {

View file

@ -0,0 +1,22 @@
package org.navalplanner.web.reports;
import java.util.Date;
import java.util.List;
import net.sf.jasperreports.engine.JRDataSource;
import org.navalplanner.business.orders.entities.Order;
/**
*
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*
*/
public interface IOrderCostsPerResourceModel {
JRDataSource getOrderReport(List<Order> orders, Date startingDate,
Date endingDate);
List<Order> getOrders();
}

View file

@ -0,0 +1,126 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.reports;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sf.jasperreports.engine.JRDataSource;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.web.common.components.ExtendedJasperreport;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Toolbarbutton;
/**
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
public class OrderCostsPerResourceController extends GenericForwardComposer {
private IOrderCostsPerResourceModel orderCostsPerResourceModel;
private OrderCostsPerResourceReport orderCostsPerResourceReport;
private Listbox lbOrders;
private Datebox startingDate;
private Datebox endingDate;
private ComboboxOutputFormat outputFormat;
private Hbox URItext;
private Toolbarbutton URIlink;
private static final String HTML = "html";
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
comp.setVariable("controller", this, true);
}
public List<Order> getOrders() {
return orderCostsPerResourceModel.getOrders();
}
public void showReport(ExtendedJasperreport report) {
final String type = outputFormat.getOutputFormat();
orderCostsPerResourceReport = new OrderCostsPerResourceReport(report);
orderCostsPerResourceReport.setDatasource(getDataSource());
orderCostsPerResourceReport.setParameters(getParameters());
String URI = orderCostsPerResourceReport.show(type);
if (type.equals(HTML)) {
URItext.setStyle("display: none");
Executions.getCurrent().sendRedirect(URI, "_blank");
} else {
URItext.setStyle("display: inline");
URIlink.setHref(URI);
}
}
private JRDataSource getDataSource() {
return orderCostsPerResourceModel.getOrderReport(getSelectedOrders(),
getStartingDate(), getEndingDate());
}
private Map<String, Object> getParameters() {
Map<String, Object> result = new HashMap<String, Object>();
result.put("startingDate", getStartingDate());
result.put("endingDate", getEndingDate());
return result;
}
private List<Order> getSelectedOrders() {
List<Order> result = new ArrayList<Order>();
final Set<Listitem> listItems = lbOrders.getSelectedItems();
for (Listitem each: listItems) {
result.add((Order) each.getValue());
}
return result;
}
private Date getStartingDate() {
return startingDate.getValue();
}
private Date getEndingDate() {
return endingDate.getValue();
}
}

View file

@ -0,0 +1,119 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.reports;
import static org.navalplanner.web.I18nHelper._;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.navalplanner.business.costcategories.entities.TypeOfWorkHours;
import org.navalplanner.business.orders.daos.IOrderDAO;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.orders.entities.OrderLine;
import org.navalplanner.business.reports.dtos.OrderCostsPerResourceDTO;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.business.workreports.entities.WorkReportLine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* Lorenzo Tilve Álvaro <ltilve@igalia.com>
*
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class OrderCostsPerResourceModel implements IOrderCostsPerResourceModel {
@Autowired
private IOrderDAO orderDAO;
@Transactional(readOnly = true)
public JRDataSource getOrderReport(List<Order> orders, Date startingDate,
Date endingDate) {
List<OrderCostsPerResourceDTO> workingHoursPerWorkerList = orderDAO
.getOrderCostsPerResource(orders, startingDate, endingDate);
Collections.sort(workingHoursPerWorkerList);
if (workingHoursPerWorkerList.isEmpty()) {
Worker emptyWorker = createFictitiousWorker();
WorkReportLine wrl = createEmptyWorkReportLine(emptyWorker);
if (orders.isEmpty()) {
Order order = Order.create();
order.setName(_("All orders"));
orders.add(order);
}
for (Order order : orders) {
OrderCostsPerResourceDTO emptyDTO = new OrderCostsPerResourceDTO(
emptyWorker, wrl);
emptyDTO.setOrderName(order.getName());
emptyDTO.setCost(new BigDecimal(0));
workingHoursPerWorkerList.add(emptyDTO);
}
}
if (workingHoursPerWorkerList != null && !workingHoursPerWorkerList.isEmpty()) {
return new JRBeanCollectionDataSource(workingHoursPerWorkerList);
} else {
return new JREmptyDataSource();
}
}
@Override
@Transactional(readOnly = true)
public List<Order> getOrders() {
return orderDAO.getOrders();
}
private WorkReportLine createEmptyWorkReportLine(Worker worker) {
OrderLine leaf = OrderLine.create();
leaf.setCode(_("All order tasks"));
TypeOfWorkHours w = TypeOfWorkHours.create();
w.setDefaultPrice(new BigDecimal(0));
WorkReportLine wrl = new WorkReportLine();
wrl.setNumHours(0);
wrl.setTypeOfWorkHours(w);
wrl.setResource(worker);
wrl.setOrderElement(leaf);
return wrl;
}
private Worker createFictitiousWorker() {
Worker unnasigned = new Worker();
unnasigned.setFirstName(_("Total dedication"));
unnasigned.setSurname(" ");
return unnasigned;
}
}

View file

@ -0,0 +1,32 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.reports;
import org.navalplanner.web.common.components.ExtendedJasperreport;
public class OrderCostsPerResourceReport extends NavalplannerReport {
public OrderCostsPerResourceReport(ExtendedJasperreport report) {
report.setSrc("orderCostsPerResourceReport.jasper");
setReport(report);
}
}

View file

@ -0,0 +1,136 @@
<!--
This file is part of ###PROJECT_NAME###
Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
Desenvolvemento Tecnolóxico de Galicia
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<?page id="reports"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<?init class="org.zkoss.zk.ui.util.Composition" arg0="/common/layout/template.zul"?>
<?link rel="stylesheet" type="text/css" href="/common/css/navalpro_v01.css"?>
<?link rel="stylesheet" type="text/css" href="/common/css/navalpro_zk.css"?>
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<?component name="combobox_output_format" macroURI="combobox_output_format.zul"
class="org.navalplanner.web.reports.ComboboxOutputFormat" ?>
<?component name="extendedjasperreport"
class="org.navalplanner.web.common.components.ExtendedJasperreport"
extends="jasperreport" ?>
<zk>
<window self="@{define(content)}"
apply="org.navalplanner.web.reports.OrderCostsPerResourceController"
title="Order costs per resource">
<tabbox>
<tabs>
<tab label="${i18n:_('Select report data')}" />
</tabs>
<tabpanels>
<tabpanel>
<!-- Select output format -->
<panel title="${i18n:_('Dates')}" border="normal"
style="overflow:auto;display:none;" >
<panelchildren>
<grid width="600px">
<columns>
<column width="200px" />
<column />
</columns>
<rows>
<row>
<label value="${i18n:_('Start date:')}" />
<datebox id="startingDate" />
</row>
<row>
<label value="${i18n:_('End date:')}" />
<datebox id="endingDate" />
</row>
</rows>
</grid>
</panelchildren>
</panel>
<!-- Select output format -->
<panel title="${i18n:_('Orders')}"
border="normal"
style="overflow:auto">
<panelchildren>
<listbox id="lbOrders"
multiple="true"
model="@{controller.orders}">
<listhead>
<listheader label="${i18n:_('Name')}" sort="auto(name)" />
<listheader label="${i18n:_('Code')}" sort="auto(code)" />
<listheader label="${i18n:_('Start date')}" sort="auto(initDate)" />
</listhead>
<listitem self="@{each='order'}" value="@{order}">
<listcell label="@{order.name}" />
<listcell label="@{order.code}" />
<listcell label="@{order.initDate, converter='org.navalplanner.web.common.typeconverters.DateConverter'}" />
</listitem>
</listbox>
</panelchildren>
</panel>
<!-- Select output format -->
<panel title="${i18n:_('Format')}" border="normal"
style="overflow:auto">
<panelchildren>
<grid width="600px">
<columns>
<column width="200px" />
<column />
</columns>
<rows>
<row>
<label value="${i18n:_('Output format:')}" />
<combobox_output_format id="outputFormat" />
</row>
</rows>
</grid>
</panelchildren>
</panel>
</tabpanel>
</tabpanels>
</tabbox>
<hbox style="display: none" id="URItext">
<label value="${i18n:_('Click on ')}" />
<toolbarbutton id="URIlink" class="z-label" zclass="z-label"
label="${i18n:_('direct link')}" />
<label value="${i18n:_(' to go to output directly')}" />
</hbox>
<separator spacing="10px" orient="horizontal"/>
<button label="Show" onClick="controller.showReport(report)" />
<extendedjasperreport style="display: none" id="report" />
</window>
</zk>