[Bug #993] Add methods to increase and decrease a IntraDayDate

It takes into account the ResourcesPerDay used.

FEA: ItEr74S04BugFixing
This commit is contained in:
Óscar González Fernández 2011-04-18 15:40:37 +02:00
parent a5dc1f1888
commit 4d1e5c9f8b
2 changed files with 125 additions and 0 deletions

View file

@ -20,8 +20,11 @@
*/
package org.navalplanner.business.workingday;
import static org.navalplanner.business.workingday.EffortDuration.seconds;
import static org.navalplanner.business.workingday.EffortDuration.zero;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -388,4 +391,54 @@ public class IntraDayDate implements Comparable<IntraDayDate> {
return date;
}
/**
* Calculates a new {@link IntraDayDate} adding {@link EffortDuration
* effort} to {@link IntraDayDate this}. It considers the provided
* {@link ResourcesPerDay resourcesPerDay}, so if the resources per day is
* big the effort taken will be less. The date will stay the same, i.e. the
* returned {@link IntraDayDate} is on the same day.
*
* @param resourcesPerDay
* @param effort
* @return a new {@link IntraDayDate}
*/
public IntraDayDate increaseBy(ResourcesPerDay resourcesPerDay, EffortDuration effort) {
EffortDuration newEnd = this.getEffortDuration().plus(
calculateProportionalDuration(resourcesPerDay,
effort));
return IntraDayDate.create(getDate(), newEnd);
}
private EffortDuration calculateProportionalDuration(
ResourcesPerDay resourcesPerDay, EffortDuration effort) {
int seconds = effort.getSeconds();
BigDecimal end = new BigDecimal(seconds).divide(
resourcesPerDay.getAmount(),
RoundingMode.HALF_UP);
return seconds(end.intValue());
}
/**
* The same as
* {@link IntraDayDate#increaseBy(ResourcesPerDay, EffortDuration)} but
* decreasing the effort. The date will stay the same, i.e. the returned
* {@link IntraDayDate} is on the same day.
*
* @see IntraDayDate#increaseBy(ResourcesPerDay, EffortDuration)
* @param resourcesPerDay
* @param effort
* @return a new {@link IntraDayDate}
*/
public IntraDayDate decreaseBy(ResourcesPerDay resourcesPerDay,
EffortDuration effort) {
EffortDuration proportionalDuration = calculateProportionalDuration(
resourcesPerDay, effort);
if (getEffortDuration().compareTo(proportionalDuration) > 0) {
return IntraDayDate.create(getDate(),
getEffortDuration().minus(proportionalDuration));
} else {
return IntraDayDate.startOfDay(getDate());
}
}
}

View file

@ -30,6 +30,8 @@ import static org.navalplanner.business.workingday.EffortDuration.hours;
import static org.navalplanner.business.workingday.EffortDuration.minutes;
import static org.navalplanner.business.workingday.EffortDuration.zero;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -45,6 +47,7 @@ import org.navalplanner.business.workingday.EffortDuration.Granularity;
import org.navalplanner.business.workingday.IntraDayDate;
import org.navalplanner.business.workingday.IntraDayDate.PartialDay;
import org.navalplanner.business.workingday.IntraDayDate.UntilEnd;
import org.navalplanner.business.workingday.ResourcesPerDay;
/**
* @author Óscar González Fernández
@ -295,4 +298,73 @@ public class IntraDayDateTest {
assertThat(IntraDayDate.startOfDay(today).roundDown(), equalTo(today));
}
@Test
public void canIncreaseAnIntraDayDayBySomeEffort() {
LocalDate today = new LocalDate();
IntraDayDate intraDate = IntraDayDate.create(today, hours(2));
EffortDuration[] efforts = { hours(4), hours(8), hours(12), hours(0),
hours(16) };
for (EffortDuration effort : efforts) {
IntraDayDate newDay = intraDate.increaseBy(
ResourcesPerDay.amount(1), effort);
assertThat(newDay.getDate(), equalTo(today));
assertThat(newDay.getEffortDuration(), equalTo(hours(2)
.plus(effort)));
}
}
@Test
public void theAmountOfTheIncreaseDependsOnTheAmountOfResourcesPerDay() {
LocalDate today = new LocalDate();
IntraDayDate intraDate = IntraDayDate.startOfDay(today);
EffortDuration effort = hours(6);
ResourcesPerDay half = ResourcesPerDay.amount(new BigDecimal(BigInteger
.valueOf(5), 1));
ResourcesPerDay oneQuarter = ResourcesPerDay.amount(new BigDecimal(
BigInteger.valueOf(25), 2));
ResourcesPerDay[] resourcesPerDays = { ResourcesPerDay.amount(2),
ResourcesPerDay.amount(3), half, oneQuarter,
ResourcesPerDay.amount(4) };
EffortDuration[] ends = { hours(3), hours(2), hours(12), hours(24),
hours(1).and(30, Granularity.MINUTES) };
for (int i = 0; i < resourcesPerDays.length; i++) {
ResourcesPerDay r = resourcesPerDays[i];
EffortDuration end = ends[i];
IntraDayDate newDay = intraDate.increaseBy(r, effort);
assertThat(newDay.getDate(), equalTo(today));
assertThat(newDay.getEffortDuration(), equalTo(end));
}
}
@Test
public void canDecreaseAnIntraDayBySomeEffort() {
LocalDate today = new LocalDate();
IntraDayDate intraDate = IntraDayDate.create(today, hours(10));
EffortDuration[] efforts = { hours(4), hours(8), hours(5), hours(10),
hours(1) };
for (EffortDuration effort : efforts) {
IntraDayDate newDay = intraDate.decreaseBy(
ResourcesPerDay.amount(1), effort);
assertThat(newDay.getDate(), equalTo(today));
assertThat(newDay.getEffortDuration(),
equalTo(hours(10).minus(effort)));
}
}
@Test
public void theDateAlwaysKeepsBeingTheSameWhenDecreasing() {
LocalDate today = new LocalDate();
IntraDayDate intraDate = IntraDayDate.create(today, hours(10));
assertThat(intraDate.decreaseBy(ResourcesPerDay.amount(1), hours(12))
.getDate(), equalTo(today));
}
}