From 7afcef6525e06c4129547abe0d5a6298d25d35a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Fri, 11 May 2012 11:29:27 +0200 Subject: [PATCH] Bug #1428: Fix bug Provide a IAssignedEffortForResource that takes into account the allocations being done. mb:e98367a8-015e-492e-bffd-56ebbaca7720 --- .../entities/AssignedEffortForResource.java | 59 ++++++++++++++++++- .../entities/DerivedAllocationGenerator.java | 2 +- .../entities/GenericDayAssignment.java | 2 +- .../entities/GenericResourceAllocation.java | 15 +++-- .../planner/entities/ResourceAllocation.java | 9 ++- .../entities/SpecificDayAssignment.java | 6 +- .../UntilFillingHoursAllocator.java | 25 ++++---- .../web/planner/allocation/AllocationRow.java | 52 +++++++++++++--- .../allocation/GenericAllocationRow.java | 19 ++---- .../allocation/SpecificAllocationRow.java | 6 +- 10 files changed, 144 insertions(+), 51 deletions(-) diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/AssignedEffortForResource.java b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/AssignedEffortForResource.java index 32b8ae352..b4e7604fc 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/AssignedEffortForResource.java +++ b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/AssignedEffortForResource.java @@ -19,6 +19,7 @@ package org.libreplan.business.planner.entities; import java.util.Collection; +import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -38,11 +39,67 @@ public class AssignedEffortForResource { LocalDate day); } - public static IAssignedEffortForResource discount( + public static IAssignedEffortForResource effortDiscounting( Collection allocations) { return new AssignedEffortDiscounting(allocations); } + public static IAssignedEffortForResource sum( + final IAssignedEffortForResource... assignedEffortForResources) { + return new IAssignedEffortForResource() { + + @Override + public EffortDuration getAssignedDurationAt(Resource resource, + LocalDate day) { + EffortDuration result = EffortDuration.zero(); + for (IAssignedEffortForResource each : assignedEffortForResources) { + EffortDuration e = each + .getAssignedDurationAt(resource, day); + if (e != null) { + result = result.plus(e); + } + } + return result; + } + }; + } + + public static IAssignedEffortForResource sum( + Collection assignedEffortForResources) { + return sum(assignedEffortForResources + .toArray(new IAssignedEffortForResource[0])); + } + + public static WithTheLoadOf withTheLoadOf( + Collection> allocations) { + return new WithTheLoadOf(allocations); + } + + public static class WithTheLoadOf implements IAssignedEffortForResource { + + private final Set> allocations; + private final IAssignedEffortForResource implementation; + + public WithTheLoadOf( + Collection> allocations) { + this.allocations = new HashSet>(allocations); + this.implementation = sum(this.allocations); + } + + @Override + public EffortDuration getAssignedDurationAt(Resource resource, + LocalDate day) { + return implementation.getAssignedDurationAt(resource, day); + } + + public WithTheLoadOf withoutConsidering(ResourceAllocation allocation) { + Set> copy = new HashSet>( + this.allocations); + copy.remove(allocation); + return new WithTheLoadOf(copy); + } + } + private static class AssignedEffortDiscounting implements IAssignedEffortForResource { diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/DerivedAllocationGenerator.java b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/DerivedAllocationGenerator.java index 2ef8a1bfd..99c3991d2 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/DerivedAllocationGenerator.java +++ b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/DerivedAllocationGenerator.java @@ -105,7 +105,7 @@ public class DerivedAllocationGenerator { List dayAssignments) { List result = new ArrayList(); EffortDistributor distributor = new EffortDistributor(resourcesFound, - AssignedEffortForResource.discount(Collections.singletonList(parent))); + AssignedEffortForResource.effortDiscounting(Collections.singletonList(parent))); for (DayAssignment each : dayAssignments) { int durationInSeconds = alpha.multiply( new BigDecimal(each.getDuration().getSeconds())).intValue(); diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/GenericDayAssignment.java b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/GenericDayAssignment.java index 5dda538d3..c85d37f87 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/GenericDayAssignment.java +++ b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/GenericDayAssignment.java @@ -67,7 +67,7 @@ public class GenericDayAssignment extends DayAssignment { @Override ParentState setParent( GenericResourceAllocation genericResourceAllocation) { - if (parent != null) { + if (parent != null && parent != genericResourceAllocation) { throw new IllegalStateException( "the allocation cannot be changed once it has been set"); } diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/GenericResourceAllocation.java b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/GenericResourceAllocation.java index 3ed02c59c..34929c7a5 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/GenericResourceAllocation.java +++ b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/GenericResourceAllocation.java @@ -238,19 +238,18 @@ public class GenericResourceAllocation extends } - private IAssignedEffortForResource assignedEffortCalculatorOverriden = null; + private IAssignedEffortForResource assignedEffortForResource = null; - public void discountAssignedHoursForResourceFrom( - Collection> allocations) { - assignedEffortCalculatorOverriden = AssignedEffortForResource - .discount(allocations); + public void customAssignedEffortForResource( + IAssignedEffortForResource assignedEffortForResource) { + this.assignedEffortForResource = assignedEffortForResource; } private IAssignedEffortForResource getAssignedEffortForResource() { - if (assignedEffortCalculatorOverriden != null) { - return assignedEffortCalculatorOverriden; + if (assignedEffortForResource != null) { + return assignedEffortForResource; } - return AssignedEffortForResource.discount(Collections + return AssignedEffortForResource.effortDiscounting(Collections .singletonList(this)); } diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/ResourceAllocation.java b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/ResourceAllocation.java index aa8cb35e0..766519fea 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/ResourceAllocation.java +++ b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/ResourceAllocation.java @@ -53,6 +53,7 @@ import org.libreplan.business.calendars.entities.ThereAreHoursOnWorkHoursCalcula import org.libreplan.business.calendars.entities.ThereAreHoursOnWorkHoursCalculator.CapacityResult; import org.libreplan.business.common.BaseEntity; import org.libreplan.business.common.Registry; +import org.libreplan.business.planner.entities.AssignedEffortForResource.IAssignedEffortForResource; import org.libreplan.business.planner.entities.DerivedAllocationGenerator.IWorkerFinder; import org.libreplan.business.planner.entities.allocationalgorithms.AllocationModification; import org.libreplan.business.planner.entities.allocationalgorithms.AllocatorForTaskDurationAndSpecifiedResourcesPerDay; @@ -84,7 +85,7 @@ import org.libreplan.business.workingday.ResourcesPerDay; * Resources are allocated to planner tasks. */ public abstract class ResourceAllocation extends - BaseEntity { + BaseEntity implements IAssignedEffortForResource { private static final Log LOG = LogFactory.getLog(ResourceAllocation.class); @@ -1987,6 +1988,12 @@ public abstract class ResourceAllocation extends return getAssignedDuration(assignments, start, endExclusive); } + @Override + public EffortDuration getAssignedDurationAt(Resource resource, LocalDate day) { + IntraDayDate start = IntraDayDate.startOfDay(day); + return getAssignedEffort(resource, start, start.nextDayAtStart()); + } + private List getAssingments(final Resource resource, LocalDate startInclusive, LocalDate endExclusive) { return filter(getAssignments(startInclusive, endExclusive), diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/SpecificDayAssignment.java b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/SpecificDayAssignment.java index 5c63865d7..85c3eb7dd 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/SpecificDayAssignment.java +++ b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/SpecificDayAssignment.java @@ -67,12 +67,12 @@ public class SpecificDayAssignment extends DayAssignment { @Override ParentState setParent( - SpecificResourceAllocation genericResourceAllocation) { - if (parent != null) { + SpecificResourceAllocation specificResourceAllocation) { + if (parent != null && parent != specificResourceAllocation) { throw new IllegalStateException( "the allocation cannot be changed once it has been set"); } - this.parent = genericResourceAllocation; + this.parent = specificResourceAllocation; return this; } diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/allocationalgorithms/UntilFillingHoursAllocator.java b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/allocationalgorithms/UntilFillingHoursAllocator.java index f94c10808..79e5c105e 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/allocationalgorithms/UntilFillingHoursAllocator.java +++ b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/allocationalgorithms/UntilFillingHoursAllocator.java @@ -143,8 +143,13 @@ public abstract class UntilFillingHoursAllocator { current = nextDay(current); } } - return adjustFinish(resourcesPerDayModification, taken, + IntraDayDate finish = adjustFinish(resourcesPerDayModification, taken, biggestLastAssignment, current); + // we have to do it now, so the other allocations take into account. At + // the end it's done again with the right end date. + setNewDataForAllocation(resourcesPerDayModification, resultAssignments + .get(resourcesPerDayModification), finish); + return finish; } private IntraDayDate adjustFinish( @@ -231,21 +236,21 @@ public abstract class UntilFillingHoursAllocator { private void setAssignmentsForEachAllocation(IntraDayDate resultDate) { for (Entry> entry : resultAssignments .entrySet()) { - setNewDataForAllocation(entry, resultDate); + setNewDataForAllocation(entry.getKey(), entry.getValue(), + resultDate); } } private void setNewDataForAllocation( - Entry> entry, + ResourcesPerDayModification modification, + List value, IntraDayDate resultDate) { @SuppressWarnings("unchecked") - ResourceAllocation allocation = (ResourceAllocation) entry - .getKey().getBeingModified(); - ResourcesPerDay resourcesPerDay = entry.getKey().getGoal(); - @SuppressWarnings("unchecked") - List value = (List) entry.getValue(); - setNewDataForAllocation(allocation, resultDate, resourcesPerDay, - value); + ResourceAllocation allocation = (ResourceAllocation) modification + .getBeingModified(); + ResourcesPerDay resourcesPerDay = modification.getGoal(); + setNewDataForAllocation(allocation, resultDate, + resourcesPerDay, value); } protected Direction getDirection() { diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/AllocationRow.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/AllocationRow.java index 7fc22740f..9e4d00b06 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/AllocationRow.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/AllocationRow.java @@ -42,10 +42,14 @@ import org.libreplan.business.calendars.entities.ThereAreHoursOnWorkHoursCalcula import org.libreplan.business.calendars.entities.ThereAreHoursOnWorkHoursCalculator.ResourcesPerDayIsZero; import org.libreplan.business.calendars.entities.ThereAreHoursOnWorkHoursCalculator.ThereAreNoValidPeriods; import org.libreplan.business.calendars.entities.ThereAreHoursOnWorkHoursCalculator.ValidPeriodsDontHaveCapacity; +import org.libreplan.business.planner.entities.AssignedEffortForResource; +import org.libreplan.business.planner.entities.AssignedEffortForResource.IAssignedEffortForResource; +import org.libreplan.business.planner.entities.AssignedEffortForResource.WithTheLoadOf; import org.libreplan.business.planner.entities.AssignmentFunction; import org.libreplan.business.planner.entities.AssignmentFunction.AssignmentFunctionName; import org.libreplan.business.planner.entities.CalculatedValue; import org.libreplan.business.planner.entities.DerivedAllocation; +import org.libreplan.business.planner.entities.GenericResourceAllocation; import org.libreplan.business.planner.entities.ResourceAllocation; import org.libreplan.business.planner.entities.Task; import org.libreplan.business.planner.entities.Task.ModifiedAllocation; @@ -187,10 +191,43 @@ public abstract class AllocationRow { List result = new ArrayList(); for (AllocationRow each : rows) { ResourcesPerDayModification modification = each - .toResourcesPerDayModification(task, requestedToRemove); + .toResourcesPerDayModification(task); result.add(modification); each.setTemporal(modification.getBeingModified()); } + setCustomAssignedEffortForResource(rows, requestedToRemove); + return result; + } + + private static void setCustomAssignedEffortForResource( + Collection rows, + Collection> requestedToRemove) { + + List> allocationsToDiscount = getToDiscount(rows); + allocationsToDiscount.addAll(requestedToRemove); + + final IAssignedEffortForResource effortForResource = AssignedEffortForResource + .effortDiscounting(allocationsToDiscount); + List> beingModified = AllocationRow + .getTemporalFrom(rows); + final WithTheLoadOf withTheLoadOf = AssignedEffortForResource + .withTheLoadOf(beingModified); + + for (GenericResourceAllocation each : ResourceAllocation.getOfType(GenericResourceAllocation.class, beingModified)) { + IAssignedEffortForResource custom = AssignedEffortForResource.sum( + withTheLoadOf.withoutConsidering(each), effortForResource); + each.customAssignedEffortForResource(custom); + } + } + + private static List> getToDiscount( + Collection rows) { + List> result = new ArrayList>(); + for (AllocationRow each : rows) { + if (each.getOrigin() != null) { + result.add(each.getOrigin()); + } + } return result; } @@ -209,11 +246,12 @@ public abstract class AllocationRow { Collection> requestedToRemove) { List result = new ArrayList(); for (AllocationRow each : currentRows) { - EffortModification hoursModification = each.toHoursModification( - task, requestedToRemove); + EffortModification hoursModification = each + .toHoursModification(task); result.add(hoursModification); each.setTemporal(hoursModification.getBeingModified()); } + setCustomAssignedEffortForResource(currentRows, requestedToRemove); return result; } @@ -242,7 +280,7 @@ public abstract class AllocationRow { } public static List> getTemporalFrom( - List rows) { + Collection rows) { List> result = new ArrayList>(); for (AllocationRow each : rows) { if (each.temporal != null) { @@ -379,11 +417,9 @@ public abstract class AllocationRow { } public abstract ResourcesPerDayModification toResourcesPerDayModification( - Task task, - Collection> requestedToRemove); + Task task); - public abstract EffortModification toHoursModification(Task task, - Collection> requestedToRemove); + public abstract EffortModification toHoursModification(Task task); public boolean isCreating() { return origin == null; diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/GenericAllocationRow.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/GenericAllocationRow.java index 9b8927ea5..126052867 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/GenericAllocationRow.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/GenericAllocationRow.java @@ -124,35 +124,26 @@ public class GenericAllocationRow extends AllocationRow { } @Override - public ResourcesPerDayModification toResourcesPerDayModification(Task task, - Collection> requestedToRemove) { - GenericResourceAllocation newGeneric = createGenericAllocation(task, - requestedToRemove); + public ResourcesPerDayModification toResourcesPerDayModification(Task task) { + GenericResourceAllocation newGeneric = createGenericAllocation(task); return ResourcesPerDayModification .create(newGeneric, getResourcesPerDayEditedValue(), this.resources); } - private GenericResourceAllocation createGenericAllocation(Task task, - Collection> allocationsRemoved) { + private GenericResourceAllocation createGenericAllocation(Task task) { GenericResourceAllocation result = GenericResourceAllocation.create( task, resourceType, criterions); GenericResourceAllocation origin = (GenericResourceAllocation) getOrigin(); - Set> discountFrom = new HashSet>( - allocationsRemoved); if (origin != null) { result.overrideConsolidatedDayAssignments(origin); - discountFrom.add(origin); result.setAssignmentFunctionWithoutApply(origin.getAssignmentFunction()); } - result.discountAssignedHoursForResourceFrom(discountFrom); return result; } @Override - public EffortModification toHoursModification(Task task, - Collection> requestedToRemove) { - return EffortModification.create( - createGenericAllocation(task, requestedToRemove), + public EffortModification toHoursModification(Task task) { + return EffortModification.create(createGenericAllocation(task), getEffortFromInput(), resources); } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/SpecificAllocationRow.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/SpecificAllocationRow.java index 0b54ebbd4..00eeb4175 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/SpecificAllocationRow.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/SpecificAllocationRow.java @@ -116,8 +116,7 @@ public class SpecificAllocationRow extends AllocationRow { } @Override - public ResourcesPerDayModification toResourcesPerDayModification(Task task, - Collection> requestedToRemove) { + public ResourcesPerDayModification toResourcesPerDayModification(Task task) { return ResourcesPerDayModification.create(createSpecific(task), getResourcesPerDayEditedValue()); } @@ -135,8 +134,7 @@ public class SpecificAllocationRow extends AllocationRow { } @Override - public EffortModification toHoursModification(Task task, - Collection> requestedToRemove) { + public EffortModification toHoursModification(Task task) { return EffortModification.create(createSpecific(task), getEffortFromInput()); }