diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/Task.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/Task.java index e7bca4584..2f947cd2a 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/Task.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/Task.java @@ -87,6 +87,25 @@ public class Task extends TaskElement implements ITaskPositionConstrained { } } + /** + * Calculates end date for a task, starting from start until fulfilling + * number of hours. + * + * For tasks with limiting resources it's needed to resize a task if the + * number of hours allocated to a resource changes. In non limiting + * resources, the task is resized because when the number of hours changes, + * new days assignments are generated, and then the task is resized + * accordingly. + * + * @param hours + */ + public void resizeToHours(int hours) { + Validate.isTrue(isLimiting()); + EffortDuration workHours = EffortDuration.hours(hours); + DurationBetweenDates duration = new DurationBetweenDates(0, workHours); + setIntraDayEndDate(duration.fromStartToEnd(getIntraDayStartDate())); + } + private CalculatedValue calculatedValue = CalculatedValue.END_DATE; private Set> resourceAllocations = new HashSet>(); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/limiting/allocation/ILimitingResourceAllocationModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/limiting/allocation/ILimitingResourceAllocationModel.java index db1044ecc..97e7040f8 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/limiting/allocation/ILimitingResourceAllocationModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/limiting/allocation/ILimitingResourceAllocationModel.java @@ -25,8 +25,10 @@ import java.util.List; import org.navalplanner.business.orders.entities.AggregatedHoursGroup; import org.navalplanner.business.planner.entities.Task; +import org.navalplanner.business.planner.entities.TaskElement; import org.navalplanner.web.planner.allocation.INewAllocationsAdder; import org.navalplanner.web.planner.order.PlanningState; +import org.zkoss.ganttz.extensions.IContextWithPlannerTask; /** * Contract for {@link Task}. @@ -43,7 +45,7 @@ public interface ILimitingResourceAllocationModel extends INewAllocationsAdder { List getResourceAllocationRows(); - void init(Task task, PlanningState planningState); + void init(IContextWithPlannerTask context, Task task, PlanningState planningState); void setLimitingResourceAllocationController( LimitingResourceAllocationController limitingResourceAllocationController); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/limiting/allocation/LimitingResourceAllocationController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/limiting/allocation/LimitingResourceAllocationController.java index 88119e821..ffa19393e 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/limiting/allocation/LimitingResourceAllocationController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/limiting/allocation/LimitingResourceAllocationController.java @@ -26,6 +26,7 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.navalplanner.business.planner.entities.ResourceAllocation; +import org.navalplanner.business.planner.entities.TaskElement; import org.navalplanner.web.common.IMessagesForUser; import org.navalplanner.web.common.Util; import org.navalplanner.web.common.components.AllocationSelector; @@ -40,6 +41,9 @@ import org.navalplanner.web.planner.taskedition.TaskPropertiesController.Resourc import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; +import org.zkoss.ganttz.extensions.IContextWithPlannerTask; +import org.zkoss.ganttz.timetracker.ICellForDetailItemRenderer; +import org.zkoss.ganttz.timetracker.OnColumnsRowRenderer; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; @@ -100,15 +104,16 @@ public class LimitingResourceAllocationController extends GenericForwardComposer /** * Shows Resource Allocation window + * @param context * @param task * @param ganttTask * @param planningState */ - public void init(org.navalplanner.business.planner.entities.Task task, + public void init(IContextWithPlannerTask context, org.navalplanner.business.planner.entities.Task task, PlanningState planningState, IMessagesForUser messagesForUser) { try { - resourceAllocationModel.init(task, planningState); + resourceAllocationModel.init(context, task, planningState); resourceAllocationModel.setLimitingResourceAllocationController(this); // if exist resource allocation with day assignments, it can not diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/limiting/allocation/LimitingResourceAllocationModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/limiting/allocation/LimitingResourceAllocationModel.java index 10c64e375..e36349599 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/limiting/allocation/LimitingResourceAllocationModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/limiting/allocation/LimitingResourceAllocationModel.java @@ -29,6 +29,8 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import org.navalplanner.business.common.IAdHocTransactionService; +import org.navalplanner.business.common.IOnTransaction; import org.navalplanner.business.orders.daos.IHoursGroupDAO; import org.navalplanner.business.orders.entities.AggregatedHoursGroup; import org.navalplanner.business.orders.entities.HoursGroup; @@ -37,6 +39,7 @@ import org.navalplanner.business.planner.daos.ITaskElementDAO; import org.navalplanner.business.planner.daos.ITaskSourceDAO; import org.navalplanner.business.planner.entities.ResourceAllocation; import org.navalplanner.business.planner.entities.Task; +import org.navalplanner.business.planner.entities.TaskElement; import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement; import org.navalplanner.business.resources.daos.ICriterionDAO; import org.navalplanner.business.resources.daos.IResourceDAO; @@ -52,6 +55,8 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.zkoss.ganttz.data.GanttDate; +import org.zkoss.ganttz.extensions.IContextWithPlannerTask; /** * Provides logical operations for limiting resource assignations in @{Task} @@ -77,16 +82,23 @@ public class LimitingResourceAllocationModel implements ILimitingResourceAllocat @Autowired private IResourceDAO resourceDAO; + @Autowired + private IAdHocTransactionService transactionService; + + private IContextWithPlannerTask context; + private Task task; - private List limitingAllocationRows = new ArrayList(); - private PlanningState planningState; + private List limitingAllocationRows = new ArrayList(); + private LimitingResourceAllocationController limitingResourceAllocationController; @Override - public void init(Task task, PlanningState planningState) { + public void init(IContextWithPlannerTask context, Task task, + PlanningState planningState) { + this.context = context; this.task = task; this.planningState = planningState; limitingAllocationRows = LimitingAllocationRow.toRows(task); @@ -315,12 +327,41 @@ public class LimitingResourceAllocationModel implements ILimitingResourceAllocat @Override @Transactional(readOnly=true) public void confirmSave() { - taskDAO.reattach(task); - ResourceAllocation resourceAllocation = getAssociatedResourceAllocation(); - if (resourceAllocation != null && resourceAllocation.isNewObject()) { - addAssociatedLimitingResourceQueueElement(task, resourceAllocation); + applyAllocationWithDateChangesNotification(new IOnTransaction() { + @Override + public Void execute() { + taskDAO.reattach(task); + + ResourceAllocation resourceAllocation = getAssociatedResourceAllocation(); + if (resourceAllocation != null) { + if (!resourceAllocation.hasAssignments()) { + task.resizeToHours(resourceAllocation + .getIntendedTotalHours()); + } + if (resourceAllocation.isNewObject()) { + addAssociatedLimitingResourceQueueElement(task, + resourceAllocation); + } + } + taskDAO.save(task); + return null; + } + }); + } + + private void applyAllocationWithDateChangesNotification( + IOnTransaction allocationDoer) { + if (context != null) { + org.zkoss.ganttz.data.Task ganttTask = context.getTask(); + GanttDate previousStartDate = ganttTask.getBeginDate(); + GanttDate previousEnd = ganttTask.getEndDate(); + transactionService.runOnReadOnlyTransaction(allocationDoer); + ganttTask.fireChangesForPreviousValues(previousStartDate, + previousEnd); + } else { + // Update hours of a Task from Limiting Resource view + transactionService.runOnReadOnlyTransaction(allocationDoer); } - taskDAO.save(task); } private void addAssociatedLimitingResourceQueueElement(Task task, ResourceAllocation resourceAllocation) { diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/taskedition/EditTaskController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/taskedition/EditTaskController.java index 7d49a28f9..73c7b62c5 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/taskedition/EditTaskController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/taskedition/EditTaskController.java @@ -194,7 +194,7 @@ public class EditTaskController extends GenericForwardComposer { showNonLimitingResourcesTab(); } else if (ResourceAllocationTypeEnum.LIMITING_RESOURCES .equals(resourceAllocationType)) { - limitingResourceAllocationController.init(asTask(taskElement), + limitingResourceAllocationController.init(context, asTask(taskElement), planningState, messagesForUser); showLimitingResourcesTab(); }