Merge branch 'work-reports-effort-duration'

This commit is contained in:
Manuel Rego Casasnovas 2011-09-09 09:01:50 +02:00
commit 2dc0274bfc
35 changed files with 467 additions and 360 deletions

View file

@ -121,10 +121,10 @@ public interface IOrderElementDAO extends IIntegrationEntityDAO<OrderElement> {
boolean isAlreadyInUseThisOrAnyOfItsChildren(OrderElement orderElement);
void updateRelatedSumChargedHoursWithWorkReportLineSet(
void updateRelatedSumChargedEffortWithWorkReportLineSet(
Set<WorkReportLine> workReportLineSet) throws InstanceNotFoundException;
void updateRelatedSumChargedHoursWithDeletedWorkReportLineSet(
void updateRelatedSumChargedEffortWithDeletedWorkReportLineSet(
Set<WorkReportLine> workReportLineSet) throws InstanceNotFoundException;
/**

View file

@ -176,8 +176,7 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
}
each.setCostPerHour(pricePerHour);
each.setCost(each.getCostPerHour().multiply(
new BigDecimal(each.getNumHours())));
each.setCost(each.getCostPerHour().multiply(each.getNumHours()));
filteredList.add(each);
}
}

View file

@ -46,6 +46,7 @@ import org.navalplanner.business.orders.entities.SchedulingDataForVersion;
import org.navalplanner.business.orders.entities.TaskSource;
import org.navalplanner.business.planner.daos.ITaskSourceDAO;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workreports.daos.IWorkReportDAO;
import org.navalplanner.business.workreports.daos.IWorkReportLineDAO;
import org.navalplanner.business.workreports.entities.WorkReport;
@ -150,9 +151,12 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement>
@Override
@Transactional(readOnly = true)
public BigDecimal getHoursAdvancePercentage(OrderElement orderElement) {
final int totalChargedHours = orderElement.getSumChargedHours() != null ? orderElement
.getSumChargedHours().getTotalChargedHours() : 0;
BigDecimal assignedHours = new BigDecimal(totalChargedHours).setScale(2);
final EffortDuration totalChargedEffort = orderElement
.getSumChargedEffort() != null ? orderElement
.getSumChargedEffort().getTotalChargedEffort() : EffortDuration
.zero();
BigDecimal assignedHours = totalChargedEffort
.toHoursAsDecimalWithScale(2);
BigDecimal estimatedHours = new BigDecimal(orderElement.getWorkHours())
.setScale(2);
@ -431,46 +435,49 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement>
return false;
}
private void updateRelatedSumChargedHoursWithWorkReportLine(
private void updateRelatedSumChargedEffortWithWorkReportLine(
final WorkReportLine workReportLine,
Map<Long, Integer> relationOrderElementIdAndIndirectChargedHours)
Map<Long, EffortDuration> relationOrderElementIdAndIndirectChargedEffort)
throws InstanceNotFoundException {
OrderElement orderElement = find(workReportLine.getOrderElement().getId());
Integer hours = workReportLine.getNumHours();
Integer differenceOfHours;
EffortDuration effort = workReportLine.getEffort();
EffortDuration differenceOfEffort;
if(workReportLine.isNewObject()) {
differenceOfHours = hours;
differenceOfEffort = effort;
}
else {
//the line already exists, we have to get the old value for numHours
Integer oldNumHours = transactionService
.runOnAnotherTransaction(new IOnTransaction<Integer>() {
EffortDuration oldEffort = transactionService
.runOnAnotherTransaction(new IOnTransaction<EffortDuration>() {
@Override
public Integer execute() {
public EffortDuration execute() {
try {
return workReportLineDAO.find(workReportLine.getId()).getNumHours();
return workReportLineDAO.find(
workReportLine.getId()).getEffort();
} catch (InstanceNotFoundException e) {
// this shouldn't happen, as workReportLine.isNewObject()
// returns false, indicating this object already exists
return workReportLine.getNumHours();
return workReportLine.getEffort();
}
}
});
differenceOfHours = hours - oldNumHours;
differenceOfEffort = effort.minus(oldEffort);
}
orderElement.getSumChargedHours().addDirectChargedHours(differenceOfHours);
orderElement.getSumChargedEffort().addDirectChargedEffort(
differenceOfEffort);
save(orderElement);
updateIndirectChargedHoursRecursively(orderElement.getParent(),differenceOfHours,
relationOrderElementIdAndIndirectChargedHours);
updateIndirectChargedEffortRecursively(orderElement.getParent(),
differenceOfEffort,
relationOrderElementIdAndIndirectChargedEffort);
workReportLineDAO.save(workReportLine);
}
private void updateRelatedSumChargedHoursWithDeletedWorkReportLine(
private void updateRelatedSumChargedEffortWithDeletedWorkReportLine(
final WorkReportLine workReportLine,
Map<Long, Integer> relationOrderElementIdAndIndirectChargedHours)
Map<Long, EffortDuration> relationOrderElementIdAndIndirectChargedHours)
throws InstanceNotFoundException {
if(workReportLine.isNewObject()) {
@ -478,67 +485,70 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement>
return;
}
OrderElement orderElement = find(workReportLine.getOrderElement().getId());
Integer hours = workReportLine.getNumHours() * -1;
EffortDuration effort = workReportLine.getEffort();
orderElement.getSumChargedHours().addDirectChargedHours(hours);
orderElement.getSumChargedEffort().subtractDirectChargedEffort(effort);
save(orderElement);
updateIndirectChargedHoursRecursively(orderElement.getParent(), hours,
updateIndirectChargedEffortRecursively(orderElement.getParent(),
effort,
relationOrderElementIdAndIndirectChargedHours);
}
private void updateIndirectChargedHoursRecursively(
OrderElement orderElement, Integer numberOfHoursDelta,
Map<Long, Integer> relationOrderElementIdAndIndirectChargedHours) {
private void updateIndirectChargedEffortRecursively(
OrderElement orderElement,
EffortDuration effortDelta,
Map<Long, EffortDuration> relationOrderElementIdAndIndirectChargedEffort) {
if(orderElement != null) {
Long id = orderElement.getId();
if(relationOrderElementIdAndIndirectChargedHours.containsKey(id)) {
Integer previous = relationOrderElementIdAndIndirectChargedHours.get(id);
relationOrderElementIdAndIndirectChargedHours.put(id, previous + numberOfHoursDelta);
if (relationOrderElementIdAndIndirectChargedEffort.containsKey(id)) {
EffortDuration previous = relationOrderElementIdAndIndirectChargedEffort
.get(id);
relationOrderElementIdAndIndirectChargedEffort.put(id,
previous.plus(effortDelta));
}
else {
relationOrderElementIdAndIndirectChargedHours.put(id, numberOfHoursDelta);
relationOrderElementIdAndIndirectChargedEffort.put(id,
effortDelta);
}
updateIndirectChargedHoursRecursively(orderElement.getParent(), numberOfHoursDelta,
relationOrderElementIdAndIndirectChargedHours);
updateIndirectChargedEffortRecursively(orderElement.getParent(),
effortDelta, relationOrderElementIdAndIndirectChargedEffort);
}
}
private void updateIndirectChargedHoursWithMap(
Map<Long, Integer> relationOrderElementIdAndIndirectChargedHours)
private void updateIndirectChargedEffortWithMap(
Map<Long, EffortDuration> relationOrderElementIdAndIndirectChargedEffort)
throws InstanceNotFoundException {
for(Long id : relationOrderElementIdAndIndirectChargedHours.keySet()) {
for (Long id : relationOrderElementIdAndIndirectChargedEffort.keySet()) {
OrderElement orderElement = find(id);
orderElement.getSumChargedHours().addIndirectChargedHours(
relationOrderElementIdAndIndirectChargedHours.get(id));
orderElement.getSumChargedEffort().addIndirectChargedEffort(
relationOrderElementIdAndIndirectChargedEffort.get(id));
save(orderElement);
}
}
@Override
@Transactional
public void updateRelatedSumChargedHoursWithDeletedWorkReportLineSet(
public void updateRelatedSumChargedEffortWithDeletedWorkReportLineSet(
Set<WorkReportLine> workReportLineSet) throws InstanceNotFoundException {
Map<Long, Integer> relationOrderElementIdAndIndirectChargedHours =
new Hashtable<Long, Integer>();
Map<Long, EffortDuration> relationOrderElementIdAndIndirectChargedEffort = new Hashtable<Long, EffortDuration>();
for(WorkReportLine line : workReportLineSet) {
updateRelatedSumChargedHoursWithDeletedWorkReportLine(line,
relationOrderElementIdAndIndirectChargedHours);
updateRelatedSumChargedEffortWithDeletedWorkReportLine(line,
relationOrderElementIdAndIndirectChargedEffort);
}
updateIndirectChargedHoursWithMap(relationOrderElementIdAndIndirectChargedHours);
updateIndirectChargedEffortWithMap(relationOrderElementIdAndIndirectChargedEffort);
}
@Override
@Transactional
public void updateRelatedSumChargedHoursWithWorkReportLineSet(
public void updateRelatedSumChargedEffortWithWorkReportLineSet(
Set<WorkReportLine> workReportLineSet) throws InstanceNotFoundException {
Map<Long, Integer> relationOrderElementIdAndIndirectChargedHours =
new Hashtable<Long, Integer>();
Map<Long, EffortDuration> relationOrderElementIdAndIndirectChargedEffort = new Hashtable<Long, EffortDuration>();
for(WorkReportLine line : workReportLineSet) {
updateRelatedSumChargedHoursWithWorkReportLine(line,
relationOrderElementIdAndIndirectChargedHours);
updateRelatedSumChargedEffortWithWorkReportLine(line,
relationOrderElementIdAndIndirectChargedEffort);
}
updateIndirectChargedHoursWithMap(relationOrderElementIdAndIndirectChargedHours);
updateIndirectChargedEffortWithMap(relationOrderElementIdAndIndirectChargedEffort);
}
@SuppressWarnings("unchecked")

View file

@ -108,7 +108,7 @@ public abstract class OrderElement extends IntegrationEntity implements
private Boolean dirtyLastAdvanceMeasurementForSpreading = true;
private SumChargedHours sumChargedHours = SumChargedHours.create();
private SumChargedEffort sumChargedEffort = SumChargedEffort.create();
public OrderElementTemplate getTemplate() {
return template;
@ -1342,12 +1342,12 @@ public abstract class OrderElement extends IntegrationEntity implements
dirtyLastAdvanceMeasurementForSpreading = true;
}
public void setSumChargedHours(SumChargedHours sumChargedHours) {
this.sumChargedHours = sumChargedHours;
public void setSumChargedEffort(SumChargedEffort sumChargedHours) {
this.sumChargedEffort = sumChargedHours;
}
public SumChargedHours getSumChargedHours() {
return sumChargedHours;
public SumChargedEffort getSumChargedEffort() {
return sumChargedEffort;
}
public void updateAdvancePercentageTaskElement() {

View file

@ -0,0 +1,73 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, 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.navalplanner.business.orders.entities;
import org.navalplanner.business.common.BaseEntity;
import org.navalplanner.business.workingday.EffortDuration;
/**
* It represents the efforts charged to an {@link OrderElement}, avoiding the
* need to iterate among the work report lines to get this information.
*
* @author Jacobo Aragunde Pérez <jaragunde@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
public class SumChargedEffort extends BaseEntity {
private EffortDuration directChargedEffort = EffortDuration.zero();
private EffortDuration indirectChargedEffort = EffortDuration.zero();
protected SumChargedEffort() {}
public static SumChargedEffort create() {
return create(new SumChargedEffort());
}
public void addDirectChargedEffort(EffortDuration directChargedEffort) {
this.directChargedEffort = this.directChargedEffort
.plus(directChargedEffort);
}
public void subtractDirectChargedEffort(EffortDuration directChargedEffort) {
this.directChargedEffort = this.directChargedEffort
.minus(directChargedEffort);
}
public EffortDuration getDirectChargedEffort() {
return directChargedEffort;
}
public void addIndirectChargedEffort(EffortDuration indirectChargedEffort) {
this.indirectChargedEffort = this.indirectChargedEffort
.plus(indirectChargedEffort);
}
public EffortDuration getIndirectChargedEffort() {
return indirectChargedEffort;
}
public EffortDuration getTotalChargedEffort() {
return directChargedEffort.plus(indirectChargedEffort);
}
}

View file

@ -1,71 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, 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.navalplanner.business.orders.entities;
import org.navalplanner.business.common.BaseEntity;
/**
* It represents the hours charged to an {@link OrderElement}, avoiding the
* need to iterate among the work report lines to get this information. <br />
* @author Jacobo Aragunde Pérez <jaragunde@igalia.com>
*/
public class SumChargedHours extends BaseEntity {
private Integer directChargedHours = 0;
private Integer indirectChargedHours = 0;
protected SumChargedHours() {}
public static SumChargedHours create() {
return create(new SumChargedHours());
}
public void setDirectChargedHours(Integer directChargedHours) {
this.directChargedHours = directChargedHours;
}
public void addDirectChargedHours(Integer directChargedHours) {
this.directChargedHours += directChargedHours;
}
public Integer getDirectChargedHours() {
return directChargedHours;
}
public void setIndirectChargedHours(Integer indirectChargedHours) {
this.indirectChargedHours = indirectChargedHours;
}
public void addIndirectChargedHours(Integer indirectChargedHours) {
this.indirectChargedHours += indirectChargedHours;
}
public Integer getIndirectChargedHours() {
return indirectChargedHours;
}
public Integer getTotalChargedHours() {
return directChargedHours + indirectChargedHours;
}
}

View file

@ -21,6 +21,7 @@
package org.navalplanner.business.reports.dtos;
import java.math.BigDecimal;
import java.util.List;
import org.joda.time.LocalDate;
@ -47,7 +48,7 @@ public class CompletedEstimatedHoursPerTaskDTO {
private Integer partialPlannedHours;
private Integer realHours;
private BigDecimal realHours;
private CompletedEstimatedHoursPerTaskDTO() {
workReportLineDAO = Registry.getWorkReportLineDAO();
@ -86,8 +87,8 @@ public class CompletedEstimatedHoursPerTaskDTO {
return result;
}
public Integer calculateRealHours(Task task, LocalDate date) {
Integer result = new Integer(0);
public BigDecimal calculateRealHours(Task task, LocalDate date) {
BigDecimal result = BigDecimal.ZERO;
final List<WorkReportLine> workReportLines = workReportLineDAO
.findByOrderElementAndChildren(task.getOrderElement());
@ -98,7 +99,8 @@ public class CompletedEstimatedHoursPerTaskDTO {
for (WorkReportLine workReportLine : workReportLines) {
final LocalDate workReportLineDate = new LocalDate(workReportLine.getDate());
if (date == null || workReportLineDate.compareTo(date) <= 0) {
result += workReportLine.getNumHours();
result = result.add(workReportLine.getEffort()
.toHoursAsDecimalWithScale(2));
}
}
return result;
@ -128,11 +130,11 @@ public class CompletedEstimatedHoursPerTaskDTO {
this.partialPlannedHours = partialPlannedHours;
}
public Integer getRealHours() {
public BigDecimal getRealHours() {
return realHours;
}
public void setRealHours(Integer realHours) {
public void setRealHours(BigDecimal realHours) {
this.realHours = realHours;
}

View file

@ -21,6 +21,7 @@
package org.navalplanner.business.reports.dtos;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Set;
@ -41,7 +42,7 @@ public class HoursWorkedPerResourceDTO {
private LocalTime clockFinish;
private Integer numHours;
private BigDecimal effort;
private String orderElementCode;
@ -59,7 +60,7 @@ Resource resource,
this.date = workReportLine.getDate();
this.clockStart = workReportLine.getClockStart();
this.clockFinish = workReportLine.getClockFinish();
this.numHours = workReportLine.getNumHours();
this.effort = workReportLine.getEffort().toHoursAsDecimalWithScale(2);
this.orderElementCode = workReportLine.getOrderElement().getCode();
this.orderElementName = workReportLine.getOrderElement().getName();
this.descriptionValues = descriptionValuesAsString(workReportLine.getDescriptionValues());
@ -82,12 +83,12 @@ Resource resource,
return (result.length() > 0) ? result.substring(0, result.length() - 2) : result;
}
public Integer getNumHours() {
return numHours;
public BigDecimal getEffort() {
return effort;
}
public void setNumHours(Integer numHours) {
this.numHours = numHours;
public void setEffort(BigDecimal effort) {
this.effort = effort;
}
public LocalTime getClockStart() {

View file

@ -21,6 +21,8 @@
package org.navalplanner.business.reports.dtos;
import java.math.BigDecimal;
import org.navalplanner.business.resources.entities.Worker;
@ -28,18 +30,18 @@ public class HoursWorkedPerWorkerInAMonthDTO {
private String workerName;
private Long numHours;
private BigDecimal numHours;
public HoursWorkedPerWorkerInAMonthDTO(Worker worker, Long numHours) {
public HoursWorkedPerWorkerInAMonthDTO(Worker worker, BigDecimal numHours) {
this.workerName = worker.getName();
this.numHours = numHours;
}
public Long getNumHours() {
public BigDecimal getNumHours() {
return numHours;
}
public void setNumHours(Long numHours) {
public void setNumHours(BigDecimal numHours) {
this.numHours = numHours;
}

View file

@ -47,7 +47,7 @@ public class OrderCostsPerResourceDTO implements
private LocalTime clockFinish;
private Integer numHours;
private BigDecimal numHours;
private String orderElementName;
@ -87,7 +87,7 @@ public class OrderCostsPerResourceDTO implements
}
this.clockStart = workReportLine.getClockStart();
this.clockFinish = workReportLine.getClockFinish();
this.numHours = workReportLine.getNumHours();
this.numHours = workReportLine.getEffort().toHoursAsDecimalWithScale(2);
this.descriptionValues = descriptionValuesAsString(workReportLine.getDescriptionValues());
this.labels = labelsAsString(workReportLine.getLabels());
this.hoursType = workReportLine.getTypeOfWorkHours().getName();
@ -114,11 +114,11 @@ public class OrderCostsPerResourceDTO implements
return (result.length() > 0) ? result.substring(0, result.length() - 2) : result;
}
public Integer getNumHours() {
public BigDecimal getNumHours() {
return numHours;
}
public void setNumHours(Integer numHours) {
public void setNumHours(BigDecimal numHours) {
this.numHours = numHours;
}

View file

@ -57,7 +57,7 @@ public class SchedulingProgressPerOrderDTO {
private Integer partialPlannedHours;
private Integer realHours;
private BigDecimal realHours;
private BigDecimal averageProgress;
@ -106,7 +106,8 @@ public class SchedulingProgressPerOrderDTO {
this.realHours = calculateRealHours(order, date);
// Progress calculations
this.imputedProgress = (totalPlannedHours != 0) ? new Double(realHours
this.imputedProgress = (totalPlannedHours != 0) ? new Double(
realHours.doubleValue()
/ totalPlannedHours.doubleValue()) : new Double(0);
this.plannedProgress = (totalPlannedHours != 0) ? new Double(
partialPlannedHours / totalPlannedHours.doubleValue())
@ -114,7 +115,7 @@ public class SchedulingProgressPerOrderDTO {
// Differences calculations
this.costDifference = calculateCostDifference(averageProgress,
new BigDecimal(totalPlannedHours), new BigDecimal(realHours));
new BigDecimal(totalPlannedHours), realHours);
this.planningDifference = calculatePlanningDifference(averageProgress,
new BigDecimal(totalPlannedHours), new BigDecimal(
partialPlannedHours));
@ -167,8 +168,8 @@ public class SchedulingProgressPerOrderDTO {
.roundToHours();
}
public Integer calculateRealHours(Order order, LocalDate date) {
int result = 0;
public BigDecimal calculateRealHours(Order order, LocalDate date) {
BigDecimal result = BigDecimal.ZERO;
final List<WorkReportLine> workReportLines = workReportLineDAO
.findByOrderElementAndChildren(order);
@ -176,7 +177,8 @@ public class SchedulingProgressPerOrderDTO {
for (WorkReportLine workReportLine : workReportLines) {
final LocalDate workReportLineDate = new LocalDate(workReportLine.getDate());
if (date == null || workReportLineDate.compareTo(date) <= 0) {
result += workReportLine.getNumHours();
result = result.add(workReportLine.getEffort()
.toHoursAsDecimalWithScale(2));
}
}
return result;
@ -194,7 +196,7 @@ public class SchedulingProgressPerOrderDTO {
return partialPlannedHours;
}
public Integer getRealHours() {
public BigDecimal getRealHours() {
return realHours;
}

View file

@ -21,15 +21,18 @@ import java.util.Date;
import org.joda.time.LocalDate;
import org.navalplanner.business.costcategories.entities.TypeOfWorkHours;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workreports.entities.WorkReportLine;
/**
* DTO for {@link WorkReportLine} entity.
*
* @author Susana Montes Pedreira <smonts@wirelessgalicia.com>
* @author Ignacio Diaz Teijido <ignacio.diaz@comtecsf.es>
*/
public class WorkReportLineDTO {
private Integer sumHours;
private EffortDuration sumEffort;
private Date date;
@ -41,19 +44,11 @@ public class WorkReportLineDTO {
}
public WorkReportLineDTO(Resource resource,
TypeOfWorkHours typeOfWorkHours, Date date, Long numHours) {
TypeOfWorkHours typeOfWorkHours, Date date, Long effortDB) {
this.setDate(date);
this.setResource(resource);
this.setTypeOfWorkHours(typeOfWorkHours);
this.setSumHours(new Integer(numHours.intValue()));
}
public void setSumHours(Integer numHours) {
this.sumHours = numHours;
}
public Integer getSumHours() {
return sumHours;
this.setSumEffort(EffortDuration.seconds(effortDB.intValue()));
}
public void setDate(Date date) {
@ -84,4 +79,12 @@ public class WorkReportLineDTO {
return LocalDate.fromDateFields(getDate());
}
}
public void setSumEffort(EffortDuration effort) {
this.sumEffort = effort;
}
public EffortDuration getSumEffort() {
return sumEffort;
}
}

View file

@ -49,7 +49,7 @@ public class WorkingProgressPerTaskDTO {
private Integer partialPlannedHours;
private Integer realHours;
private BigDecimal realHours;
private BigDecimal averageProgress;
@ -81,10 +81,12 @@ public class WorkingProgressPerTaskDTO {
this.realHours = calculateRealHours(task, date);
this.averageProgress = task.getOrderElement().getAdvancePercentage(date);
this.imputedProgress = (totalPlannedHours != 0) ? new Double(realHours / totalPlannedHours.doubleValue()) : new Double(0);
this.imputedProgress = (totalPlannedHours != 0) ? new Double(
realHours.doubleValue() / totalPlannedHours.doubleValue())
: new Double(0);
this.plannedProgress = (totalPlannedHours != 0) ? new Double(partialPlannedHours / totalPlannedHours.doubleValue()) : new Double(0);
this.costDifference = calculateCostDifference(averageProgress,
new BigDecimal(totalPlannedHours), new BigDecimal(realHours));
new BigDecimal(totalPlannedHours), realHours);
this.planningDifference = calculatePlanningDifference(averageProgress,
new BigDecimal(totalPlannedHours), new BigDecimal(
partialPlannedHours));
@ -116,8 +118,8 @@ public class WorkingProgressPerTaskDTO {
return result;
}
public Integer calculateRealHours(Task task, LocalDate date) {
Integer result = new Integer(0);
public BigDecimal calculateRealHours(Task task, LocalDate date) {
BigDecimal result = BigDecimal.ZERO;
final List<WorkReportLine> workReportLines = workReportLineDAO
.findByOrderElementAndChildren(task.getOrderElement());
@ -128,7 +130,8 @@ public class WorkingProgressPerTaskDTO {
for (WorkReportLine workReportLine : workReportLines) {
final LocalDate workReportLineDate = new LocalDate(workReportLine.getDate());
if (date == null || workReportLineDate.compareTo(date) <= 0) {
result += workReportLine.getNumHours();
result = result.add(workReportLine.getEffort()
.toHoursAsDecimalWithScale(2));
}
}
return result;
@ -158,11 +161,11 @@ public class WorkingProgressPerTaskDTO {
this.partialPlannedHours = partialPlannedHours;
}
public Integer getRealHours() {
public BigDecimal getRealHours() {
return realHours;
}
public void setRealHours(Integer realHours) {
public void setRealHours(BigDecimal realHours) {
this.realHours = realHours;
}

View file

@ -21,6 +21,7 @@
package org.navalplanner.business.resources.daos;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
@ -38,6 +39,7 @@ import org.navalplanner.business.resources.entities.Machine;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.business.scenarios.IScenarioManager;
import org.navalplanner.business.workingday.EffortDuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
@ -199,10 +201,9 @@ public class ResourceDAO extends IntegrationEntityDAO<Resource> implements
public List<HoursWorkedPerWorkerInAMonthDTO> getWorkingHoursPerWorker(
Integer year, Integer month) {
String strQuery =
"SELECT wrlresource.id, SUM(wrl.numHours) "
+ "FROM WorkReportLine wrl "
+ "LEFT OUTER JOIN wrl.resource wrlresource ";
String strQuery = "SELECT wrlresource.id, SUM(wrl.effort) "
+ "FROM WorkReportLine wrl "
+ "LEFT OUTER JOIN wrl.resource wrlresource ";
if (year != null) {
strQuery += "WHERE YEAR(wrl.date) = :year ";
@ -231,7 +232,8 @@ public class ResourceDAO extends IntegrationEntityDAO<Resource> implements
for (Object row: rows) {
Object[] columns = (Object[]) row;
Worker worker = (Worker) findExistingEntity((Long) columns[0]);
Long numHours = (Long) columns[1];
BigDecimal numHours = (EffortDuration.seconds(((Long) columns[1])
.intValue())).toHoursAsDecimalWithScale(2);
HoursWorkedPerWorkerInAMonthDTO dto = new HoursWorkedPerWorkerInAMonthDTO(
worker, numHours);
@ -240,4 +242,4 @@ public class ResourceDAO extends IntegrationEntityDAO<Resource> implements
return result;
}
}
}

View file

@ -63,7 +63,7 @@ public class WorkReportLineDAO extends IntegrationEntityDAO<WorkReportLine>
public List<WorkReportLineDTO> findByOrderElementGroupByResourceAndHourTypeAndDate(
OrderElement orderElement) {
String strQuery = "SELECT new org.navalplanner.business.reports.dtos.WorkReportLineDTO(wrl.resource, wrl.typeOfWorkHours, wrl.date, SUM(wrl.numHours)) "
String strQuery = "SELECT new org.navalplanner.business.reports.dtos.WorkReportLineDTO(wrl.resource, wrl.typeOfWorkHours, wrl.date, SUM(wrl.effort)) "
+ "FROM WorkReportLine wrl "
+ "LEFT OUTER JOIN wrl.orderElement orderElement "
+ "WHERE orderElement = :orderElement "

View file

@ -29,9 +29,9 @@ import org.apache.commons.lang.StringUtils;
import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotNull;
import org.hibernate.validator.Valid;
import org.joda.time.Hours;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.joda.time.Seconds;
import org.navalplanner.business.common.IntegrationEntity;
import org.navalplanner.business.common.Registry;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
@ -40,6 +40,7 @@ import org.navalplanner.business.labels.entities.Label;
import org.navalplanner.business.labels.entities.LabelType;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workreports.daos.IWorkReportLineDAO;
import org.navalplanner.business.workreports.valueobjects.DescriptionField;
import org.navalplanner.business.workreports.valueobjects.DescriptionValue;
@ -57,13 +58,7 @@ public class WorkReportLine extends IntegrationEntity implements Comparable,
return create(new WorkReportLine(workReport));
}
public static WorkReportLine create(Integer numHours, Resource resource,
OrderElement orderElement, WorkReport workReport) {
return create(new WorkReportLine(numHours, resource, orderElement,
workReport));
}
private Integer numHours;
private EffortDuration effort;
private Date date;
@ -93,26 +88,18 @@ public class WorkReportLine extends IntegrationEntity implements Comparable,
this.setWorkReport(workReport);
}
private WorkReportLine(Integer numHours, Resource resource,
OrderElement orderElement, WorkReport workReport) {
this(workReport);
this.numHours = numHours;
this.resource = resource;
this.orderElement = orderElement;
@NotNull(message = "effort not specified")
public EffortDuration getEffort() {
return effort;
}
@NotNull(message = "number of hours not specified")
public Integer getNumHours() {
return numHours;
}
public void setNumHours(Integer numHours) {
this.numHours = numHours;
public void setEffort(EffortDuration effort) {
this.effort = effort;
if ((workReport != null)
&& (workReport.getWorkReportType() != null)
&& (workReport.getWorkReportType().getHoursManagement()
.equals(HoursManagementEnum.HOURS_CALCULATED_BY_CLOCK))) {
this.numHours = getDiferenceBetweenTimeStartAndFinish();
this.effort = getDiferenceBetweenTimeStartAndFinish();
}
}
@ -128,7 +115,7 @@ public class WorkReportLine extends IntegrationEntity implements Comparable,
public void setClockFinish(LocalTime clockFinish) {
this.clockFinish = clockFinish;
updateNumHours();
updateEffort();
}
public LocalTime getClockStart() {
@ -143,7 +130,7 @@ public class WorkReportLine extends IntegrationEntity implements Comparable,
public void setClockStart(LocalTime clockStart) {
this.clockStart = clockStart;
updateNumHours();
updateEffort();
}
@Override
@ -225,8 +212,8 @@ public class WorkReportLine extends IntegrationEntity implements Comparable,
// copy the required fields if these are shared by lines
updatesAllSharedDataByLines();
// update calculated hours
updateNumHours();
// update calculated effort
updateEffort();
}
@Override
@ -271,7 +258,7 @@ public class WorkReportLine extends IntegrationEntity implements Comparable,
return true;
}
@AssertTrue(message = "closckFinish:the clockStart must be not null if number of hours is calcultate by clock")
@AssertTrue(message = "clockFinish:the clockStart must be not null if number of hours is calcultate by clock")
public boolean checkConstraintClockFinishMustBeNotNullIfIsCalculatedByClock() {
if (!firstLevelValidationsPassed()) {
return true;
@ -386,18 +373,19 @@ public class WorkReportLine extends IntegrationEntity implements Comparable,
}
}
private void updateNumHours() {
private void updateEffort() {
if ((workReport != null)
&& (workReport.getWorkReportType() != null)
&& workReport.getWorkReportType().getHoursManagement().equals(
HoursManagementEnum.HOURS_CALCULATED_BY_CLOCK)) {
setNumHours(getDiferenceBetweenTimeStartAndFinish());
setEffort(getDiferenceBetweenTimeStartAndFinish());
}
}
private Integer getDiferenceBetweenTimeStartAndFinish() {
private EffortDuration getDiferenceBetweenTimeStartAndFinish() {
if ((clockStart != null) && (clockFinish != null)) {
return Hours.hoursBetween(clockStart, clockFinish).getHours();
return EffortDuration.seconds(Seconds.secondsBetween(clockStart,
clockFinish).getSeconds());
}
return null;
}
@ -440,7 +428,7 @@ public class WorkReportLine extends IntegrationEntity implements Comparable,
if (workReport.getWorkReportType().getHoursManagement().equals(
HoursManagementEnum.HOURS_CALCULATED_BY_CLOCK)) {
if (getDiferenceBetweenTimeStartAndFinish().compareTo(numHours) != 0) {
if (getDiferenceBetweenTimeStartAndFinish().compareTo(effort) != 0) {
return false;
}
}
@ -449,7 +437,7 @@ public class WorkReportLine extends IntegrationEntity implements Comparable,
private boolean firstLevelValidationsPassed() {
return (workReport != null) && (typeOfWorkHours != null)
&& (numHours != null) && (date != null) && (resource != null)
&& (effort != null) && (date != null) && (resource != null)
&& (orderElement != null);
}
@ -563,4 +551,25 @@ public class WorkReportLine extends IntegrationEntity implements Comparable,
return getWorkReport() != null ? getWorkReport().isCodeAutogenerated()
: false;
}
/**
* TODO remove this method in order to use
* {@link WorkReportLine#getEffort()}
*
* @deprecated Use {@link WorkReportLine#getEffort()} instead
*/
public Integer getNumHours() {
return (getEffort() == null) ? null : getEffort().getHours();
}
/**
* TODO remove this method in order to use
* {@link WorkReportLine#setEffort()}
*
* @deprecated Use {@link WorkReportLine#setEffort()} instead
*/
public void setNumHours(Integer hours) {
setEffort(EffortDuration.hours(hours));
}
}

View file

@ -248,4 +248,48 @@
referencesUniqueColumn="false" />
</changeSet>
<changeSet id="change-numhours-to-effort-in-work-report-lines" author="idiazt">
<comment>Changing work_report_line numHours to effort</comment>
<renameColumn tableName="work_report_line" oldColumnName="num_hours" newColumnName="effort"/>
</changeSet>
<changeSet id="update-numhours-values-to-effort-values" author="idiazt">
<comment>Updating numHours to effort (hours to seconds)</comment>
<sql>
UPDATE work_report_line
SET effort = effort*3600
</sql>
</changeSet>
<changeSet id="change-sum_charged_hours-to-sum_charged_effort" author="mrego">
<comment>Changing sum_charged_hours to sum_charged_effort</comment>
<renameTable oldTableName="sum_charged_hours"
newTableName="sum_charged_effort" />
<renameColumn tableName="sum_charged_effort"
oldColumnName="direct_charged_hours"
newColumnName="direct_charged_effort" />
<renameColumn tableName="sum_charged_effort"
oldColumnName="indirect_charged_hours"
newColumnName="indirect_charged_effort" />
</changeSet>
<changeSet id="update-effort-values-in-sum_charged_effort" author="mrego">
<comment>Updating effort values (hours to seconds) in sum_charged_effort table</comment>
<sql>
UPDATE sum_charged_effort
SET direct_charged_effort = direct_charged_effort*3600
</sql>
<sql>
UPDATE sum_charged_effort
SET indirect_charged_effort = indirect_charged_effort*3600
</sql>
</changeSet>
<changeSet id="rename-sum_charged_hours_id-to-sum_charged_effort_id" author="mrego">
<comment>Rename sum_charged_hours_id to sum_charged_effort_id in order_element</comment>
<renameColumn tableName="order_element"
oldColumnName="sum_charged_hours_id"
newColumnName="sum_charged_effort_id" />
</changeSet>
</databaseChangeLog>

View file

@ -74,9 +74,9 @@
column="scheduling_state_for_version_id" />
</map>
<many-to-one name="sumChargedHours"
class="SumChargedHours"
column="sum_charged_hours_id"
<many-to-one name="sumChargedEffort"
class="SumChargedEffort"
column="sum_charged_effort_id"
cascade="save-update, delete"
unique="true"
lazy="false" />
@ -236,7 +236,7 @@
</set>
</class>
<class name="SumChargedHours" table="sum_charged_hours">
<class name="SumChargedEffort" table="sum_charged_effort">
<id name="id" access="property" type="long">
<generator class="hilo" >
<param name="max_lo">100</param>
@ -244,10 +244,12 @@
</id>
<version name="version" access="property" type="long" />
<property name="directChargedHours" access="field"
column="direct_charged_hours" />
<property name="indirectChargedHours" access="field"
column="indirect_charged_hours" />
<property name="directChargedEffort" access="field"
column="direct_charged_effort"
type="org.navalplanner.business.workingday.hibernate.EffortDurationType" />
<property name="indirectChargedEffort" access="field"
column="indirect_charged_effort"
type="org.navalplanner.business.workingday.hibernate.EffortDurationType" />
</class>
</hibernate-mapping>

View file

@ -119,7 +119,7 @@
<property name="code" access="property" not-null="true" unique="true"/>
<property name="numHours" access="field" column="num_hours" />
<property name="effort" access="field" column="effort" type="org.navalplanner.business.workingday.hibernate.EffortDurationType" />
<property name="date" access="field"/>
<property name="clockStart" access="field" column="clock_start"
type="org.joda.time.contrib.hibernate.PersistentLocalTimeExact" />

View file

@ -68,6 +68,7 @@ import org.navalplanner.business.scenarios.entities.OrderVersion;
import org.navalplanner.business.test.calendars.entities.BaseCalendarTest;
import org.navalplanner.business.test.orders.entities.OrderElementTest;
import org.navalplanner.business.test.planner.daos.ResourceAllocationDAOTest;
import org.navalplanner.business.workingday.EffortDuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ -420,16 +421,19 @@ public class OrderElementDAOTest {
public void testSumChargedHoursRelation() throws InstanceNotFoundException {
OrderLine orderLine = createValidOrderLine();
orderLine.getSumChargedHours().setDirectChargedHours(8);
orderLine.getSumChargedHours().setIndirectChargedHours(10);
orderLine.getSumChargedEffort().addDirectChargedEffort(
EffortDuration.hours(8));
orderLine.getSumChargedEffort().addIndirectChargedEffort(
EffortDuration.hours(10));
orderElementDAO.save(orderLine);
OrderElement orderLineCopy = orderElementDAO.find(orderLine.getId());
assertEquals(orderLine.getSumChargedHours().getId(),
orderLineCopy.getSumChargedHours().getId());
assertEquals(orderLine.getSumChargedEffort().getId(),
orderLineCopy.getSumChargedEffort().getId());
assertTrue(orderLineCopy.getSumChargedHours().getTotalChargedHours().equals(18));
assertEquals(orderLineCopy.getSumChargedEffort()
.getTotalChargedEffort(), EffortDuration.hours(18));
}
}

View file

@ -10,7 +10,7 @@
<field name="estimatedHours" class="java.lang.Integer"/>
<field name="totalPlannedHours" class="java.lang.Integer"/>
<field name="partialPlannedHours" class="java.lang.Integer"/>
<field name="realHours" class="java.lang.Integer"/>
<field name="realHours" class="java.math.BigDecimal"/>
<group name="Group2">
<groupExpression><![CDATA[(int)($V{REPORT_COUNT}/5)]]></groupExpression>
</group>
@ -237,7 +237,7 @@
<textField isBlankWhenNull="true">
<reportElement x="441" y="0" width="55" height="36"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$F{realHours}]]></textFieldExpression>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$F{realHours}]]></textFieldExpression>
</textField>
</band>
</detail>

View file

@ -6,10 +6,10 @@
<parameter name="month" class="java.lang.String"/>
<parameter name="logo" class="java.lang.String"/>
<field name="workerName" class="java.lang.String"/>
<field name="numHours" class="java.lang.Long"/>
<variable name="sumNumHours" class="java.lang.Long" calculation="Sum">
<field name="numHours" class="java.math.BigDecimal"/>
<variable name="sumNumHours" class="java.math.BigDecimal" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<initialValueExpression><![CDATA[new java.lang.Long(0)]]></initialValueExpression>
<initialValueExpression><![CDATA[java.math.BigDecimal.ZERO]]></initialValueExpression>
</variable>
<background>
<band splitType="Stretch"/>
@ -123,7 +123,7 @@
<textField isBlankWhenNull="true">
<reportElement x="213" y="0" width="100" height="15"/>
<textElement textAlignment="Center"/>
<textFieldExpression class="java.lang.Long"><![CDATA[$F{numHours}]]></textFieldExpression>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$F{numHours}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="13" y="0" width="200" height="15"/>
@ -138,7 +138,7 @@
<textField evaluationTime="Report" isBlankWhenNull="true">
<reportElement x="213" y="10" width="100" height="15"/>
<textElement textAlignment="Center"/>
<textFieldExpression class="java.lang.Long"><![CDATA[$V{sumNumHours}]]></textFieldExpression>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumNumHours}]]></textFieldExpression>
</textField>
<line>
<reportElement x="224" y="4" width="80" height="1"/>

View file

@ -11,18 +11,18 @@
<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="effort" class="java.math.BigDecimal"/>
<field name="orderElementCode" class="java.lang.String"/>
<field name="orderElementName" class="java.lang.String"/>
<field name="descriptionValues" class="java.lang.String"/>
<field name="labels" class="java.lang.String"/>
<variable name="sumHoursPerDay" class="java.lang.Integer" resetType="Group" resetGroup="Date group" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<initialValueExpression><![CDATA[new java.lang.Integer(0)]]></initialValueExpression>
<variable name="sumHoursPerDay" class="java.math.BigDecimal" resetType="Group" resetGroup="Date group" calculation="Sum">
<variableExpression><![CDATA[$F{effort}]]></variableExpression>
<initialValueExpression><![CDATA[java.math.BigDecimal.ZERO]]></initialValueExpression>
</variable>
<variable name="sumHoursPerWorker" class="java.lang.Integer" resetType="Group" resetGroup="Worker group" incrementType="Group" incrementGroup="Date group" calculation="Sum">
<variable name="sumHoursPerWorker" class="java.math.BigDecimal" resetType="Group" resetGroup="Worker group" incrementType="Group" incrementGroup="Date group" calculation="Sum">
<variableExpression><![CDATA[$V{sumHoursPerDay}]]></variableExpression>
<initialValueExpression><![CDATA[new java.lang.Integer(0)]]></initialValueExpression>
<initialValueExpression><![CDATA[java.math.BigDecimal.ZERO]]></initialValueExpression>
</variable>
<group name="Worker group">
<groupExpression><![CDATA[$F{workerName}]]></groupExpression>
@ -55,7 +55,7 @@
<textField isBlankWhenNull="true">
<reportElement x="257" y="1" width="38" height="15"/>
<textElement textAlignment="Center" verticalAlignment="Top"/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{sumHoursPerWorker}]]></textFieldExpression>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumHoursPerWorker}]]></textFieldExpression>
</textField>
<line>
<reportElement positionType="FixRelativeToBottom" x="0" y="21" width="555" height="1"/>
@ -175,7 +175,7 @@
<textField isBlankWhenNull="true">
<reportElement x="257" y="10" width="38" height="15"/>
<textElement textAlignment="Center" verticalAlignment="Top"/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{sumHoursPerDay}]]></textFieldExpression>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumHoursPerDay}]]></textFieldExpression>
</textField>
<line>
<reportElement x="257" y="6" width="35" height="1"/>
@ -330,7 +330,7 @@
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$F{numHours}]]></textFieldExpression>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$F{effort}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="186" y="0" width="66" height="30"/>

View file

@ -11,7 +11,7 @@
<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="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"/>
@ -21,13 +21,13 @@
<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.lang.Integer" resetType="Group" resetGroup="Task" calculation="Sum">
<variable name="sumHoursPerTask" class="java.math.BigDecimal" resetType="Group" resetGroup="Task" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<initialValueExpression><![CDATA[new Integer(0)]]></initialValueExpression>
<initialValueExpression><![CDATA[new BigDecimal(0)]]></initialValueExpression>
</variable>
<variable name="sumHoursPerWorker" class="java.lang.Integer" resetType="Group" resetGroup="Worker" calculation="Sum">
<variable name="sumHoursPerWorker" class="java.math.BigDecimal" resetType="Group" resetGroup="Worker" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<initialValueExpression><![CDATA[new Integer(0)]]></initialValueExpression>
<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>
@ -36,16 +36,16 @@
<variable name="sumTotalCosts" class="java.math.BigDecimal" resetType="Group" resetGroup="OrderCode" calculation="Sum">
<variableExpression><![CDATA[$F{cost}]]></variableExpression>
</variable>
<variable name="sumTotalHours" class="java.lang.Integer" resetType="Group" resetGroup="OrderCode" calculation="Sum">
<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.lang.Integer" resetType="Group" resetGroup="HoursType Group" calculation="Sum">
<variable name="sumHoursPerWorkerandCost" class="java.math.BigDecimal" resetType="Group" resetGroup="HoursType Group" calculation="Sum">
<variableExpression><![CDATA[$F{numHours}]]></variableExpression>
<initialValueExpression><![CDATA[new Integer(0)]]></initialValueExpression>
<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>
@ -83,12 +83,12 @@
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total}]]></textFieldExpression>
</textField>
<textField pattern="###0 h">
<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.lang.Integer"><![CDATA[$V{sumTotalHours}]]></textFieldExpression>
<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"/>
@ -132,10 +132,10 @@
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total.task}]]></textFieldExpression>
</textField>
<textField pattern="###0 h">
<textField pattern="###0.00 h">
<reportElement x="329" y="2" width="93" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{sumHoursPerTask}]]></textFieldExpression>
<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"/>
@ -242,10 +242,10 @@
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total.worker}]]></textFieldExpression>
</textField>
<textField pattern="###0 h">
<textField pattern="###0.00 h">
<reportElement x="329" y="2" width="93" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{sumHoursPerWorker}]]></textFieldExpression>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumHoursPerWorker}]]></textFieldExpression>
</textField>
</band>
</groupFooter>
@ -271,10 +271,10 @@
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumCostsPerWorkerandCost}]]></textFieldExpression>
</textField>
<textField pattern="###0 h">
<textField pattern="###0.00 h">
<reportElement x="330" y="0" width="93" height="14"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{sumHoursPerWorkerandCost}]]></textFieldExpression>
<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"/>

View file

@ -12,7 +12,7 @@
<field name="estimatedHours" class="java.lang.Integer"/>
<field name="totalPlannedHours" class="java.lang.Integer"/>
<field name="partialPlannedHours" class="java.lang.Integer"/>
<field name="realHours" class="java.lang.Integer"/>
<field name="realHours" class="java.math.BigDecimal"/>
<field name="averageProgress" class="java.math.BigDecimal"/>
<field name="imputedProgress" class="java.lang.Double"/>
<field name="plannedProgress" class="java.lang.Double"/>
@ -196,7 +196,7 @@
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$F{realHours}]]></textFieldExpression>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$F{realHours}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="24" y="1" width="450" height="16"/>

View file

@ -10,7 +10,7 @@
<field name="estimatedHours" class="java.lang.Integer"/>
<field name="totalPlannedHours" class="java.lang.Integer"/>
<field name="partialPlannedHours" class="java.lang.Integer"/>
<field name="realHours" class="java.lang.Integer"/>
<field name="realHours" class="java.math.BigDecimal"/>
<field name="averageProgress" class="java.math.BigDecimal"/>
<field name="imputedProgress" class="java.lang.Double"/>
<field name="plannedProgress" class="java.lang.Double"/>
@ -290,7 +290,7 @@
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$F{realHours}]]></textFieldExpression>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$F{realHours}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="86" y="96" width="80" height="20"/>

View file

@ -52,21 +52,24 @@ public class AssignedHoursToOrderElementController extends
return assignedHoursToOrderElementModel.getWorkReportLines();
}
public int getTotalAssignedDirectHours() {
return assignedHoursToOrderElementModel.getAssignedDirectHours();
public String getTotalAssignedDirectEffort() {
return assignedHoursToOrderElementModel.getAssignedDirectEffort()
.toFormattedString();
}
public int getTotalAssignedHours() {
return assignedHoursToOrderElementModel.getTotalAssignedHours();
public String getTotalAssignedEffort() {
return assignedHoursToOrderElementModel.getTotalAssignedEffort()
.toFormattedString();
}
public int getHoursChildren() {
public String getEffortChildren() {
return assignedHoursToOrderElementModel
.getAssignedDirectHoursChildren();
.getAssignedDirectEffortChildren().toFormattedString();
}
public int getEstimatedHours() {
return assignedHoursToOrderElementModel.getEstimatedHours();
public String getEstimatedEffort() {
return assignedHoursToOrderElementModel.getEstimatedEffort()
.toFormattedString();
}
public int getProgressWork() {

View file

@ -33,6 +33,7 @@ import org.joda.time.LocalDate;
import org.navalplanner.business.orders.daos.IOrderElementDAO;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.reports.dtos.WorkReportLineDTO;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workreports.daos.IWorkReportLineDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
@ -44,6 +45,7 @@ import org.springframework.transaction.annotation.Transactional;
* Service to show the asigned hours of a selected order element
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Ignacio Díaz Teijido <ignacio.diaz@comtecsf.es>
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -56,7 +58,7 @@ public class AssignedHoursToOrderElementModel implements
@Autowired
private IOrderElementDAO orderElementDAO;
private int assignedDirectHours;
private EffortDuration assignedDirectEffort;
private OrderElement orderElement;
@ -66,7 +68,7 @@ public class AssignedHoursToOrderElementModel implements
public AssignedHoursToOrderElementModel(IWorkReportLineDAO workReportLineDAO) {
Validate.notNull(workReportLineDAO);
this.workReportLineDAO = workReportLineDAO;
this.assignedDirectHours = 0;
this.assignedDirectEffort = EffortDuration.zero();
}
@Override
@ -76,7 +78,7 @@ public class AssignedHoursToOrderElementModel implements
return new ArrayList<WorkReportLineDTO>();
}
orderElementDAO.reattach(orderElement);
this.assignedDirectHours = 0;
this.assignedDirectEffort = EffortDuration.zero();
this.listWRL = workReportLineDAO
.findByOrderElementGroupByResourceAndHourTypeAndDate(orderElement);
@ -86,8 +88,8 @@ public class AssignedHoursToOrderElementModel implements
WorkReportLineDTO w = iterador.next();
w.getResource().getShortDescription();
w.getTypeOfWorkHours().getName();
this.assignedDirectHours = this.assignedDirectHours
+ w.getSumHours();
this.assignedDirectEffort = this.assignedDirectEffort.plus(w
.getSumEffort());
}
return sortByDate(listWRL);
}
@ -128,8 +130,8 @@ public class AssignedHoursToOrderElementModel implements
.equals(nextWRL.getTypeOfWorkHours().getId()))
&& (currentDate.compareTo(nextDate) == 0)) {
// sum the number of hours to the next WorkReportLineDTO
currentWRL.setSumHours(currentWRL.getSumHours()
+ nextWRL.getSumHours());
currentWRL.setSumEffort(currentWRL.getSumEffort().plus(
nextWRL.getSumEffort()));
} else {
groupedByDateList.add(nextWRL);
currentWRL = nextWRL;
@ -140,32 +142,32 @@ public class AssignedHoursToOrderElementModel implements
}
@Override
public int getAssignedDirectHours() {
public EffortDuration getAssignedDirectEffort() {
if (orderElement == null) {
return 0;
return EffortDuration.zero();
}
return this.assignedDirectHours;
return this.assignedDirectEffort;
}
@Override
public int getTotalAssignedHours() {
public EffortDuration getTotalAssignedEffort() {
if (orderElement == null) {
return 0;
return EffortDuration.zero();
}
return this.orderElement.getSumChargedHours().getTotalChargedHours();
return this.orderElement.getSumChargedEffort().getTotalChargedEffort();
}
@Override
@Transactional(readOnly = true)
public int getAssignedDirectHoursChildren() {
public EffortDuration getAssignedDirectEffortChildren() {
if (orderElement == null) {
return 0;
return EffortDuration.zero();
}
if (orderElement.getChildren().isEmpty()) {
return 0;
return EffortDuration.zero();
}
int assignedDirectChildren = getTotalAssignedHours()
- this.assignedDirectHours;
EffortDuration assignedDirectChildren = getTotalAssignedEffort().minus(
this.assignedDirectEffort);
return assignedDirectChildren;
}
@ -177,11 +179,12 @@ public class AssignedHoursToOrderElementModel implements
@Override
@Transactional(readOnly = true)
public int getEstimatedHours() {
public EffortDuration getEstimatedEffort() {
if (orderElement == null) {
return 0;
return EffortDuration.zero();
}
return orderElement.getWorkHours();
//TODO this must be changed when changing HoursGroup
return EffortDuration.hours(orderElement.getWorkHours());
}
@Override

View file

@ -25,16 +25,21 @@ import java.util.List;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.reports.dtos.WorkReportLineDTO;
import org.navalplanner.business.workingday.EffortDuration;
/**
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
public interface IAssignedHoursToOrderElementModel{
public List<WorkReportLineDTO> getWorkReportLines();
public int getAssignedDirectHours();
public int getTotalAssignedHours();
public int getAssignedDirectHoursChildren();
public EffortDuration getTotalAssignedEffort();
public EffortDuration getAssignedDirectEffortChildren();
public void initOrderElement(OrderElement orderElement);
public int getEstimatedHours();
public EffortDuration getEstimatedEffort();
public int getProgressWork();
public EffortDuration getAssignedDirectEffort();
}

View file

@ -474,15 +474,16 @@ public class TaskElementAdapter implements ITaskElementAdapter {
public GanttDate getHoursAdvanceEndDate() {
OrderElement orderElement = taskElement.getOrderElement();
Integer assignedHours = 0;
if (orderElement.getSumChargedHours() != null) {
assignedHours = orderElement.getSumChargedHours()
.getTotalChargedHours();
EffortDuration assignedEffort = EffortDuration.zero();
if (orderElement.getSumChargedEffort() != null) {
assignedEffort = orderElement.getSumChargedEffort()
.getTotalChargedEffort();
}
GanttDate result = null;
if(!(taskElement instanceof TaskGroup)) {
result = calculateLimitDate(assignedHours);
result = calculateLimitDate(assignedEffort
.toHoursAsDecimalWithScale(2));
}
if (result == null) {
Integer hours = taskElement.getSumOfHoursAllocated();
@ -493,8 +494,9 @@ public class TaskElementAdapter implements ITaskElementAdapter {
return getBeginDate();
}
}
BigDecimal percentage = new BigDecimal(assignedHours)
.setScale(2).divide(new BigDecimal(hours),
BigDecimal percentage = assignedEffort
.toHoursAsDecimalWithScale(2).divide(
new BigDecimal(hours),
RoundingMode.DOWN);
result = calculateLimitDate(percentage);
@ -510,9 +512,12 @@ public class TaskElementAdapter implements ITaskElementAdapter {
return BigDecimal.ZERO;
}
int totalChargedHours = orderElement.getSumChargedHours() != null ? orderElement
.getSumChargedHours().getTotalChargedHours() : 0;
BigDecimal assignedHours = new BigDecimal(totalChargedHours).setScale(2);
EffortDuration totalChargedEffort = orderElement
.getSumChargedEffort() != null ? orderElement
.getSumChargedEffort().getTotalChargedEffort()
: EffortDuration.zero();
BigDecimal assignedHours = totalChargedEffort
.toHoursAsDecimalWithScale(2);
BigDecimal estimatedHours = new BigDecimal(taskElement.getSumOfHoursAllocated())
.setScale(2);

View file

@ -37,6 +37,7 @@ import org.navalplanner.business.labels.entities.Label;
import org.navalplanner.business.labels.entities.LabelType;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workreports.entities.HoursManagementEnum;
import org.navalplanner.business.workreports.entities.WorkReport;
import org.navalplanner.business.workreports.entities.WorkReportLabelTypeAssigment;
@ -50,6 +51,7 @@ import org.navalplanner.web.common.MessagesForUser;
import org.navalplanner.web.common.OnlyOneVisible;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.common.components.Autocomplete;
import org.navalplanner.web.common.components.EffortDurationPicker;
import org.navalplanner.web.common.components.NewDataSortableColumn;
import org.navalplanner.web.common.components.NewDataSortableGrid;
import org.navalplanner.web.common.components.bandboxsearch.BandboxSearch;
@ -72,7 +74,6 @@ import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Constraint;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Intbox;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
@ -407,22 +408,20 @@ public class WorkReportCRUDController extends GenericForwardComposer implements
return false;
}
if (workReportLine.getNumHours() == null) {
// Locate TextboxOrder
Intbox txtHours = getIntboxHours(row);
if (txtHours != null) {
String message = _("Hours cannot be null");
showInvalidMessage(txtHours, message);
if (workReportLine.getEffort() == null) {
EffortDurationPicker effort = getEffortDurationPicker(row);
if (effort == null) {
String message = _("Effort cannot be null");
showInvalidMessage(effort, message);
}
return false;
}
if (!workReportLine.checkConstraintHoursCalculatedByClock()) {
// Locate TextboxOrder
Intbox txtHours = getIntboxHours(row);
if (txtHours != null) {
String message = _("number of hours is not properly calculated based on clock");
showInvalidMessage(txtHours, message);
EffortDurationPicker effort = getEffortDurationPicker(row);
if (effort != null) {
String message = _("effort is not properly calculated based on clock");
showInvalidMessage(effort, message);
}
return false;
}
@ -513,14 +512,15 @@ public class WorkReportCRUDController extends GenericForwardComposer implements
}
/**
* Locates {@link Intbox} Hours in {@link Row}
* Locates {@link EffortDurationPicker} effort in {@link Row}
*
* @param row
* @return
*/
private Intbox getIntboxHours(Row row) {
private EffortDurationPicker getEffortDurationPicker(Row row) {
try {
int position = row.getChildren().size() - 4;
return (Intbox) row.getChildren().get(position);
return (EffortDurationPicker) row.getChildren().get(position);
} catch (Exception e) {
return null;
}
@ -1041,7 +1041,7 @@ public class WorkReportCRUDController extends GenericForwardComposer implements
Timebox timeFinish = (Timebox) getTimeboxFinish(row);
if (timeFinish != null) {
checkCannotBeHigher(timeStart, timeFinish);
updateNumHours(row);
updateEffort(row);
}
}
});
@ -1049,12 +1049,12 @@ public class WorkReportCRUDController extends GenericForwardComposer implements
row.appendChild(timeStart);
}
private void updateNumHours(final Row row) {
private void updateEffort(final Row row) {
WorkReportLine line = (WorkReportLine) row.getValue();
Intbox txtHours = getIntboxHours(row);
if (txtHours != null) {
txtHours.setValue(line.getNumHours());
txtHours.invalidate();
EffortDurationPicker effort = getEffortDurationPicker(row);
if (effort != null) {
effort.setValue(line.getEffort());
effort.invalidate();
}
}
@ -1102,7 +1102,7 @@ public class WorkReportCRUDController extends GenericForwardComposer implements
Timebox timeStart = (Timebox) getTimeboxStart(row);
if (timeStart != null) {
checkCannotBeHigher(timeStart, timeFinish);
updateNumHours(row);
updateEffort(row);
}
}
@ -1126,21 +1126,20 @@ public class WorkReportCRUDController extends GenericForwardComposer implements
}
/**
* Append a {@link Intbox} numHours to {@link Row}
* Append a {@link EffortDurationPicker} effort to {@link Row}
*
* @param row
*/
private void appendNumHours(Row row) {
Intbox intNumHours = new Intbox();
intNumHours.setWidth("50px");
private void appendEffortDuration(Row row) {
EffortDurationPicker effort = new EffortDurationPicker();
WorkReportLine workReportLine = (WorkReportLine) row.getValue();
bindIntboxNumHours(intNumHours, workReportLine);
bindEffortDurationPicker(effort, workReportLine);
if (getWorkReportType().getHoursManagement().equals(
HoursManagementEnum.HOURS_CALCULATED_BY_CLOCK)) {
intNumHours.setReadonly(true);
effort.setDisabled(true);
}
row.appendChild(intNumHours);
row.appendChild(effort);
}
/**
@ -1264,24 +1263,28 @@ public class WorkReportCRUDController extends GenericForwardComposer implements
}
/**
* Binds Intbox numHours to a {@link WorkReportLine} numHours
* @param intNumHours
* Binds EffortDurationPicker efffort to a {@link WorkReportLine} numHours
*
* @param effort
* @param workReportLine
*/
private void bindIntboxNumHours(final Intbox intNumHours,
private void bindEffortDurationPicker(final EffortDurationPicker effort,
final WorkReportLine workReportLine) {
Util.bind(intNumHours, new Util.Getter<Integer>() {
effort.bind(new Util.Getter<EffortDuration>() {
@Override
public Integer get() {
return workReportLine.getNumHours();
public EffortDuration get() {
if (workReportLine.getEffort() != null) {
return workReportLine.getEffort();
}
return EffortDuration.zero();
}
}, new Util.Setter<Integer>() {
}, new Util.Setter<EffortDuration>() {
@Override
public void set(Integer value) {
workReportLine.setNumHours(value);
public void set(EffortDuration value) {
workReportLine.setEffort(value);
}
});
}
@ -1325,7 +1328,7 @@ public class WorkReportCRUDController extends GenericForwardComposer implements
appendHourFinish(row);
}
appendNumHours(row);
appendEffortDuration(row);
appendHoursType(row);
appendCode(row);
appendDeleteButton(row);

View file

@ -45,7 +45,6 @@ import org.navalplanner.business.labels.entities.Label;
import org.navalplanner.business.labels.entities.LabelType;
import org.navalplanner.business.orders.daos.IOrderDAO;
import org.navalplanner.business.orders.daos.IOrderElementDAO;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.orders.entities.OrderLineGroup;
import org.navalplanner.business.resources.daos.IWorkerDAO;
@ -281,9 +280,11 @@ public class WorkReportModel extends IntegrationEntityModel implements
@Transactional
public void confirmSave() throws ValidationException {
try {
orderElementDAO.updateRelatedSumChargedHoursWithDeletedWorkReportLineSet(
orderElementDAO
.updateRelatedSumChargedEffortWithDeletedWorkReportLineSet(
deletedWorkReportLinesSet);
orderElementDAO.updateRelatedSumChargedHoursWithWorkReportLineSet(
orderElementDAO
.updateRelatedSumChargedEffortWithWorkReportLineSet(
workReport.getWorkReportLines());
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
@ -420,7 +421,8 @@ public class WorkReportModel extends IntegrationEntityModel implements
public void remove(WorkReport workReport) {
//before deleting the report, update OrderElement.SumChargedHours
try {
orderElementDAO.updateRelatedSumChargedHoursWithDeletedWorkReportLineSet(
orderElementDAO
.updateRelatedSumChargedEffortWithDeletedWorkReportLineSet(
workReport.getWorkReportLines());
workReportDAO.remove(workReport.getId());
} catch (InstanceNotFoundException e) {

View file

@ -144,7 +144,8 @@ public class WorkReportServiceREST extends
*/
entity.validate();
try {
orderElementDAO.updateRelatedSumChargedHoursWithWorkReportLineSet(
orderElementDAO
.updateRelatedSumChargedEffortWithWorkReportLineSet(
entity.getWorkReportLines());
} catch (InstanceNotFoundException e) {
//should never happen, because the entity has been

View file

@ -41,7 +41,7 @@
<label
value="@{workReportLine.resource.shortDescription}" />
<label value="@{workReportLine.typeOfWorkHours.name}" />
<label value="@{workReportLine.sumHours}" />
<label value="@{workReportLine.sumEffort.toFormattedString}" />
</row>
</rows>
</grid>
@ -55,20 +55,20 @@
<label
value="${i18n:_('Sum of direct imputed hours')}" />
<label
value="@{assignedHoursToOrderElementController.totalAssignedDirectHours}" />
value="@{assignedHoursToOrderElementController.totalAssignedDirectEffort}" />
</row>
<row>
<label
value="${i18n:_('Sum of all task leafs imputed hours')}" />
<label id="totalIDC"
value="@{assignedHoursToOrderElementController.hoursChildren}" />
value="@{assignedHoursToOrderElementController.effortChildren}" />
</row>
<row
style="border-top:1px solid black; font-weight: bold;">
<label value="${i18n:_('Total hours')}"
style="font-weight: bold" />
<label id="addtotal"
value="@{assignedHoursToOrderElementController.totalAssignedHours}"
value="@{assignedHoursToOrderElementController.totalAssignedEffort}"
style="font-weight: bold" />
</row>
</rows>
@ -102,13 +102,13 @@
<label
value="${i18n:_('Budget hours')}:" />
<label
value="@{assignedHoursToOrderElementController.estimatedHours}" />
value="@{assignedHoursToOrderElementController.estimatedEffort}" />
</row>
<row>
<label
value="${i18n:_('Imputed hours')}:" />
<label
value="@{assignedHoursToOrderElementController.totalAssignedHours}" />
value="@{assignedHoursToOrderElementController.totalAssignedEffort}" />
</row>
</rows>
</grid>

View file

@ -82,7 +82,7 @@
<column id="finishHour" label="${i18n:_('Finish hour')}" width="80px" align="center"
sort="auto(clockFinish)" sortDirection="ascending"/>
<column id="hours" label="${i18n:_('Hours')}" width="50px" align="center"
sort="auto(numHours)" sortDirection="ascending"/>
sort="auto(effort)" sortDirection="ascending"/>
<column id="hourType" label="${i18n:_('Hours type')}" width="90px" align="center"
sort="auto(typeOfWorkHours.name)" sortDirection="ascending"/>
<column label="${i18n:_('Work Report')}" width="80px" align="center"/>
@ -97,7 +97,7 @@
<label value="@{queryWorkReportLine.orderElement.name}" />
<label value="@{queryWorkReportLine.clockStart, converter='org.navalplanner.web.common.typeconverters.TimeConverter'}" />
<label value="@{queryWorkReportLine.clockFinish, converter='org.navalplanner.web.common.typeconverters.TimeConverter'}" />
<label value="@{queryWorkReportLine.numHours}" />
<label value="@{queryWorkReportLine.effort.toFormattedString}" />
<label value="@{queryWorkReportLine.typeOfWorkHours.name}" />
<button sclass="icono" image="/common/img/ico_editar1.png"
hoverImage="/common/img/ico_editar.png"