From 4d1e5c9f8b2ecbebea4fb9fdbf308136bec3e870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Mon, 18 Apr 2011 15:40:37 +0200 Subject: [PATCH] [Bug #993] Add methods to increase and decrease a IntraDayDate It takes into account the ResourcesPerDay used. FEA: ItEr74S04BugFixing --- .../business/workingday/IntraDayDate.java | 53 ++++++++++++++ .../test/workingday/IntraDayDateTest.java | 72 +++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/workingday/IntraDayDate.java b/navalplanner-business/src/main/java/org/navalplanner/business/workingday/IntraDayDate.java index 0246c1d49..75f789481 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/workingday/IntraDayDate.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/workingday/IntraDayDate.java @@ -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 { 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()); + } + } + } diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/workingday/IntraDayDateTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/workingday/IntraDayDateTest.java index d0ef32d57..5c1798f5a 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/workingday/IntraDayDateTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/workingday/IntraDayDateTest.java @@ -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)); + } + }