From f8de3fec73c9b74e4708d0ee7ab73f4e5e4fbac5 Mon Sep 17 00:00:00 2001 From: Manuel Rego Casasnovas Date: Wed, 29 Jul 2009 19:04:15 +0200 Subject: [PATCH] ItEr19S08CUCreacionProxectoPlanificacionItEr18S08: Added new fields to the edit task popup. --- .../business/planner/entities/Task.java | 81 ++++++++++++ .../planner/entities/TaskElement.java | 1 - .../business/planner/entities/Tasks.hbm.xml | 2 + .../AsignedHoursToOrderElementModel.java | 3 +- .../web/planner/EditTaskCommand.java | 32 +++-- .../web/planner/EditTaskController.java | 119 ++++++++++++++++++ .../web/planner/EditTaskModel.java | 31 +++++ .../web/planner/IEditTaskCommand.java | 3 +- .../web/planner/IEditTaskModel.java | 21 ++++ .../web/planner/IOrderPlanningModel.java | 3 +- .../web/planner/OrderPlanningController.java | 10 +- .../web/planner/OrderPlanningModel.java | 5 +- .../src/main/webapp/planner/order.zul | 14 ++- 13 files changed, 302 insertions(+), 23 deletions(-) create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/planner/EditTaskController.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/planner/EditTaskModel.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/planner/IEditTaskModel.java 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 e1984e96f..9cb1d0b6e 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 @@ -1,12 +1,16 @@ package org.navalplanner.business.planner.entities; +import java.math.BigDecimal; import java.util.Collections; +import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.lang.Validate; import org.hibernate.validator.NotNull; +import org.joda.time.DateTime; +import org.joda.time.Days; import org.navalplanner.business.orders.entities.HoursGroup; import org.navalplanner.business.resources.entities.Worker; @@ -22,6 +26,13 @@ public class Task extends TaskElement { @NotNull private HoursGroup hoursGroup; + private Boolean fixedDuration = false; + + /** + * Duration in days of the Task + */ + private Integer duration; + private Set resourceAllocations = new HashSet(); private Integer shareOfHours; @@ -68,6 +79,76 @@ public class Task extends TaskElement { resourceAllocations.remove(resourceAllocation); } + public void setFixedDuration(Boolean fixed_duration) { + this.fixedDuration = fixed_duration; + } + + public Boolean isFixedDuration() { + return fixedDuration; + } + + public void setDuration(Integer duration) { + this.duration = duration; + + DateTime endDate = (new DateTime(getStartDate())).plusDays(duration); + setEndDate(endDate.toDate()); + } + + @Override + public void setEndDate(Date endDate) { + super.setEndDate(endDate); + + DateTime startDateTime = new DateTime(getStartDate()); + DateTime endDateTime = new DateTime(endDate); + Days days = Days.daysBetween(startDateTime, endDateTime); + + this.duration = days.getDays(); + } + + public Integer getDuration() { + if (!isFixedDuration()) { + // If it is not fixed the duration is calculated + Integer duration = calculateDaysDuration(); + setDuration(duration); + return duration; + } + + return duration; + } + + /** + * Calculates the number of days needed to complete the Task taking into + * account the Resources assigned and their dedication. + * + * If the Task has not yet Resources assigned then a typical 8 hours day + * will be considered. + * + * @return The days of duration + */ + private Integer calculateDaysDuration() { + BigDecimal hoursPerDay = new BigDecimal(0).setScale(2); + + for (ResourceAllocation resourceAllocation : resourceAllocations) { + if (resourceAllocation instanceof SpecificResourceAllocation) { + BigDecimal percentage = resourceAllocation.getPercentage(); + Integer hours = ((SpecificResourceAllocation) resourceAllocation) + .getWorker().getDailyCapacity(); + + hoursPerDay = hoursPerDay.add(percentage + .multiply(new BigDecimal(hours).setScale(2))); + } + } + + BigDecimal taskHours = new BigDecimal(getWorkHours()).setScale(2); + + if (hoursPerDay.compareTo(new BigDecimal(0).setScale(2)) == 0) { + // FIXME Review, by default 8 hours per day + hoursPerDay = new BigDecimal(8).setScale(2); + } + + return taskHours.divide(hoursPerDay, BigDecimal.ROUND_DOWN).intValue(); + } + /** * Checks if there isn't any {@link Worker} repeated in the {@link Set} of * {@link ResourceAllocation} of this {@link Task}. 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 1d9b32a62..6d4917b56 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 @@ -148,7 +148,6 @@ public abstract class TaskElement { public abstract List getChildren(); - protected void setParent(TaskGroup taskGroup) { this.parent = taskGroup; } diff --git a/navalplanner-business/src/main/resources/org/navalplanner/business/planner/entities/Tasks.hbm.xml b/navalplanner-business/src/main/resources/org/navalplanner/business/planner/entities/Tasks.hbm.xml index fb069edc9..8d4b829b0 100644 --- a/navalplanner-business/src/main/resources/org/navalplanner/business/planner/entities/Tasks.hbm.xml +++ b/navalplanner-business/src/main/resources/org/navalplanner/business/planner/entities/Tasks.hbm.xml @@ -30,6 +30,8 @@ + + diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/AsignedHoursToOrderElementModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/AsignedHoursToOrderElementModel.java index 8c6b707aa..93822556e 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/AsignedHoursToOrderElementModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/AsignedHoursToOrderElementModel.java @@ -3,15 +3,16 @@ package org.navalplanner.web.orders; import java.util.ArrayList; import java.util.Iterator; import java.util.List; + import org.apache.commons.lang.Validate; import org.navalplanner.business.orders.entities.OrderElement; import org.navalplanner.business.workreports.daos.IWorkReportLineDAO; import org.navalplanner.business.workreports.entities.WorkReportLine; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * Service to show the asigned hours of a selected order element diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/EditTaskCommand.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/EditTaskCommand.java index 782c35bd2..9bd002ac9 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/EditTaskCommand.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/EditTaskCommand.java @@ -1,10 +1,13 @@ package org.navalplanner.web.planner; +import org.navalplanner.business.planner.daos.TaskElementDao; +import org.navalplanner.business.planner.entities.Task; import org.navalplanner.business.planner.entities.TaskElement; +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.TaskEditFormComposer; +import org.springframework.transaction.annotation.Transactional; import org.zkoss.ganttz.extensions.IContextWithPlannerTask; /** @@ -16,13 +19,27 @@ import org.zkoss.ganttz.extensions.IContextWithPlannerTask; @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class EditTaskCommand implements IEditTaskCommand { - private TaskEditFormComposer taskEditFormComposer; + @Autowired + private TaskElementDao taskElementDAO; + + private EditTaskController editTaskController; @Override + @Transactional(readOnly = true) public void doAction(IContextWithPlannerTask context, - TaskElement task) { - taskEditFormComposer.showEditFormFor(context.getRelativeTo(), context - .getTask()); + TaskElement taskElement) { + + taskElementDAO.save(taskElement); + if (taskElement instanceof Task) { + forceLoadHoursGroup((Task) taskElement); + } + + editTaskController.showEditFormFor(context.getRelativeTo(), context + .getTask(), taskElement); + } + + private void forceLoadHoursGroup(Task task) { + task.getHoursGroup(); } @Override @@ -31,9 +48,8 @@ public class EditTaskCommand implements IEditTaskCommand { } @Override - public void setTaskEditFormComposer( - TaskEditFormComposer taskEditFormComposer) { - this.taskEditFormComposer = taskEditFormComposer; + public void setEditTaskController(EditTaskController editTaskController) { + this.editTaskController = editTaskController; } } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/EditTaskController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/EditTaskController.java new file mode 100644 index 000000000..b35a44483 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/EditTaskController.java @@ -0,0 +1,119 @@ +package org.navalplanner.web.planner; + +import org.navalplanner.business.planner.entities.Task; +import org.navalplanner.business.planner.entities.TaskElement; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.zkoss.ganttz.TaskEditFormComposer; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.util.GenericForwardComposer; +import org.zkoss.zul.Checkbox; +import org.zkoss.zul.Datebox; +import org.zkoss.zul.Intbox; + +/** + * Controller for edit {@link Task} popup. + * + * @author Manuel Rego Casasnovas + */ +@org.springframework.stereotype.Component("editTaskController") +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +public class EditTaskController extends GenericForwardComposer { + + private IEditTaskModel editTaskModel; + + private TaskElement currentTaskElement; + + private Intbox hours; + + private Checkbox fixedDuration; + + private Intbox duration; + + private Datebox endDateBox; + + /** + * Controller from the Gantt to manage common fields on edit {@link Task} + * popup. + */ + private TaskEditFormComposer taskEditFormComposer = new TaskEditFormComposer(); + + public void showEditFormFor(Component openRelativeTo, + org.zkoss.ganttz.data.Task task, + TaskElement taskElement) { + this.currentTaskElement = taskElement; + taskEditFormComposer.showEditFormFor(openRelativeTo, task); + updateComponentValuesForTask(); + } + + private void updateComponentValuesForTask() { + if (currentTaskElement instanceof Task) { + // If it's a Task + // Show fields + hours.getFellow("fixedDurationRow").setVisible(true); + hours.getFellow("durationRow").setVisible(true); + + Task task = (Task) currentTaskElement; + + // Sets the value of fields + fixedDuration.setChecked(task.isFixedDuration() == null ? false + : task.isFixedDuration()); + duration.setValue(editTaskModel.getDuration(task)); + + // Disable some fields depending on fixedDuration value + duration.setDisabled(task.isFixedDuration() == null ? true : !task + .isFixedDuration()); + ((Datebox) hours.getFellow("endDateBox")) + .setDisabled(task.isFixedDuration() == null ? true : !task + .isFixedDuration()); + } else { + // If it's a TaskGroup + // Hide fields + hours.getFellow("fixedDurationRow").setVisible(false); + hours.getFellow("durationRow").setVisible(false); + } + + // Sets the values for the common fields + endDateBox.setValue(currentTaskElement.getEndDate()); + hours.setValue(currentTaskElement.getWorkHours()); + + // Update the Task size in the Gantt + taskEditFormComposer.onChange$endDateBox(null); + } + + @Override + public void doAfterCompose(Component comp) throws Exception { + super.doAfterCompose(comp); + taskEditFormComposer.doAfterCompose(comp); + } + + public void onCheck$fixedDuration(Event event) { + if (currentTaskElement instanceof Task) { + Task task = (Task) currentTaskElement; + task.setFixedDuration(fixedDuration.isChecked()); + + // Disable some fields depending on fixedDuration value + duration.setDisabled(!fixedDuration.isChecked()); + ((Datebox) duration.getFellow("endDateBox")) + .setDisabled(!fixedDuration.isChecked()); + } + + updateComponentValuesForTask(); + } + + public void onChange$duration(Event event) { + if (currentTaskElement instanceof Task) { + Task task = (Task) currentTaskElement; + task.setDuration(duration.getValue()); + } + + updateComponentValuesForTask(); + } + + public void onChange$endDateBox(Event event) { + currentTaskElement.setEndDate(endDateBox.getValue()); + updateComponentValuesForTask(); + } + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/EditTaskModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/EditTaskModel.java new file mode 100644 index 000000000..e42b8765c --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/EditTaskModel.java @@ -0,0 +1,31 @@ +package org.navalplanner.web.planner; + +import org.navalplanner.business.planner.daos.ITaskElementDao; +import org.navalplanner.business.planner.entities.Task; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Model for UI operations related to edit {@link Task} popup. + * + * @author Manuel Rego Casasnovas + */ +@Service +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +public class EditTaskModel implements IEditTaskModel { + + @Autowired + private ITaskElementDao taskElementDAO; + + @Override + @Transactional(readOnly = true) + public Integer getDuration(Task task) { + taskElementDAO.save(task); + + return task.getDuration(); + } + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/IEditTaskCommand.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/IEditTaskCommand.java index a10a01b7b..c404843bb 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/IEditTaskCommand.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/IEditTaskCommand.java @@ -1,7 +1,6 @@ package org.navalplanner.web.planner; import org.navalplanner.business.planner.entities.TaskElement; -import org.zkoss.ganttz.TaskEditFormComposer; import org.zkoss.ganttz.extensions.ICommandOnTask; /** @@ -11,6 +10,6 @@ import org.zkoss.ganttz.extensions.ICommandOnTask; */ public interface IEditTaskCommand extends ICommandOnTask { - void setTaskEditFormComposer(TaskEditFormComposer taskEditFormComposer); + void setEditTaskController(EditTaskController editTaskController); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/IEditTaskModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/IEditTaskModel.java new file mode 100644 index 000000000..573ee8e28 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/IEditTaskModel.java @@ -0,0 +1,21 @@ +package org.navalplanner.web.planner; + +import org.navalplanner.business.planner.entities.Task; + +/** + * Contract for edit {@link Task} popup. + * + * @author Manuel Rego Casasnovas + */ +public interface IEditTaskModel { + + /** + * Returns the duration of a {@link Task} in number of days. + * + * @param task + * The {@link Task} to get the duration + * @return The days of the {@link Task} + */ + Integer getDuration(Task task); + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/IOrderPlanningModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/IOrderPlanningModel.java index 128debe84..36e4cd446 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/IOrderPlanningModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/IOrderPlanningModel.java @@ -2,7 +2,6 @@ package org.navalplanner.web.planner; import org.navalplanner.business.orders.entities.Order; import org.navalplanner.business.planner.entities.TaskElement; -import org.zkoss.ganttz.TaskEditFormComposer; import org.zkoss.ganttz.adapters.PlannerConfiguration; /** @@ -16,7 +15,7 @@ public interface IOrderPlanningModel { void createConfiguration(Order order, ResourceAllocationController resourceAllocationController, - TaskEditFormComposer taskEditFormComposer, + EditTaskController editTaskController, ConfigurationOnTransaction onTransaction); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/OrderPlanningController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/OrderPlanningController.java index f7b85fc4f..9eb86eb5c 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/OrderPlanningController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/OrderPlanningController.java @@ -10,7 +10,6 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import org.zkoss.ganttz.Planner; -import org.zkoss.ganttz.TaskEditFormComposer; import org.zkoss.ganttz.adapters.PlannerConfiguration; /** @@ -28,10 +27,11 @@ public class OrderPlanningController implements return resourceAllocationController; } - private TaskEditFormComposer taskEditFormComposer = new TaskEditFormComposer(); + @Autowired + private EditTaskController editTaskController; - public TaskEditFormComposer getTaskEditFormComposer() { - return taskEditFormComposer; + public EditTaskController getEditTaskController() { + return editTaskController; } @Autowired @@ -48,7 +48,7 @@ public class OrderPlanningController implements @Override public void showSchedule(Order order) { model.createConfiguration(order, resourceAllocationController, - taskEditFormComposer, + editTaskController, new ConfigurationOnTransaction() { @Override diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/OrderPlanningModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/OrderPlanningModel.java index 627dce7ea..007386a0f 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/OrderPlanningModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/OrderPlanningModel.java @@ -15,7 +15,6 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; -import org.zkoss.ganttz.TaskEditFormComposer; import org.zkoss.ganttz.adapters.IStructureNavigator; import org.zkoss.ganttz.adapters.PlannerConfiguration; @@ -48,7 +47,7 @@ public abstract class OrderPlanningModel implements IOrderPlanningModel { @Transactional(readOnly = true) public void createConfiguration(Order order, ResourceAllocationController resourceAllocationController, - TaskEditFormComposer taskEditFormComposer, + EditTaskController editTaskController, ConfigurationOnTransaction onTransaction) { Order orderReloaded = reload(order); if (!orderReloaded.isSomeTaskElementScheduled()) @@ -70,7 +69,7 @@ public abstract class OrderPlanningModel implements IOrderPlanningModel { configuration.addCommandOnTask(splitCommand); IEditTaskCommand editTaskCommand = getEditTaskCommand(); - editTaskCommand.setTaskEditFormComposer(taskEditFormComposer); + editTaskCommand.setEditTaskController(editTaskController); configuration.setEditTaskCommand(editTaskCommand); onTransaction.use(configuration); diff --git a/navalplanner-webapp/src/main/webapp/planner/order.zul b/navalplanner-webapp/src/main/webapp/planner/order.zul index 1de5f46c6..8d105bbbb 100644 --- a/navalplanner-webapp/src/main/webapp/planner/order.zul +++ b/navalplanner-webapp/src/main/webapp/planner/order.zul @@ -18,7 +18,7 @@
- + @@ -37,6 +37,18 @@ ${c:l('task.notes')} + + Hours + + + + Fixed duration + + + + Duration (days) + +