diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/Order.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/Order.java index cfb04ecbe..8ab979612 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/Order.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/Order.java @@ -171,9 +171,9 @@ public class Order extends OrderLineGroup { deepCopyWithNeededReplaces(newOrderVersion), newOrderVersion); useSchedulingDataFor(currentScenario); + removeSpuriousDayAssignments(currentScenario); } - private DeepCopy deepCopyWithNeededReplaces( OrderVersion newOrderVersion) { DeepCopy result = new DeepCopy(); @@ -511,5 +511,4 @@ public class Order extends OrderLineGroup { public void setOrderVersion(Scenario scenario, OrderVersion newOrderVersion) { scenarios.put(scenario, newOrderVersion); } - } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderElement.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderElement.java index 8c38ddf18..496bca253 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderElement.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderElement.java @@ -31,6 +31,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Map.Entry; import org.apache.commons.lang.Validate; import org.hibernate.validator.AssertTrue; @@ -63,6 +64,7 @@ import org.navalplanner.business.requirements.entities.CriterionRequirement; import org.navalplanner.business.requirements.entities.DirectCriterionRequirement; import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement; import org.navalplanner.business.scenarios.entities.OrderVersion; +import org.navalplanner.business.scenarios.entities.Scenario; import org.navalplanner.business.templates.entities.OrderElementTemplate; import org.navalplanner.business.trees.ITreeNode; import org.navalplanner.business.util.deepcopy.DeepCopy; @@ -216,6 +218,32 @@ public abstract class OrderElement extends IntegrationEntity implements writeSchedulingDataChanges(); } + protected void removeSpuriousDayAssignments(Scenario scenario) { + removeAtNotCurrent(scenario); + removeAtCurrent(scenario); + for (OrderElement each : getChildren()) { + each.removeSpuriousDayAssignments(scenario); + } + } + + private void removeAtNotCurrent(Scenario scenario) { + SchedulingDataForVersion currentDataForVersion = getCurrentSchedulingDataForVersion(); + for (Entry each : schedulingDatasForVersion + .entrySet()) { + SchedulingDataForVersion dataForVersion = each.getValue(); + if (!currentDataForVersion.equals(dataForVersion)) { + dataForVersion.removeSpuriousDayAssignments(scenario); + } + } + } + + private void removeAtCurrent(Scenario scenario) { + TaskElement associatedTaskElement = getAssociatedTaskElement(); + if (associatedTaskElement != null) { + associatedTaskElement.removePredecessorsDayAssignmentsFor(scenario); + } + } + public List calculateSynchronizationsNeeded() { SchedulingDataForVersion schedulingDataForVersion = getCurrentSchedulingData() .getVersion(); @@ -771,6 +799,12 @@ public abstract class OrderElement extends IntegrationEntity implements return result; } + public List getAllScenariosTaskSourcesFromBottomToTop() { + List result = new ArrayList(); + allScenariosTaskSourcesFromBottomToTop(result); + return result; + } + public List getSchedulingDatasForVersionFromBottomToTop() { List result = new ArrayList(); schedulingDataForVersionFromBottomToTop(result); @@ -794,6 +828,19 @@ public abstract class OrderElement extends IntegrationEntity implements } } + private void allScenariosTaskSourcesFromBottomToTop(List result) { + for (OrderElement each : getChildren()) { + each.allScenariosTaskSourcesFromBottomToTop(result); + } + for (Entry each : schedulingDatasForVersion + .entrySet()) { + TaskSource taskSource = each.getValue().getTaskSource(); + if (taskSource != null) { + result.add(taskSource); + } + } + } + @Valid public Set getMaterialAssignments() { return Collections.unmodifiableSet(materialAssignments); diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/SchedulingDataForVersion.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/SchedulingDataForVersion.java index b797a61d9..8156bfd22 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/SchedulingDataForVersion.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/SchedulingDataForVersion.java @@ -25,7 +25,9 @@ import org.hibernate.validator.Valid; import org.navalplanner.business.common.BaseEntity; import org.navalplanner.business.orders.entities.SchedulingState.ITypeChangedListener; import org.navalplanner.business.orders.entities.SchedulingState.Type; +import org.navalplanner.business.planner.entities.TaskElement; import org.navalplanner.business.scenarios.entities.OrderVersion; +import org.navalplanner.business.scenarios.entities.Scenario; import org.navalplanner.business.util.deepcopy.DeepCopy; /** @@ -179,4 +181,12 @@ public class SchedulingDataForVersion extends BaseEntity { return Data.from(this, orderVersion); } + void removeSpuriousDayAssignments(Scenario scenario) { + TaskSource taskSource = getTaskSource(); + if (taskSource != null) { + TaskElement task = taskSource.getTask(); + task.removeDayAssignmentsFor(scenario); + } + } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DerivedAllocation.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DerivedAllocation.java index 5e3a4ab39..bdcca78fa 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DerivedAllocation.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DerivedAllocation.java @@ -362,4 +362,21 @@ public class DerivedAllocation extends BaseEntity { toContainer.resetAssignmentsTo(fromContainer.getDayAssignments()); } + public void removePredecessorContainersFor(Scenario scenario) { + Map byScenario = byScenario(); + for (Scenario each : scenario.getPredecessors()) { + DerivedDayAssignmentsContainer container = byScenario.get(each); + if (container != null) { + derivedDayAssignmentsContainers.remove(container); + } + } + } + + public void removeContainersFor(Scenario scenario) { + DerivedDayAssignmentsContainer container = byScenario().get(scenario); + if (container != null) { + derivedDayAssignmentsContainers.remove(container); + } + } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/GenericResourceAllocation.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/GenericResourceAllocation.java index 2dcc911a5..eedf5dc6c 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/GenericResourceAllocation.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/GenericResourceAllocation.java @@ -512,4 +512,24 @@ public class GenericResourceAllocation extends toContainer.resetTo(fromContainer.getDayAssignments()); } + @Override + protected void removePredecessorContainersFor(Scenario scenario) { + Map byScenario = containersByScenario(); + for (Scenario each : scenario.getPredecessors()) { + GenericDayAssignmentsContainer container = byScenario.get(each); + if (container != null) { + genericDayAssignmentsContainers.remove(container); + } + } + } + + @Override + protected void removeContainersFor(Scenario scenario) { + GenericDayAssignmentsContainer container = containersByScenario().get( + scenario); + if (container != null) { + genericDayAssignmentsContainers.remove(container); + } + } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/ResourceAllocation.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/ResourceAllocation.java index 01f725718..47a8fabb7 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/ResourceAllocation.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/ResourceAllocation.java @@ -1088,4 +1088,22 @@ public abstract class ResourceAllocation extends public abstract void makeAssignmentsContainersDontPoseAsTransientAnyMore(); + public void removePredecessorsDayAssignmentsFor(Scenario scenario) { + for (DerivedAllocation each : getDerivedAllocations()) { + each.removePredecessorContainersFor(scenario); + } + removePredecessorContainersFor(scenario); + } + + protected abstract void removePredecessorContainersFor(Scenario scenario); + + public void removeDayAssigmentsFor(Scenario scenario) { + for (DerivedAllocation each : getDerivedAllocations()) { + each.removeContainersFor(scenario); + } + removeContainersFor(scenario); + } + + protected abstract void removeContainersFor(Scenario scenario); + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/SpecificResourceAllocation.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/SpecificResourceAllocation.java index 29d75e8fa..ca05054f9 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/SpecificResourceAllocation.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/SpecificResourceAllocation.java @@ -405,4 +405,24 @@ public class SpecificResourceAllocation extends toContainer.resetTo(fromContainer.getDayAssignments()); } + @Override + protected void removePredecessorContainersFor(Scenario scenario) { + Map byScenario = containersByScenario(); + for (Scenario each : scenario.getPredecessors()) { + SpecificDayAssignmentsContainer container = byScenario.get(each); + if (container != null) { + specificDayAssignmentsContainers.remove(container); + } + } + } + + @Override + protected void removeContainersFor(Scenario scenario) { + SpecificDayAssignmentsContainer container = containersByScenario().get( + scenario); + if (container != null) { + specificDayAssignmentsContainers.remove(container); + } + } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/TaskElement.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/TaskElement.java index 2e4efa8ec..c6aa87e93 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/TaskElement.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/TaskElement.java @@ -503,4 +503,16 @@ public abstract class TaskElement extends BaseEntity { return getEndDate().getTime() - getStartDate().getTime(); } + public void removePredecessorsDayAssignmentsFor(Scenario scenario) { + for (ResourceAllocation each : getAllResourceAllocations()) { + each.removePredecessorsDayAssignmentsFor(scenario); + } + } + + public void removeDayAssignmentsFor(Scenario scenario) { + for (ResourceAllocation each : getAllResourceAllocations()) { + each.removeDayAssigmentsFor(scenario); + } + } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/scenarios/entities/Scenario.java b/navalplanner-business/src/main/java/org/navalplanner/business/scenarios/entities/Scenario.java index 4dfb9609c..866f9daf4 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/scenarios/entities/Scenario.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/scenarios/entities/Scenario.java @@ -120,6 +120,16 @@ public class Scenario extends BaseEntity { return predecessor; } + public List getPredecessors() { + List result = new ArrayList(); + Scenario current = getPredecessor(); + while (current != null) { + result.add(current); + current = current.getPredecessor(); + } + return result; + } + @AssertTrue(message = "name is already used") public boolean checkConstraintUniqueName() { if (StringUtils.isBlank(name)) { diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java index 5b1d51756..d5483baf2 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java @@ -490,6 +490,7 @@ public class OrderModel implements IOrderModel { if (newOrderVersionNeeded) { OrderVersion newVersion = OrderVersion .createInitialVersion(currentScenario); + reattachAllTaskSources(); order.writeSchedulingDataChangesTo(currentScenario, newVersion); createAndSaveNewOrderVersion(scenarioManager.getCurrent(), newVersion); @@ -556,6 +557,15 @@ public class OrderModel implements IOrderModel { } } + private void reattachAllTaskSources() { + // avoid LazyInitializationException for when doing + // removePredecessorsDayAssignmentsFor + for (TaskSource each : order + .getAllScenariosTaskSourcesFromBottomToTop()) { + taskSourceDAO.reattach(each); + } + } + private void reattachTasksForTasksSources() { for (TaskSource each : order.getTaskSourcesFromBottomToTop()) { each.reloadTask(taskElementDAO);