Bug #1413: Fix bug
The methods used to calculate the start and end of the task when moving the task and when allocating in the form were different. This caused the length of the task to change when being moved. Now the method used when moving the task is the one always in use, because it's more precise.
This commit is contained in:
parent
d27fabbbeb
commit
4780b1fad0
3 changed files with 65 additions and 61 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue