From 9f10cfc47f35efb81355fa5d4754b29709c5cf1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Mon, 15 Mar 2010 13:28:24 +0100 Subject: [PATCH] ItEr50S04ValidacionEProbasFuncionaisItEr49S04: [Bug #386] Fixing bug. For the task group not constraint is generated. When calculating the start of a task container the children must be taken into account so it doesn't start at the start of the order. Also fixes bug #384. --- .../zkoss/ganttz/data/GanttDiagramGraph.java | 104 ++++++++++++++---- .../web/planner/TaskElementAdapter.java | 4 +- 2 files changed, 86 insertions(+), 22 deletions(-) diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/GanttDiagramGraph.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/GanttDiagramGraph.java index 9aa66c325..6aae85a39 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/GanttDiagramGraph.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/GanttDiagramGraph.java @@ -234,29 +234,85 @@ public class GanttDiagramGraph implements ICriticalPathCalculable { } private void enforceStartDate(Set incoming) { - List> dependencyConstraints = Dependency - .getStartConstraints(incoming); - Date newStart; - if (dependenciesConstraintsHavePriority) { - newStart = Constraint. initialValue(null) - .withConstraints(task - .getStartConstraints()) - .withConstraints(dependencyConstraints) - .withConstraints(globalStartConstraints) - .apply(); - - } else { - newStart = Constraint. initialValue(null) - .withConstraints(dependencyConstraints) - .withConstraints(task - .getStartConstraints()) - .withConstraints(globalStartConstraints) - .apply(); - } + Date newStart = calculateStartDateFor(task, incoming); + Date childrenEarliest = getEarliestStartDateOfChildren(task); + newStart = maxNotNull(newStart, childrenEarliest); if (!task.getBeginDate().equals(newStart)) { task.setBeginDate(newStart); } } + + private Date getEarliestStartDateOfChildren(Task task) { + if (!task.isContainer()) { + return null; + } + List startDates = getChildrenStartDates((TaskContainer) task); + if (!startDates.isEmpty()) { + return Collections.min(startDates); + } + return null; + } + + private List getChildrenStartDates(TaskContainer container) { + List children = container.getTasks(); + List startDates = new ArrayList(); + for (Task each : children) { + Set incomingDependencies = withoutDependencyFrom( + container, graph.incomingEdgesOf(each)); + Date dateWithoutContainerInfluence = calculateStartDateFor( + each, incomingDependencies); + if (dateWithoutContainerInfluence != null) { + startDates.add(dateWithoutContainerInfluence); + } + } + return startDates; + } + + private Set withoutDependencyFrom(TaskContainer container, + Set incoming) { + Set result = new HashSet(); + for (Dependency each : incoming) { + if (!each.getSource().equals(container)) { + result.add(each); + } + } + return result; + } + + private Date maxNotNull(Date... dates) { + List list = new ArrayList(); + for (Date each : dates) { + if (each != null) { + list.add(each); + } + } + if (list.isEmpty()) { + return null; + } + return Collections.max(list); + } + } + + private Date calculateStartDateFor(Task task, + Set withDependencies) { + List> dependencyConstraints = Dependency + .getStartConstraints(withDependencies); + Date newStart; + if (dependenciesConstraintsHavePriority) { + newStart = Constraint. initialValue(null) + .withConstraints(task.getStartConstraints()) + .withConstraints(dependencyConstraints) + .withConstraints(globalStartConstraints) + .apply(); + + } else { + newStart = Constraint. initialValue(null) + .withConstraints(dependencyConstraints) + .withConstraints(task.getStartConstraints()) + .withConstraints(globalStartConstraints) + .apply(); + } + return newStart; } public void enforceAllRestrictions() { @@ -300,12 +356,18 @@ public class GanttDiagramGraph implements ICriticalPathCalculable { ParentShrinkingEnforcer parentShrinkingEnforcer = new ParentShrinkingEnforcer( (TaskContainer) task); parentShrinkingEnforcerByTask.put(task, parentShrinkingEnforcer); + List dependenciesToAdd = new ArrayList(); for (Task child : task.getTasks()) { addTask(child); - add(new Dependency(child, task, DependencyType.END_END, false)); - add(new Dependency(task, child, DependencyType.START_START, + dependenciesToAdd.add(new Dependency(child, task, + DependencyType.END_END, false)); + dependenciesToAdd.add(new Dependency(task, child, + DependencyType.START_START, false)); } + for (Dependency each : dependenciesToAdd) { + add(each); + } } } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/TaskElementAdapter.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/TaskElementAdapter.java index 55f2c4935..0fed78ece 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/TaskElementAdapter.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/TaskElementAdapter.java @@ -504,9 +504,11 @@ public class TaskElementAdapter implements ITaskElementAdapter { default: throw new RuntimeException("can't handle " + constraintType); } - } else { + } else if (taskElement.isMilestone()) { return Collections.singletonList(DateConstraint .biggerOrEqualThan(taskElement.getStartDate())); + } else { + return Collections.emptyList(); } }