diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/Task.java b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/Task.java index 506e84b7b..d5dd84418 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/Task.java +++ b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/Task.java @@ -581,6 +581,18 @@ public class Task extends TaskElement implements ITaskPositionConstrained { return durationBetweenDates.fromStartToEnd(newStartDate); } + public IntraDayDate calculateEndGivenWorkableDays(int days) { + Validate.isTrue(days >= 0); + DurationBetweenDates duration = fromFixedDuration(days); + return duration.fromStartToEnd(getIntraDayStartDate()); + } + + public IntraDayDate calculateStartGivenWorkableDays(int days) { + Validate.isTrue(days >= 0); + DurationBetweenDates duration = fromFixedDuration(days); + return duration.fromEndToStart(getIntraDayEndDate()); + } + private IntraDayDate calculateStartKeepingLength(IntraDayDate newEnd) { DurationBetweenDates durationBetweenDates = getDurationBetweenDates(); return durationBetweenDates.fromEndToStart(newEnd); @@ -645,12 +657,23 @@ public class Task extends TaskElement implements ITaskPositionConstrained { } public IntraDayDate fromStartToEnd(IntraDayDate newStartDate) { - LocalDate resultDay = calculateEndGivenWorkableDays( + LocalDate resultDay = afterSomeWorkableDays( newStartDate.getDate(), numberOfWorkableDays); return plusDuration(IntraDayDate.startOfDay(resultDay), remainderDuration.plus(newStartDate.getEffortDuration())); } + private LocalDate afterSomeWorkableDays(LocalDate start, + int workableDays) { + LocalDate result = start; + for (int i = 0; i < workableDays; result = result.plusDays(1)) { + if (isWorkable(result)) { + i++; + } + } + return result; + } + private IntraDayDate plusDuration(IntraDayDate start, EffortDuration remaining) { IntraDayDate result = IntraDayDate.startOfDay(start.getDate()); @@ -699,13 +722,23 @@ public class Task extends TaskElement implements ITaskPositionConstrained { } public IntraDayDate fromEndToStart(IntraDayDate newEnd) { - LocalDate resultDay = calculateStartGivenWorkableDays( + LocalDate resultDay = someWorkableDaysBefore( newEnd.getDate(), numberOfWorkableDays); return minusDuration(plusDuration( IntraDayDate.startOfDay(resultDay), newEnd.getEffortDuration()), remainderDuration); } + private LocalDate someWorkableDaysBefore(LocalDate end, int workableDays) { + LocalDate result = end; + for (int i = 0; i < workableDays; result = result.minusDays(1)) { + if (isWorkable(result.minusDays(1))) { + i++; + } + } + return result; + } + private IntraDayDate minusDuration(IntraDayDate date, EffortDuration decrement) { IntraDayDate result = IntraDayDate.create( @@ -1060,38 +1093,6 @@ public class Task extends TaskElement implements ITaskPositionConstrained { return result; } - public LocalDate calculateEndGivenWorkableDays(int workableDays) { - return calculateEndGivenWorkableDays(getIntraDayStartDate().getDate(), - workableDays); - } - - public LocalDate calculateStartGivenWorkableDays(int workableDays) { - return calculateStartGivenWorkableDays(getEndAsLocalDate(), - workableDays); - } - - private LocalDate calculateEndGivenWorkableDays(LocalDate start, - int workableDays) { - LocalDate result = start; - for (int i = 0; i < workableDays; result = result.plusDays(1)) { - if (isWorkable(result)) { - i++; - } - } - return result; - } - - private LocalDate calculateStartGivenWorkableDays(LocalDate end, - int workableDays) { - LocalDate result = end; - for (int i = 0; i < workableDays; result = result.minusDays(1)) { - if (isWorkable(result.minusDays(1))) { - i++; - } - } - return result; - } - private boolean isWorkable(LocalDate day) { ICalendar calendar = getCalendar(); assert calendar != null; diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/AllocationRowsHandler.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/AllocationRowsHandler.java index 5f287a753..b861f7a0d 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/AllocationRowsHandler.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/AllocationRowsHandler.java @@ -50,7 +50,6 @@ import org.libreplan.business.resources.entities.ResourceEnum; import org.libreplan.business.scenarios.entities.Scenario; import org.libreplan.business.workingday.EffortDuration; import org.libreplan.business.workingday.EffortDuration.IEffortFrom; -import org.libreplan.business.workingday.IntraDayDate; public class AllocationRowsHandler { @@ -299,10 +298,10 @@ public class AllocationRowsHandler { .createAndAssociate(task, currentRows, requestedToRemove); if (isForwardsAllocation()) { ResourceAllocation.allocating(allocations).allocateUntil( - formBinder.getAllocationEnd()); + formBinder.getAllocationEnd().asExclusiveEnd()); } else { ResourceAllocation.allocating(allocations).allocateFromEndUntil( - formBinder.getAllocationStart()); + formBinder.getAllocationStart().getDate()); } return allocations; } @@ -343,10 +342,10 @@ public class AllocationRowsHandler { requestedToRemove); if (isForwardsAllocation()) { ResourceAllocation.allocatingHours(hours).allocateUntil( - IntraDayDate.startOfDay(formBinder.getAllocationEnd())); + formBinder.getAllocationEnd()); } else { ResourceAllocation.allocatingHours(hours).allocateFromEndUntil( - IntraDayDate.startOfDay(formBinder.getAllocationStart())); + formBinder.getAllocationStart()); } return hours; } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/FormBinder.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/FormBinder.java index 01ce78435..ca0610ffb 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/FormBinder.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/FormBinder.java @@ -51,6 +51,7 @@ import org.libreplan.business.resources.entities.Resource; import org.libreplan.business.resources.entities.ResourceEnum; import org.libreplan.business.scenarios.entities.Scenario; import org.libreplan.business.workingday.EffortDuration; +import org.libreplan.business.workingday.IntraDayDate; import org.libreplan.business.workingday.ResourcesPerDay; import org.libreplan.web.common.EffortDurationBox; import org.libreplan.web.common.IMessagesForUser; @@ -307,34 +308,36 @@ public class FormBinder { Task task = getTask(); Integer workableDays = taskWorkableDays.getValue(); if (allocationRowsHandler.isForwardsAllocation()) { - LocalDate newEnd = ensureItIsAfterConsolidation( - task.calculateEndGivenWorkableDays(workableDays)); + IntraDayDate newEnd = ensureItIsAfterConsolidation(task + .calculateEndGivenWorkableDays(workableDays)); updateWorkableDaysIfNecessary(workableDays, - getTask().getStartAsLocalDate(), newEnd); + getTask().getIntraDayStartDate(), + newEnd); taskPropertiesController - .updateTaskEndDate(newEnd); - showValueOfDateOn(labelTaskEnd, newEnd); + .updateTaskEndDate(newEnd.getDate()); + showValueOfDateOn(labelTaskEnd, + newEnd.getDate()); } else { - LocalDate newStart = ensureItIsAfterConsolidation(task + IntraDayDate newStart = ensureItIsAfterConsolidation(task .calculateStartGivenWorkableDays(workableDays)); updateWorkableDaysIfNecessary(workableDays, - newStart, task.getIntraDayEndDate() - .asExclusiveEnd()); + newStart, task.getIntraDayEndDate()); taskPropertiesController - .updateTaskStartDate(newStart); - showValueOfDateOn(labelTaskStart, newStart); + .updateTaskStartDate(newStart.getDate()); + showValueOfDateOn(labelTaskStart, + newStart.getDate()); } } private void updateWorkableDaysIfNecessary( int specifiedWorkableDays, - LocalDate allocationStart, - LocalDate allocationEnd) { + IntraDayDate allocationStart, + IntraDayDate allocationEnd) { Integer effectiveWorkableDays = getTask() - .getWorkableDaysFrom(allocationStart, - allocationEnd); - if (!effectiveWorkableDays - .equals(specifiedWorkableDays)) { + .getWorkableDaysFrom( + allocationStart.getDate(), + allocationEnd.asExclusiveEnd()); + if (effectiveWorkableDays < specifiedWorkableDays) { Clients.response(new AuWrongValue( taskWorkableDays, _("The original workable days value {0} cannot be modified as it has consolidations", @@ -345,10 +348,10 @@ public class FormBinder { } @SuppressWarnings("unchecked") - private LocalDate ensureItIsAfterConsolidation( - LocalDate newDate) { + private IntraDayDate ensureItIsAfterConsolidation( + IntraDayDate newDate) { return Collections.max(Arrays.asList(newDate, - firstPossibleDay)); + IntraDayDate.startOfDay(firstPossibleDay))); } }, onChangeEnableApply); @@ -403,7 +406,8 @@ public class FormBinder { taskWorkableDays.setValue(lastSpecifiedWorkableDays); showValueOfDateOn( labelTaskEnd, - task.calculateEndGivenWorkableDays(lastSpecifiedWorkableDays)); + task.calculateEndGivenWorkableDays( + lastSpecifiedWorkableDays).getDate()); lastSpecifiedWorkableDays = null; } } @@ -436,12 +440,12 @@ public class FormBinder { | SimpleConstraint.NO_NEGATIVE); } - public LocalDate getAllocationEnd() { + public IntraDayDate getAllocationEnd() { return getTask().calculateEndGivenWorkableDays( workableDaysAndDatesBinder.getValue()); } - public LocalDate getAllocationStart() { + public IntraDayDate getAllocationStart() { return getTask().calculateStartGivenWorkableDays( workableDaysAndDatesBinder.getValue()); }