diff --git a/libreplan-business/src/main/java/org/libreplan/business/workingday/IntraDayDate.java b/libreplan-business/src/main/java/org/libreplan/business/workingday/IntraDayDate.java index 1945af828..05f17da15 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/workingday/IntraDayDate.java +++ b/libreplan-business/src/main/java/org/libreplan/business/workingday/IntraDayDate.java @@ -3,7 +3,7 @@ * * 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. + * Copyright (C) 2010-2012 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 @@ -70,7 +70,9 @@ import org.libreplan.business.calendars.entities.Capacity; * @see PartialDay * @see LocalDate * @see EffortDuration + * * @author Óscar González Fernández + * @author Manuel Rego Casasnovas * */ public class IntraDayDate implements Comparable { @@ -497,4 +499,57 @@ public class IntraDayDate implements Comparable { return startOfDay(date); } + /** + * Returns the {@link EffortDuration} until {@code end} considering 8h per + * day of effort. + * + * @param end + * @return The {@link EffortDuration} until {@code end} + */ + public EffortDuration effortUntil(IntraDayDate end) { + Validate.isTrue(compareTo(end) <= 0); + int days = Days.daysBetween(getDate(), end.getDate()).getDays(); + + EffortDuration result = EffortDuration.hours(days * 8); + + if (!getEffortDuration().isZero()) { + result = result.minus(EffortDuration.hours(8)); + result = result.plus(EffortDuration.hours(8).minus( + getEffortDuration())); + } + + if (!end.getEffortDuration().isZero()) { + result = result.plus(end.getEffortDuration()); + } + + return result; + } + + /** + * Returns the {@link IntraDayDate} adding the {@code effort} considering 8h + * per day of effort. + * + * @param effort + * @return The {@link IntraDayDate} result of adding the {@code effort} + */ + public IntraDayDate addEffort(EffortDuration effort) { + int secondsPerDay = 3600 * 8; + + int seconds = effort.getSeconds(); + + if (!getEffortDuration().isZero()) { + seconds += getEffortDuration().getSeconds(); + } + + int days = seconds / secondsPerDay; + + EffortDuration extraEffort = EffortDuration.zero(); + int extra = seconds % secondsPerDay; + if (extra != 0) { + extraEffort = extraEffort.plus(EffortDuration.seconds(extra)); + } + + return IntraDayDate.create(getDate().plusDays(days), extraEffort); + } + } diff --git a/libreplan-business/src/test/java/org/libreplan/business/test/workingday/IntraDayDateTest.java b/libreplan-business/src/test/java/org/libreplan/business/test/workingday/IntraDayDateTest.java index 783ff0604..67bc0a733 100644 --- a/libreplan-business/src/test/java/org/libreplan/business/test/workingday/IntraDayDateTest.java +++ b/libreplan-business/src/test/java/org/libreplan/business/test/workingday/IntraDayDateTest.java @@ -3,7 +3,7 @@ * * 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. + * Copyright (C) 2010-2012 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 @@ -51,7 +51,7 @@ import org.libreplan.business.workingday.ResourcesPerDay; /** * @author Óscar González Fernández - * + * @author Manuel Rego Casasnovas */ public class IntraDayDateTest { @@ -367,4 +367,79 @@ public class IntraDayDateTest { .getDate(), equalTo(today)); } + @Test + public void calculateEffortBetweenTwoDates() { + IntraDayDate start = IntraDayDate.create(today, zero()); + IntraDayDate end = IntraDayDate.create(today.plusDays(3), hours(0)); + + assertThat(start.effortUntil(end), equalTo(hours(8 * 3))); + + end = IntraDayDate.create(today.plusDays(3), hours(8)); + assertThat(start.effortUntil(end), equalTo(hours(8 * 4))); + + start = IntraDayDate.create(today, hours(8)); + end = IntraDayDate.create(today.plusDays(3), hours(0)); + assertThat(start.effortUntil(end), equalTo(hours(8 * 2))); + + start = IntraDayDate.create(today, hours(3)); + assertThat(start.effortUntil(end), equalTo(hours(8 * 2 + 5))); + + end = IntraDayDate.create(today.plusDays(3), hours(6)); + assertThat(start.effortUntil(end), equalTo(hours(8 * 2 + 5 + 6))); + + end = IntraDayDate.create(today.plusDays(3), minutes(30)); + assertThat(start.effortUntil(end), + equalTo(hours(8 * 2 + 5).plus(minutes(30)))); + + start = IntraDayDate.create(today, hours(5).plus(minutes(40))); + assertThat(start.effortUntil(end), + equalTo(hours(8 * 2 + 2).plus(minutes(50)))); + } + + @Test + public void calculateAddEffort() { + IntraDayDate start = IntraDayDate.create(today, zero()); + + assertThat(start.addEffort(hours(24)), + equalTo(IntraDayDate.create(today.plusDays(3), hours(0)))); + + assertThat(start.addEffort(hours(20)), + equalTo(IntraDayDate.create(today.plusDays(2), hours(4)))); + + assertThat( + start.addEffort(hours(20).plus(minutes(20))), + equalTo(IntraDayDate.create(today.plusDays(2), + hours(4).plus(minutes(20))))); + + start = IntraDayDate.create(today, hours(3)); + assertThat(start.addEffort(hours(24)), + equalTo(IntraDayDate.create(today.plusDays(3), hours(3)))); + + assertThat(start.addEffort(hours(20)), + equalTo(IntraDayDate.create(today.plusDays(2), hours(7)))); + + assertThat(start.addEffort(hours(20).plus(minutes(20))), + equalTo(IntraDayDate.create(today.plusDays(2), + hours(7).plus(minutes(20))))); + + start = IntraDayDate.create(today, hours(3).plus(minutes(40))); + assertThat( + start.addEffort(hours(24)), + equalTo(IntraDayDate.create(today.plusDays(3), + hours(3).plus(minutes(40))))); + + assertThat( + start.addEffort(hours(20)), + equalTo(IntraDayDate.create(today.plusDays(2), + hours(7).plus(minutes(40))))); + + assertThat(start.addEffort(hours(20).plus(minutes(20))), + equalTo(IntraDayDate.create(today.plusDays(3), hours(0)))); + + assertThat( + start.addEffort(hours(20).plus(minutes(10))), + equalTo(IntraDayDate.create(today.plusDays(2), + hours(7).plus(minutes(50))))); + } + } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/TaskElementAdapter.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/TaskElementAdapter.java index c83ae631f..0492c60ff 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/TaskElementAdapter.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/TaskElementAdapter.java @@ -600,7 +600,24 @@ public class TaskElementAdapter { @Override public GanttDate getMoneyCostBarEndDate() { - return calculateLimitDateByPercentage(getMoneyCostBarPercentage()); + return calculateLimitDateProportionalToTaskElementSize(getMoneyCostBarPercentage()); + } + + private GanttDate calculateLimitDateProportionalToTaskElementSize( + BigDecimal proportion) { + if (proportion.compareTo(BigDecimal.ZERO) == 0) { + return getBeginDate(); + } + + IntraDayDate start = taskElement.getIntraDayStartDate(); + IntraDayDate end = taskElement.getIntraDayEndDate(); + + EffortDuration effortBetween = start.effortUntil(end); + int seconds = new BigDecimal(effortBetween.getSeconds()) + .multiply(proportion).toBigInteger().intValue(); + return TaskElementAdapter.toGantt( + start.addEffort(EffortDuration.seconds(seconds)), + EffortDuration.hours(8)); } private BigDecimal getMoneyCostBarPercentage() {