ResourcesPerDay now works with EffortDurations instead of hours

FEA: ItEr60S19TimeUnitDataType
This commit is contained in:
Óscar González Fernández 2010-08-18 18:19:32 +02:00
parent 597989de06
commit 0228ce0e65
6 changed files with 91 additions and 34 deletions

View file

@ -23,6 +23,7 @@ package org.navalplanner.business.calendars.entities;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -37,6 +38,8 @@ import org.navalplanner.business.calendars.daos.IBaseCalendarDAO;
import org.navalplanner.business.calendars.entities.CalendarData.Days;
import org.navalplanner.business.common.IntegrationEntity;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workingday.EffortDuration.Granularity;
import org.navalplanner.business.workingday.ResourcesPerDay;
/**
@ -886,11 +889,30 @@ public class BaseCalendar extends IntegrationEntity implements IWorkHours {
calendarAvailability.setEndDate(endDate);
}
public static int roundToHours(EffortDuration effortDuration) {
if (effortDuration.equals(EffortDuration.zero())) {
return 0;
}
return Math.max(1, roundHalfUpToHours(effortDuration.decompose()));
}
private static int roundHalfUpToHours(
EnumMap<Granularity, Integer> components) {
int seconds = components.get(Granularity.SECONDS);
int minutes = components.get(Granularity.MINUTES)
+ (seconds < 30 ? 0 : 1);
int hours = components.get(Granularity.HOURS) + (minutes < 30 ? 0 : 1);
return hours;
}
@Override
public Integer toHours(LocalDate day, ResourcesPerDay resourcesPerDay) {
final Integer workableHours = getWorkableHours(day);
return limitOverAssignability(day, resourcesPerDay
.asHoursGivenResourceWorkingDayOf(workableHours), workableHours);
return limitOverAssignability(day,
roundToHours(resourcesPerDay
.asDurationGivenWorkingDayOf(EffortDuration
.hours(workableHours))),
workableHours);
}
private Integer limitOverAssignability(LocalDate day,

View file

@ -22,6 +22,7 @@ package org.navalplanner.business.calendars.entities;
import org.apache.commons.lang.Validate;
import org.joda.time.LocalDate;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workingday.ResourcesPerDay;
public class SameWorkHoursEveryDay implements IWorkHours {
@ -47,7 +48,9 @@ public class SameWorkHoursEveryDay implements IWorkHours {
@Override
public Integer toHours(LocalDate day, ResourcesPerDay amount) {
return amount.asHoursGivenResourceWorkingDayOf(getCapacityAt(day));
return BaseCalendar.roundToHours(amount
.asDurationGivenWorkingDayOf(EffortDuration
.hours(getCapacityAt(day))));
}
@Override

View file

@ -25,6 +25,7 @@ import java.math.RoundingMode;
import org.apache.commons.lang.Validate;
import org.navalplanner.business.common.ProportionalDistributor;
import org.navalplanner.business.workingday.EffortDuration.Granularity;
public class ResourcesPerDay {
@ -99,15 +100,16 @@ public class ResourcesPerDay {
return amount;
}
public int asHoursGivenResourceWorkingDayOf(
Integer resourceWorkingDayHours) {
public EffortDuration asDurationGivenWorkingDayOf(
EffortDuration resourceWorkingDayDuration) {
BigDecimal multiply = getAmount().multiply(
new BigDecimal(resourceWorkingDayHours));
if(multiply.compareTo(BigDecimal.ZERO)>0){
return Math.max(1, multiply.setScale(0, RoundingMode.HALF_UP)
.intValue());
new BigDecimal(resourceWorkingDayDuration.getSeconds()));
if (multiply.compareTo(BigDecimal.ZERO) > 0) {
return EffortDuration.elapsing(Math.max(1,
multiply.setScale(0, RoundingMode.HALF_UP).intValue()),
Granularity.SECONDS);
} else {
return 0;
return EffortDuration.zero();
}
}

View file

@ -60,6 +60,7 @@ import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.resources.entities.VirtualWorker;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.business.scenarios.entities.Scenario;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workingday.ResourcesPerDay;
public class GenericResourceAllocationTest {
@ -232,8 +233,9 @@ public class GenericResourceAllocationTest {
@Override
public Integer answer() throws Throwable {
ResourcesPerDay resourcesPerDay = (ResourcesPerDay) getCurrentArguments()[1];
return resourcesPerDay
.asHoursGivenResourceWorkingDayOf(hoursPerDay);
return BaseCalendar.roundToHours(resourcesPerDay
.asDurationGivenWorkingDayOf(EffortDuration
.hours(hoursPerDay)));
}
}).anyTimes();
expect(baseCalendar.canWork(isA(LocalDate.class))).andReturn(true)
@ -325,7 +327,8 @@ public class GenericResourceAllocationTest {
List<GenericDayAssignment> orderedAssignmentsFor = genericResourceAllocation
.getOrderedAssignmentsFor(worker1);
int hoursPerDay = resourcesPerDay.asHoursGivenResourceWorkingDayOf(8);
int hoursPerDay = resourcesPerDay.asDurationGivenWorkingDayOf(
EffortDuration.hours(8)).getHours();
assertThat(orderedAssignmentsFor, haveHours(hoursPerDay, hoursPerDay));
}
@ -347,7 +350,8 @@ public class GenericResourceAllocationTest {
List<GenericDayAssignment> orderedAssignmentsFor = genericResourceAllocation
.getOrderedAssignmentsFor(worker1);
int hoursPerDay = resourcesPerDay.asHoursGivenResourceWorkingDayOf(8);
int hoursPerDay = resourcesPerDay.asDurationGivenWorkingDayOf(
EffortDuration.hours(8)).getHours();
assertThat(orderedAssignmentsFor, haveHours(hoursPerDay, hoursPerDay));
}

View file

@ -49,12 +49,13 @@ import org.junit.Test;
import org.navalplanner.business.calendars.entities.AvailabilityTimeLine;
import org.navalplanner.business.calendars.entities.BaseCalendar;
import org.navalplanner.business.calendars.entities.ResourceCalendar;
import org.navalplanner.business.planner.entities.ResourceAllocation.DetachDayAssignmentOnRemoval;
import org.navalplanner.business.planner.entities.ResourceAllocation.IOnDayAssignmentRemoval;
import org.navalplanner.business.planner.entities.SpecificDayAssignment;
import org.navalplanner.business.planner.entities.SpecificResourceAllocation;
import org.navalplanner.business.planner.entities.Task;
import org.navalplanner.business.planner.entities.ResourceAllocation.DetachDayAssignmentOnRemoval;
import org.navalplanner.business.planner.entities.ResourceAllocation.IOnDayAssignmentRemoval;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workingday.ResourcesPerDay;
public class SpecificResourceAllocationTest {
@ -96,7 +97,9 @@ public class SpecificResourceAllocationTest {
public Integer answer() throws Throwable {
ResourcesPerDay perDay = (ResourcesPerDay) EasyMock
.getCurrentArguments()[1];
return perDay.asHoursGivenResourceWorkingDayOf(hours);
return BaseCalendar.roundToHours(perDay
.asDurationGivenWorkingDayOf(EffortDuration
.hours(hours)));
}
};
}

View file

@ -25,6 +25,9 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.navalplanner.business.workingday.EffortDuration.hours;
import static org.navalplanner.business.workingday.EffortDuration.seconds;
import static org.navalplanner.business.workingday.EffortDuration.zero;
import java.math.BigDecimal;
@ -32,6 +35,8 @@ import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Test;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workingday.EffortDuration.Granularity;
import org.navalplanner.business.workingday.ResourcesPerDay;
import org.navalplanner.business.workingday.ResourcesPerDay.ResourcesPerDayDistributor;
@ -107,17 +112,43 @@ public class ResourcesPerDayTest {
}
@Test
public void canBeConvertedToHoursGivenTheWorkingDayHours() {
public void canBeConvertedToDurationsGivenTheWorkingDayInDifferentGranularities() {
ResourcesPerDay units = ResourcesPerDay.amount(2);
assertThat(units.asHoursGivenResourceWorkingDayOf(8), equalTo(16));
for (Granularity each : Granularity.values()) {
assertThat(units.asDurationGivenWorkingDayOf(EffortDuration
.elapsing(8, each)), equalTo(EffortDuration.elapsing(16,
each)));
}
}
@Test
public void ifTheAmountIsDecimalTheRoundingIsHalfUp() {
ResourcesPerDay units = ResourcesPerDay.amount(new BigDecimal(2.4));
assertThat(units.asHoursGivenResourceWorkingDayOf(8), equalTo(19));
assertThat(units.asHoursGivenResourceWorkingDayOf(10), equalTo(24));
assertThat(units.asHoursGivenResourceWorkingDayOf(2), equalTo(5));
public void ifTheAmountIsDecimalTheSecondsAreMultiplied() {
ResourcesPerDay resourcesPerDay = ResourcesPerDay
.amount(new BigDecimal(2.4));
assertThat(resourcesPerDay.asDurationGivenWorkingDayOf(hours(8)),
equalTo(hours(19).and(12, Granularity.MINUTES)));
assertThat(resourcesPerDay.asDurationGivenWorkingDayOf(hours(10)),
equalTo(hours(24)));
assertThat(resourcesPerDay.asDurationGivenWorkingDayOf(hours(2)),
equalTo(hours(4).and(48, Granularity.MINUTES)));
}
@Test
public void theSecondsAreRoundedHalfUpUnlessItIsMinusThanOneSecond() {
ResourcesPerDay resourcesPerDay = ResourcesPerDay
.amount(new BigDecimal(2.4));
assertThat(resourcesPerDay.asDurationGivenWorkingDayOf(seconds(1)),
equalTo(seconds(2)));
assertThat(resourcesPerDay.asDurationGivenWorkingDayOf(seconds(2)),
equalTo(seconds(5)));
}
@Test
public void asSecondsMustReturnOneIfResultingAmountFromMultiplicationIsGreaterThanZero() {
ResourcesPerDay resourcesPerDay = ResourcesPerDay
.amount(new BigDecimal(0.1));
assertThat(resourcesPerDay.asDurationGivenWorkingDayOf(seconds(1)),
equalTo(seconds(1)));
}
@Test
@ -128,19 +159,11 @@ public class ResourcesPerDayTest {
assertEquals(a, b);
}
@Test
public void asHoursMustReturnOneIfAmountIsGreaterThanZero() {
ResourcesPerDay amount = ResourcesPerDay.amount(new BigDecimal(0.05));
int hours = amount
.asHoursGivenResourceWorkingDayOf(8);
assertThat(hours, equalTo(1));
}
@Test
public void ifTheAmountIsZeroMustReturnZero() {
ResourcesPerDay amount = ResourcesPerDay.amount(BigDecimal.ZERO);
int hours = amount.asHoursGivenResourceWorkingDayOf(8);
assertThat(hours, equalTo(0));
EffortDuration result = amount.asDurationGivenWorkingDayOf(hours(8));
assertThat(result, equalTo(zero()));
}
@Test