From 2a101847d4d701afdc80779c02f811a015c439d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Wed, 11 May 2011 18:28:49 +0200 Subject: [PATCH] [Bug #1054] Consider task constraints FEA: ItEr74S04BugFixing --- .../LimitingResourceQueueElement.java | 46 ++------- .../web/planner/order/ISaveCommand.java | 4 + .../web/planner/order/OrderPlanningModel.java | 6 +- .../web/planner/order/SaveCommand.java | 99 ++++++++++++++++++- 4 files changed, 108 insertions(+), 47 deletions(-) diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/limiting/entities/LimitingResourceQueueElement.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/limiting/entities/LimitingResourceQueueElement.java index c2b1dd1ca..78c885154 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/limiting/entities/LimitingResourceQueueElement.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/limiting/entities/LimitingResourceQueueElement.java @@ -22,7 +22,6 @@ package org.navalplanner.business.planner.limiting.entities; import java.math.BigDecimal; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; @@ -37,7 +36,6 @@ import org.joda.time.Duration; import org.joda.time.LocalDate; import org.navalplanner.business.common.BaseEntity; import org.navalplanner.business.planner.entities.DayAssignment; -import org.navalplanner.business.planner.entities.Dependency; import org.navalplanner.business.planner.entities.GenericResourceAllocation; import org.navalplanner.business.planner.entities.ResourceAllocation; import org.navalplanner.business.planner.entities.SpecificResourceAllocation; @@ -46,6 +44,7 @@ import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.LimitingResourceQueue; import org.navalplanner.business.resources.entities.LimitingResourceQueueElementComparator; import org.navalplanner.business.resources.entities.Resource; +import org.navalplanner.business.workingday.IntraDayDate; /** * Entity which represents an element in the queue which represents the limiting @@ -247,46 +246,13 @@ public class LimitingResourceQueueElement extends BaseEntity { return Collections.unmodifiableSet(dependenciesAsDestiny); } - public void updateDates(Date orderInitDate, - Collection incomingDependencies) { - this.earlierStartDateBecauseOfGantt = calculateStartDate(orderInitDate, - incomingDependencies); - this.earliestEndDateBecauseOfGantt = calculateEndDate(orderInitDate, - incomingDependencies); + public void updateDates(IntraDayDate earliestStart, IntraDayDate earliestEnd) { + this.earlierStartDateBecauseOfGantt = toDate(earliestStart); + this.earliestEndDateBecauseOfGantt = toDate(earliestEnd); } - private Date calculateStartDate(Date orderInitDate, - Collection dependenciesWithThisDestination) { - Date result = orderInitDate; - for (Dependency each : dependenciesWithThisDestination) { - if (!each.isDependencyBetweenLimitedAllocatedTasks() - && each.getType().modifiesDestinationStart()) { - result = bigger(result, each.getDateFromOrigin()); - } - } - return result; - } - - private Date calculateEndDate(Date orderInitDate, - Collection incomingDependencies) { - Date result = orderInitDate; - for (Dependency each : incomingDependencies) { - if (!each.isDependencyBetweenLimitedAllocatedTasks() - && each.getType().modifiesDestinationEnd()) { - result = bigger(result, each.getDateFromOrigin()); - } - } - return result; - } - - private Date bigger(Date one, Date another) { - if (one == null) { - return another; - } - if (another == null) { - return one; - } - return one.compareTo(another) >= 0 ? one : another; + private Date toDate(IntraDayDate intraDayDate) { + return intraDayDate.toDateTimeAtStartOfDay().toDate(); } public void detach() { diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/ISaveCommand.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/ISaveCommand.java index 029dfffd2..a9677211d 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/ISaveCommand.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/ISaveCommand.java @@ -22,6 +22,7 @@ package org.navalplanner.web.planner.order; import org.navalplanner.business.planner.entities.TaskElement; +import org.zkoss.ganttz.adapters.PlannerConfiguration; import org.zkoss.ganttz.extensions.ICommand; /** @@ -36,10 +37,13 @@ public interface ISaveCommand extends ICommand { public void setState(PlanningState planningState); + public void setConfiguration(PlannerConfiguration configuration); + public void addListener(IAfterSaveListener listener); public void removeListener(IAfterSaveListener listener); public String getImage(); + } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/OrderPlanningModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/OrderPlanningModel.java index 8c75af9e8..a1e209249 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/OrderPlanningModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/OrderPlanningModel.java @@ -967,7 +967,7 @@ public abstract class OrderPlanningModel implements IOrderPlanningModel { PlannerConfiguration configuration, boolean writingAllowed) { if (writingAllowed) { - ISaveCommand result = buildSaveCommand(); + ISaveCommand result = buildSaveCommand(configuration); configuration.addGlobalCommand(result); return result; } @@ -1029,8 +1029,10 @@ public abstract class OrderPlanningModel implements IOrderPlanningModel { return resourceAllocationCommand; } - private ISaveCommand buildSaveCommand() { + private ISaveCommand buildSaveCommand( + PlannerConfiguration configuration) { ISaveCommand saveCommand = getSaveCommand(); + saveCommand.setConfiguration(configuration); saveCommand.setState(planningState); return saveCommand; } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/SaveCommand.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/SaveCommand.java index 5360d7ea5..8dfab0654 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/SaveCommand.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/SaveCommand.java @@ -34,6 +34,7 @@ import java.util.SortedSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.joda.time.LocalDate; import org.navalplanner.business.advance.entities.AdvanceAssignment; import org.navalplanner.business.advance.entities.AdvanceMeasurement; import org.navalplanner.business.advance.entities.DirectAdvanceAssignment; @@ -67,10 +68,18 @@ import org.navalplanner.business.planner.limiting.daos.ILimitingResourceQueueDep import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueDependency; import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement; import org.navalplanner.web.common.concurrentdetection.OnConcurrentModification; +import org.navalplanner.web.planner.TaskElementAdapter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import org.zkoss.ganttz.adapters.DomainDependency; +import org.zkoss.ganttz.adapters.IAdapterToTaskFundamentalProperties; +import org.zkoss.ganttz.adapters.PlannerConfiguration; +import org.zkoss.ganttz.data.ConstraintCalculator; +import org.zkoss.ganttz.data.DependencyType.Point; +import org.zkoss.ganttz.data.GanttDate; +import org.zkoss.ganttz.data.constraint.Constraint; import org.zkoss.ganttz.extensions.IContext; import org.zkoss.zul.Messagebox; @@ -115,16 +124,43 @@ public class SaveCommand implements ISaveCommand { private PlanningState state; + private PlannerConfiguration configuration; + + private ConstraintCalculator constraintCalculator; + @Autowired private IAdHocTransactionService transactionService; private List listeners = new ArrayList(); + private IAdapterToTaskFundamentalProperties adapter; + + @Override public void setState(PlanningState state) { this.state = state; } + @Override + public void setConfiguration(PlannerConfiguration configuration) { + this.configuration = configuration; + this.adapter = configuration.getAdapter(); + this.constraintCalculator = new ConstraintCalculator( + configuration.isScheduleBackwards()) { + + @Override + protected GanttDate getStartDate(TaskElement vertex) { + return TaskElementAdapter + .toGantt(vertex.getIntraDayStartDate()); + } + + @Override + protected GanttDate getEndDate(TaskElement vertex) { + return TaskElementAdapter.toGantt(vertex.getIntraDayEndDate()); + } + }; + } + @Override public void doAction(IContext context) { if (state.getScenarioInfo().isUsingTheOwnerScenario() @@ -237,11 +273,64 @@ public class SaveCommand implements ISaveCommand { } private void updateLimitingResourceQueueElementDates(Task task) { - LimitingResourceQueueElement limiting = task - .getAssociatedLimitingResourceQueueElementIfAny(); - Date initDate = state.getRootTask().getOrderElement().getInitDate(); - limiting.updateDates(initDate, - task.getDependenciesWithThisDestination()); + try { + LimitingResourceQueueElement limiting = task + .getAssociatedLimitingResourceQueueElementIfAny(); + + GanttDate earliestStart = resolveConstraints(task, Point.START); + GanttDate earliestEnd = resolveConstraints(task, Point.END); + + limiting.updateDates(TaskElementAdapter.toIntraDay(earliestStart), + TaskElementAdapter.toIntraDay(earliestEnd)); + } catch (Exception e) { + // if this fails all the saving shouldn't fail + LOG.error( + "error updating associated LimitingResourceQueueElement for task: " + + task, e); + } + } + + private GanttDate resolveConstraints(Task task, Point point) { + List> dependencyConstraints = toConstraints( + adapter.getIncomingDependencies(task), point); + List> taskConstraints = getTaskConstraints(task); + + boolean dependenciesHavePriority = configuration + .isDependenciesConstraintsHavePriority(); + if (dependenciesHavePriority) { + return Constraint + . initialValue( + TaskElementAdapter.toGantt(getOrderInitDate())) + .withConstraints(taskConstraints) + .withConstraints(dependencyConstraints) + .applyWithoutFinalCheck(); + } else { + return Constraint + . initialValue( + TaskElementAdapter.toGantt(getOrderInitDate())) + .withConstraints(dependencyConstraints) + .withConstraints(taskConstraints) + .applyWithoutFinalCheck(); + } + } + + private List> getTaskConstraints(Task task) { + return TaskElementAdapter.getStartConstraintsFor(task, getOrderInitDate()); + } + + private LocalDate getOrderInitDate() { + return LocalDate.fromDateFields(state.getRootTask().getOrderElement() + .getInitDate()); + } + + private List> toConstraints( + List> incomingDependencies, + Point point) { + List> result = new ArrayList>(); + for (DomainDependency each : incomingDependencies) { + result.addAll(constraintCalculator.getConstraints(each, point)); + } + return result; } private void removeEmptyConsolidation(TaskElement taskElement) {