diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/BaseEntity.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/BaseEntity.java index ddd0ee8ef..458f706cb 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/common/BaseEntity.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/BaseEntity.java @@ -21,6 +21,12 @@ package org.navalplanner.business.common; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.validator.InvalidValue; @@ -41,6 +47,24 @@ import org.navalplanner.business.util.deepcopy.Strategy; */ public abstract class BaseEntity implements INewObject { + /** + * Groups the entities by id. Entities with null id are also included. + * + * @param entities + * @return entities grouped by id + */ + public static Map> byId( + Collection entities) { + Map> result = new HashMap>(); + for (T each : entities) { + if (!result.containsKey(each.getId())) { + result.put(each.getId(), new HashSet()); + } + result.get(each.getId()).add(each); + } + return result; + } + private static final Log LOG = LogFactory.getLog(BaseEntity.class); @OnCopy(Strategy.IGNORE) diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/AssignedEffortDiscounting.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/AssignedEffortDiscounting.java index 89e11a7f1..5f072777b 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/AssignedEffortDiscounting.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/AssignedEffortDiscounting.java @@ -20,21 +20,31 @@ */ package org.navalplanner.business.planner.entities; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + import org.joda.time.LocalDate; +import org.navalplanner.business.common.BaseEntity; import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.workingday.EffortDuration; public class AssignedEffortDiscounting implements IAssignedEffortForResource { - private final Object allocation; + private final Map> allocations; - AssignedEffortDiscounting(Object discountFrom) { - this.allocation = discountFrom; + public AssignedEffortDiscounting(BaseEntity allocationToDiscountFrom) { + this(Collections.singleton(allocationToDiscountFrom)); + } + + AssignedEffortDiscounting(Collection discountFrom) { + this.allocations = BaseEntity.byId(discountFrom); } public EffortDuration getAssignedDurationAt(Resource resource, LocalDate day) { - return resource.getAssignedDurationDiscounting(allocation, day); + return resource.getAssignedDurationDiscounting(allocations, day); } } \ No newline at end of file diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DayAssignment.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DayAssignment.java index 0e7a1801b..39b028b31 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DayAssignment.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DayAssignment.java @@ -267,7 +267,26 @@ public abstract class DayAssignment extends BaseEntity { protected abstract void detachFromAllocation(); - public abstract boolean belongsTo(Object allocation); + public final boolean belongsToSomeOf(Map> allocations) { + BaseEntity parent = getParent(); + if (parent.getId() == null) { + Set entitiesWithNullId = allocations.get(null); + return entitiesWithNullId != null + && entitiesWithNullId.contains(parent); + } + Set set = allocations.get(parent.getId()); + return set != null; + } + + protected abstract BaseEntity getParent(); + + public final boolean belongsTo(BaseEntity allocation) { + if (allocation == null) { + return false; + } + return belongsToSomeOf(BaseEntity.byId(Collections + .singleton(allocation))); + } /** * @return null if {@link DayAssignment this} day assignment diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DerivedDayAssignment.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DerivedDayAssignment.java index 4d17b1a53..b81a15a08 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DerivedDayAssignment.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DerivedDayAssignment.java @@ -25,6 +25,7 @@ import static org.navalplanner.business.workingday.EffortDuration.hours; import org.apache.commons.lang.Validate; import org.hibernate.validator.NotNull; import org.joda.time.LocalDate; +import org.navalplanner.business.common.BaseEntity; import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.Worker; import org.navalplanner.business.scenarios.entities.Scenario; @@ -165,9 +166,8 @@ public class DerivedDayAssignment extends DayAssignment { } @Override - public boolean belongsTo(Object allocation) { - return allocation != null - && parentState.getAllocation().equals(allocation); + protected BaseEntity getParent() { + return parentState.getAllocation(); } @Override diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/GenericDayAssignment.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/GenericDayAssignment.java index e142d14de..44b34c439 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/GenericDayAssignment.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/GenericDayAssignment.java @@ -30,6 +30,7 @@ import java.util.Set; import org.apache.commons.lang.Validate; import org.hibernate.validator.NotNull; import org.joda.time.LocalDate; +import org.navalplanner.business.common.BaseEntity; import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.scenarios.entities.Scenario; import org.navalplanner.business.util.deepcopy.OnCopy; @@ -195,9 +196,8 @@ public class GenericDayAssignment extends DayAssignment { } @Override - public boolean belongsTo(Object allocation) { - return allocation != null - && getGenericResourceAllocation().equals(allocation); + protected BaseEntity getParent() { + return getGenericResourceAllocation(); } @Override diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/SpecificDayAssignment.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/SpecificDayAssignment.java index 53b98556a..9660faefa 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/SpecificDayAssignment.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/SpecificDayAssignment.java @@ -30,6 +30,7 @@ import java.util.Set; import org.apache.commons.lang.Validate; import org.hibernate.validator.NotNull; import org.joda.time.LocalDate; +import org.navalplanner.business.common.BaseEntity; import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.scenarios.entities.Scenario; import org.navalplanner.business.util.deepcopy.OnCopy; @@ -186,9 +187,8 @@ public class SpecificDayAssignment extends DayAssignment { } @Override - public boolean belongsTo(Object resourceAllocation) { - return resourceAllocation != null - && getSpecificResourceAllocation().equals(resourceAllocation); + protected BaseEntity getParent() { + return getSpecificResourceAllocation(); } @Override diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Resource.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Resource.java index 6a9cbe567..267a1b982 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Resource.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Resource.java @@ -47,6 +47,7 @@ import org.navalplanner.business.calendars.entities.BaseCalendar; import org.navalplanner.business.calendars.entities.ICalendar; import org.navalplanner.business.calendars.entities.ResourceCalendar; import org.navalplanner.business.calendars.entities.SameWorkHoursEveryDay; +import org.navalplanner.business.common.BaseEntity; import org.navalplanner.business.common.IntegrationEntity; import org.navalplanner.business.common.Registry; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; @@ -845,10 +846,13 @@ public abstract class Resource extends IntegrationEntity { } public EffortDuration getAssignedDurationDiscounting( - Object alloationFromWhichDiscountHours, LocalDate day) { + Map> allocationsFromWhichDiscountHours, + LocalDate day) { EffortDuration result = zero(); for (DayAssignment dayAssignment : getAssignmentsForDay(day)) { - if (!dayAssignment.belongsTo(alloationFromWhichDiscountHours)) { + + if (!dayAssignment + .belongsToSomeOf(allocationsFromWhichDiscountHours)) { result = result.plus(dayAssignment.getDuration()); } } diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/DerivedAllocationGeneratorTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/DerivedAllocationGeneratorTest.java index a2ef5d64b..319fc896f 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/DerivedAllocationGeneratorTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/DerivedAllocationGeneratorTest.java @@ -125,7 +125,7 @@ public class DerivedAllocationGeneratorTest { private Worker workerWithAlwaysAssignedHours(int assignedHours){ Worker result = createNiceMock(Worker.class); expect( - result.getAssignedDurationDiscounting(isA(Object.class), + result.getAssignedDurationDiscounting(isA(Map.class), isA(LocalDate.class))).andReturn(hours(assignedHours)) .anyTimes(); replay(result); diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/GenericResourceAllocationTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/GenericResourceAllocationTest.java index 5169c0449..9299b2b43 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/GenericResourceAllocationTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/GenericResourceAllocationTest.java @@ -169,7 +169,7 @@ public class GenericResourceAllocationTest { public static void mockZeroLoad(Resource... resources) { for (Resource each : resources) { expect( - each.getAssignedDurationDiscounting(isA(Object.class), + each.getAssignedDurationDiscounting(isA(Map.class), isA(LocalDate.class))).andReturn(zero()).anyTimes(); } } @@ -223,7 +223,7 @@ public class GenericResourceAllocationTest { Worker result = createNiceMock(Worker.class); expect(result.getCalendar()).andReturn(resourceCalendar).anyTimes(); expect( - result.getAssignedDurationDiscounting(isA(Object.class), + result.getAssignedDurationDiscounting(isA(Map.class), isA(LocalDate.class))).andAnswer( new IAnswer() { @@ -807,7 +807,7 @@ public class GenericResourceAllocationTest { EffortDuration load) { VirtualWorker worker = createNiceMock(VirtualWorker.class); expect( - worker.getAssignedDurationDiscounting(isA(Object.class), + worker.getAssignedDurationDiscounting(isA(Map.class), isA(LocalDate.class))).andReturn(load) .anyTimes(); expect(worker.getCalendar()).andReturn(