Use EffortDuration instead of hours to increase precision

FEA: ItEr70S04BugFixing
This commit is contained in:
Óscar González Fernández 2011-02-09 19:28:19 +01:00
parent 098f8e594b
commit 685386e06f
5 changed files with 51 additions and 37 deletions

View file

@ -391,9 +391,9 @@ public class GenericResourceAllocation extends
}
@Override
public int getAssignedHours(ICriterion criterion, LocalDate start,
LocalDate endExclusive) {
return super.getAssignedHours(start, endExclusive);
public EffortDuration getAssignedEffort(ICriterion criterion,
LocalDate start, LocalDate endExclusive) {
return super.getAssignedDuration(start, endExclusive);
}
}

View file

@ -1660,14 +1660,20 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
public int getAssignedHours(final Resource resource, LocalDate start,
LocalDate endExclusive) {
return getAssignedDuration(filter(getAssignments(start, endExclusive),
new PredicateOnDayAssignment() {
return getAssignedEffort(resource, start, endExclusive).roundToHours();
}
public EffortDuration getAssignedEffort(final Resource resource,
LocalDate start, LocalDate endExclusive) {
return getAssignedDuration(
filter(getAssignments(start, endExclusive),
new PredicateOnDayAssignment() {
@Override
public boolean satisfiedBy(
DayAssignment dayAssignment) {
return dayAssignment.isAssignedTo(resource);
}
})).roundToHours();
}));
}
public List<DayAssignment> getAssignments(LocalDate start,
@ -1680,7 +1686,7 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
return getAssignedDuration(start, endExclusive).roundToHours();
}
public abstract int getAssignedHours(ICriterion criterion, LocalDate start,
public abstract EffortDuration getAssignedEffort(ICriterion criterion, LocalDate start,
LocalDate endExclusive);
private List<DayAssignment> filter(List<DayAssignment> assignments,

View file

@ -358,7 +358,7 @@ public class SpecificResourceAllocation extends
}
@Override
public int getAssignedHours(ICriterion criterion, LocalDate startInclusive,
public EffortDuration getAssignedEffort(ICriterion criterion, LocalDate startInclusive,
LocalDate endExclusive) {
EffortDuration result = EffortDuration.zero();
for (Interval each : getIntervalsRelatedWith(criterion, startInclusive,
@ -369,7 +369,7 @@ public class SpecificResourceAllocation extends
result = result.plus(getAssignedDuration(intervalStart.getDate(),
intervalEnd.getDate()));
}
return result.roundToHours();
return result;
}
private List<Interval> getIntervalsRelatedWith(ICriterion criterion,

View file

@ -28,6 +28,7 @@ import java.util.EnumMap;
import java.util.Map.Entry;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.math.Fraction;
/**
* <p>
@ -184,6 +185,10 @@ public class EffortDuration implements Comparable<EffortDuration> {
return seconds / other.seconds;
}
public Fraction divivedBy(EffortDuration effortAssigned) {
return Fraction.getFraction(this.seconds, effortAssigned.seconds);
}
/**
* Calculates the remainder resulting of doing the integer division of both
* durations

View file

@ -24,7 +24,6 @@ package org.navalplanner.web.resourceload;
import static org.navalplanner.business.workingday.IntraDayDate.max;
import static org.navalplanner.business.workingday.IntraDayDate.min;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -34,6 +33,7 @@ import java.util.List;
import java.util.Map;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.math.Fraction;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.navalplanner.business.planner.entities.ResourceAllocation;
@ -200,36 +200,37 @@ abstract class LoadPeriodGenerator {
+ allocationsOnInterval + ". LoadPeriod ignored");
return null;
}
int totalWorkHours = getTotalWorkHours();
int hoursAssigned = getHoursAssigned();
EffortDuration totalEffort = getTotalAvailableEffort();
EffortDuration effortAssigned = getEffortAssigned();
return new LoadPeriod(start.getDate(), end.asExclusiveEnd(),
totalWorkHours, hoursAssigned,
new LoadLevel(calculateLoadPercentage(totalWorkHours,
hoursAssigned)));
totalEffort.roundToHours(), effortAssigned.roundToHours(),
new LoadLevel(calculateLoadPercentage(totalEffort,
effortAssigned)));
}
protected abstract int getTotalWorkHours();
protected abstract EffortDuration getTotalAvailableEffort();
private static int calculateLoadPercentage(int totalWorkHours,
int hoursAssigned) {
if (totalWorkHours == 0) {
return hoursAssigned == 0 ? 0 : Integer.MAX_VALUE;
private static int calculateLoadPercentage(EffortDuration totalEffort,
EffortDuration effortAssigned) {
if (totalEffort.isZero()) {
return effortAssigned.isZero() ? 0 : Integer.MAX_VALUE;
}
double proportion = hoursAssigned / (double) totalWorkHours;
return new BigDecimal(proportion).scaleByPowerOfTen(2).intValue();
Fraction fraction = totalEffort.divivedBy(effortAssigned);
Fraction percentage = fraction.multiplyBy(Fraction.getFraction(100, 1));
return percentage.intValue();
}
protected abstract int getHoursAssigned();
protected abstract EffortDuration getEffortAssigned();
protected final int sumAllocations() {
int sum = 0;
protected final EffortDuration sumAllocations() {
EffortDuration sum = EffortDuration.zero();
for (ResourceAllocation<?> resourceAllocation : allocationsOnInterval) {
sum += getAssignedHoursFor(resourceAllocation);
sum = sum.plus(getAssignedEffortFor(resourceAllocation));
}
return sum;
}
protected abstract int getAssignedHoursFor(
protected abstract EffortDuration getAssignedEffortFor(
ResourceAllocation<?> resourceAllocation);
public IntraDayDate getStart() {
@ -272,18 +273,19 @@ class LoadPeriodGeneratorOnResource extends LoadPeriodGenerator {
}
@Override
protected int getTotalWorkHours() {
return resource.getTotalEffortFor(start, end, criterion).roundToHours();
protected EffortDuration getTotalAvailableEffort() {
return resource.getTotalEffortFor(start, end, criterion);
}
@Override
protected int getAssignedHoursFor(ResourceAllocation<?> resourceAllocation) {
return resourceAllocation.getAssignedHours(resource, start.getDate(),
protected EffortDuration getAssignedEffortFor(
ResourceAllocation<?> resourceAllocation) {
return resourceAllocation.getAssignedEffort(resource, start.getDate(),
end.asExclusiveEnd());
}
@Override
protected int getHoursAssigned() {
protected EffortDuration getEffortAssigned() {
return sumAllocations();
}
@ -323,22 +325,23 @@ class LoadPeriodGeneratorOnCriterion extends LoadPeriodGenerator {
}
@Override
protected int getAssignedHoursFor(ResourceAllocation<?> resourceAllocation) {
return resourceAllocation.getAssignedHours(criterion, start.getDate(),
protected EffortDuration getAssignedEffortFor(
ResourceAllocation<?> resourceAllocation) {
return resourceAllocation.getAssignedEffort(criterion, start.getDate(),
end.asExclusiveEnd());
}
@Override
protected int getTotalWorkHours() {
protected EffortDuration getTotalAvailableEffort() {
EffortDuration sum = EffortDuration.zero();
for (Resource resource : resourcesSatisfyingCriterionAtSomePoint) {
sum = sum.plus(resource.getTotalEffortFor(start, end, criterion));
}
return sum.roundToHours();
return sum;
}
@Override
protected int getHoursAssigned() {
protected EffortDuration getEffortAssigned() {
return sumAllocations();
}