[Bug #989] Support discounting the hours of several allocations

FEA: ItEr74S04BugFixing
This commit is contained in:
Óscar González Fernández 2011-04-15 13:44:58 +02:00
parent e03d524613
commit e7bf3dc4dd
9 changed files with 77 additions and 20 deletions

View file

@ -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 <T extends BaseEntity> Map<Long, Set<T>> byId(
Collection<? extends T> entities) {
Map<Long, Set<T>> result = new HashMap<Long, Set<T>>();
for (T each : entities) {
if (!result.containsKey(each.getId())) {
result.put(each.getId(), new HashSet<T>());
}
result.get(each.getId()).add(each);
}
return result;
}
private static final Log LOG = LogFactory.getLog(BaseEntity.class);
@OnCopy(Strategy.IGNORE)

View file

@ -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<Long, Set<BaseEntity>> allocations;
AssignedEffortDiscounting(Object discountFrom) {
this.allocation = discountFrom;
public AssignedEffortDiscounting(BaseEntity allocationToDiscountFrom) {
this(Collections.singleton(allocationToDiscountFrom));
}
AssignedEffortDiscounting(Collection<? extends BaseEntity> discountFrom) {
this.allocations = BaseEntity.byId(discountFrom);
}
public EffortDuration getAssignedDurationAt(Resource resource, LocalDate day) {
return resource.getAssignedDurationDiscounting(allocation, day);
return resource.getAssignedDurationDiscounting(allocations, day);
}
}

View file

@ -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<Long, Set<BaseEntity>> allocations) {
BaseEntity parent = getParent();
if (parent.getId() == null) {
Set<BaseEntity> entitiesWithNullId = allocations.get(null);
return entitiesWithNullId != null
&& entitiesWithNullId.contains(parent);
}
Set<BaseEntity> 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 <code>null</code> if {@link DayAssignment this} day assignment

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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<Long, Set<BaseEntity>> allocationsFromWhichDiscountHours,
LocalDate day) {
EffortDuration result = zero();
for (DayAssignment dayAssignment : getAssignmentsForDay(day)) {
if (!dayAssignment.belongsTo(alloationFromWhichDiscountHours)) {
if (!dayAssignment
.belongsToSomeOf(allocationsFromWhichDiscountHours)) {
result = result.plus(dayAssignment.getDuration());
}
}

View file

@ -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);

View file

@ -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<EffortDuration>() {
@ -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(