From 6e3dbd2886479b52725ad9bfa66ac0932376c5e2 Mon Sep 17 00:00:00 2001 From: Manuel Rego Casasnovas Date: Tue, 30 Jun 2009 18:42:01 +0200 Subject: [PATCH] ItEr15S11CUConfiguracionDeOrganizacionsDeTraballoConUnidadesTraballoItEr14S11: Added relation between HoursGroup and Criterion. --- .../orders/daos/IOrderElementDao.java | 13 + .../business/orders/daos/OrderElementDao.java | 19 ++ .../business/orders/entities/HoursGroup.java | 78 ++++++ .../orders/entities/OrderElement.java | 21 +- .../business/orders/entities/OrderLine.java | 36 ++- .../orders/entities/OrderLineGroup.java | 21 +- .../services/impl/CriterionServiceImpl.java | 1 - .../business/orders/entities/Orders.hbm.xml | 9 + .../resources/entities/Resources.hbm.xml | 1 + .../orders/services/OrderServiceTest.java | 76 +++++- .../web/orders/IOrderElementModel.java | 21 ++ .../navalplanner/web/orders/IOrderModel.java | 5 +- .../web/orders/OrderElementController.java | 224 +++++++++++++++- .../web/orders/OrderElementModel.java | 246 +++++------------- .../orders/OrderElementTreeController.java | 28 +- .../web/orders/OrderElementTreeModel.java | 201 ++++++++++++++ .../navalplanner/web/orders/OrderModel.java | 18 +- .../main/webapp/orders/_editOrderElement.zul | 42 ++- .../src/main/webapp/orders/orders.zul | 2 +- 19 files changed, 837 insertions(+), 225 deletions(-) create mode 100644 navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/IOrderElementDao.java create mode 100644 navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/OrderElementDao.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderElementModel.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/IOrderElementDao.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/IOrderElementDao.java new file mode 100644 index 000000000..de92ec9c0 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/IOrderElementDao.java @@ -0,0 +1,13 @@ +package org.navalplanner.business.orders.daos; + +import org.navalplanner.business.common.daos.IGenericDao; +import org.navalplanner.business.orders.entities.OrderElement; + +/** + * Contract for {@link OrderElementDao} + * + * @author Manuel Rego Casasnovas + */ +public interface IOrderElementDao extends IGenericDao { + +} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/OrderElementDao.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/OrderElementDao.java new file mode 100644 index 000000000..2c4b996d8 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/daos/OrderElementDao.java @@ -0,0 +1,19 @@ +package org.navalplanner.business.orders.daos; + +import org.navalplanner.business.common.daos.impl.GenericDaoHibernate; +import org.navalplanner.business.orders.entities.OrderElement; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Repository; + +/** + * Dao for {@link OrderElement} + * + * @author Manuel Rego Casasnovas + */ +@Repository +@Scope(BeanDefinition.SCOPE_SINGLETON) +public class OrderElementDao extends GenericDaoHibernate + implements + IOrderElementDao { +} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/HoursGroup.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/HoursGroup.java index d4fe2b073..8fd418fa5 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/HoursGroup.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/HoursGroup.java @@ -1,13 +1,20 @@ package org.navalplanner.business.orders.entities; import java.math.BigDecimal; +import java.util.HashSet; +import java.util.Set; +import org.apache.commons.lang.builder.ToStringBuilder; import org.hibernate.validator.NotNull; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.ICriterionType; public class HoursGroup implements Cloneable { private Long id; + private Long version; + public Long getId() { return id; } @@ -23,6 +30,8 @@ public class HoursGroup implements Cloneable { private HoursPolicies hoursPolicy = HoursPolicies.NO_FIXED; + private Set criterions = new HashSet(); + public void setWorkingHours(Integer workingHours) { this.workingHours = workingHours; } @@ -47,4 +56,73 @@ public class HoursGroup implements Cloneable { return hoursPolicy; } + public void setCriterions(Set criterions) { + this.criterions = criterions; + } + + public Set getCriterions() { + return criterions; + } + + public void addCriterion(Criterion criterion) { + Criterion oldCriterion = getCriterionByType(criterion.getType()); + if (oldCriterion != null) { + removeCriterion(oldCriterion); + } + + criterions.add(criterion); + } + + public void removeCriterion(Criterion criterion) { + criterions.remove(criterion); + } + + public Criterion getCriterionByType(ICriterionType type) { + for (Criterion criterion : criterions) { + if (criterion.getType().equals(type.getName())) { + return criterion; + } + } + + return null; + } + + public Criterion getCriterionByType(String type) { + for (Criterion criterion : criterions) { + if (criterion.getType().equals(type)) { + return criterion; + } + } + + return null; + } + + public void removeCriterionByType(ICriterionType type) { + Criterion criterion = getCriterionByType(type); + if (criterion != null) { + removeCriterion(criterion); + } + } + + public void removeCriterionByType(String type) { + Criterion criterion = getCriterionByType(type); + if (criterion != null) { + removeCriterion(criterion); + } + } + + public void forceLoadCriterions() { + criterions.size(); + } + + public void makeTransientAgain() { + // FIXME Review reattachment + id = null; + version = null; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } } 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 c66c5ed03..015f667c7 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 @@ -6,7 +6,10 @@ import java.util.List; import org.hibernate.validator.NotNull; public abstract class OrderElement { - private long id; + + private Long id; + + private Long version; @NotNull private String name; @@ -92,4 +95,20 @@ public abstract class OrderElement { public abstract void forceLoadHourGroups(); + public abstract void forceLoadHourGroupsCriterions(); + + public void makeTransientAgain() { + // FIXME Review reattachment + id = null; + version = null; + for (HoursGroup hoursGroup : getHoursGroups()) { + hoursGroup.makeTransientAgain(); + } + } + + public boolean isTransient() { + // FIXME Review reattachment + return id == null; + } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderLine.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderLine.java index 4d4973e70..11bf3a068 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderLine.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderLine.java @@ -19,7 +19,6 @@ public class OrderLine extends OrderElement { @Override public List getChildren() { - // FIXME Shouldn't return null? return new ArrayList(); } @@ -44,14 +43,6 @@ public class OrderLine extends OrderElement { return new ArrayList(hoursGroups); } - @Override - public void forceLoadHourGroups() { - for (HoursGroup hoursGroup : hoursGroups) { - hoursGroup.getWorkingHours(); - } - } - - public void addHoursGroup(HoursGroup hoursGroup) { hoursGroups.add(hoursGroup); recalculatePercentages(hoursGroups); @@ -88,7 +79,6 @@ public class OrderLine extends OrderElement { } else { if (!isTotalHoursValid(workHours)) { - // FIXME change exception type throw new IllegalArgumentException( "\"workHours\" value is not valid, taking into " + "account the current list of HoursGroup"); @@ -203,7 +193,7 @@ public class OrderLine extends OrderElement { * The desired value * @return true if the value is valid */ - private boolean isTotalHoursValid(Integer total) { + public boolean isTotalHoursValid(Integer total) { Integer newTotal = 0; @@ -291,4 +281,28 @@ public class OrderLine extends OrderElement { } } + /** + * Re-calculates the percentages in the {@link HoursGroup} set of the + * current {@link OrderLine}, without modify the {@link HoursGroup} with + * policy FIXED_PERCENTAGE. + * + */ + public void recalculatePercentages() { + recalculatePercentages(hoursGroups); + } + + @Override + public void forceLoadHourGroups() { + for (HoursGroup hoursGroup : hoursGroups) { + hoursGroup.getWorkingHours(); + } + } + + @Override + public void forceLoadHourGroupsCriterions() { + for (HoursGroup hoursGroup : hoursGroups) { + hoursGroup.forceLoadCriterions(); + } + } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderLineGroup.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderLineGroup.java index 4ac0bb0bf..34adaa2d2 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderLineGroup.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/OrderLineGroup.java @@ -66,13 +66,6 @@ public class OrderLineGroup extends OrderElement implements IOrderLineGroup { return result; } - @Override - public void forceLoadHourGroups() { - for (OrderElement orderElement : children) { - orderElement.forceLoadHourGroups(); - } - } - @Override public List getHoursGroups() { List hoursGroups = new ArrayList(); @@ -82,4 +75,18 @@ public class OrderLineGroup extends OrderElement implements IOrderLineGroup { return hoursGroups; } + @Override + public void forceLoadHourGroups() { + for (OrderElement orderElement : children) { + orderElement.forceLoadHourGroups(); + } + } + + @Override + public void forceLoadHourGroupsCriterions() { + for (OrderElement orderElement : children) { + orderElement.forceLoadHourGroupsCriterions(); + } + } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/CriterionServiceImpl.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/CriterionServiceImpl.java index 3d272cca1..8dda4f8aa 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/CriterionServiceImpl.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/CriterionServiceImpl.java @@ -5,7 +5,6 @@ import java.util.Collection; import java.util.Date; import java.util.List; -import javax.transaction.RollbackException; import org.apache.commons.lang.Validate; import org.hibernate.validator.InvalidValue; import org.navalplanner.business.common.OnTransaction; diff --git a/navalplanner-business/src/main/resources/org/navalplanner/business/orders/entities/Orders.hbm.xml b/navalplanner-business/src/main/resources/org/navalplanner/business/orders/entities/Orders.hbm.xml index 4787ad4a0..22d327d99 100644 --- a/navalplanner-business/src/main/resources/org/navalplanner/business/orders/entities/Orders.hbm.xml +++ b/navalplanner-business/src/main/resources/org/navalplanner/business/orders/entities/Orders.hbm.xml @@ -23,6 +23,7 @@ + @@ -54,10 +55,18 @@ + + + + + + \ No newline at end of file diff --git a/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml b/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml index d726134c1..cf1db0824 100644 --- a/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml +++ b/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml @@ -31,6 +31,7 @@ + diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/orders/services/OrderServiceTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/orders/services/OrderServiceTest.java index 250d89bd7..7ad25d4d4 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/orders/services/OrderServiceTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/orders/services/OrderServiceTest.java @@ -9,7 +9,11 @@ import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONF import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE; import java.util.List; +import java.util.Set; +import java.util.UUID; +import org.hibernate.Session; +import org.hibernate.SessionFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.navalplanner.business.common.OnTransaction; @@ -18,9 +22,11 @@ import org.navalplanner.business.common.exceptions.ValidationException; import org.navalplanner.business.orders.entities.HoursGroup; import org.navalplanner.business.orders.entities.Order; import org.navalplanner.business.orders.entities.OrderElement; -import org.navalplanner.business.orders.entities.OrderLineGroup; import org.navalplanner.business.orders.entities.OrderLine; +import org.navalplanner.business.orders.entities.OrderLineGroup; import org.navalplanner.business.orders.services.IOrderService; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.services.CriterionService; import org.navalplanner.business.test.resources.daos.CriterionSatisfactionDAOTest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.NotTransactional; @@ -51,6 +57,16 @@ public class OrderServiceTest { @Autowired private IOrderService orderService; + @Autowired + private CriterionService criterionService; + + @Autowired + private SessionFactory sessionFactory; + + private Session getSession() { + return sessionFactory.getCurrentSession(); + } + @Test public void testCreation() throws ValidationException { Order order = createValidOrder(); @@ -184,4 +200,62 @@ public class OrderServiceTest { } }); } + + @Test + @NotTransactional + public void testManyToManyHoursGroupCriterionMapping() throws Exception { + final Order order = createValidOrder(); + + OrderElement orderElement = new OrderLine(); + orderElement.setName("Order element"); + order.add(orderElement); + + HoursGroup hoursGroup = new HoursGroup(); + hoursGroup.setWorkingHours(10); + HoursGroup hoursGroup2 = new HoursGroup(); + hoursGroup2.setWorkingHours(5); + + ((OrderLine) orderElement).addHoursGroup(hoursGroup); + ((OrderLine) orderElement).addHoursGroup(hoursGroup2); + + Criterion criterion = Criterion.withNameAndType("Test" + + UUID.randomUUID().toString(), "test"); + criterionService.save(criterion); + + hoursGroup.addCriterion(criterion); + hoursGroup2.addCriterion(criterion); + + orderService.save(order); + + orderService.onTransaction(new OnTransaction() { + + @Override + public Void execute() { + try { + Order reloaded = orderService.find(order.getId()); + + List orderElements = reloaded + .getOrderElements(); + assertThat(orderElements.size(), equalTo(1)); + + List hoursGroups = orderElements.get(0) + .getHoursGroups(); + assertThat(hoursGroups.size(), equalTo(2)); + + Set criterions = hoursGroups.get(0) + .getCriterions(); + assertThat(criterions.size(), equalTo(1)); + + Criterion criterion = criterions.iterator().next(); + + assertThat(criterion.getType(), equalTo("test")); + } catch (InstanceNotFoundException e) { + throw new RuntimeException(e); + } + return null; + } + }); + + } + } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderElementModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderElementModel.java new file mode 100644 index 000000000..ecabc6805 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderElementModel.java @@ -0,0 +1,21 @@ +package org.navalplanner.web.orders; + +import java.util.List; + +import org.navalplanner.business.orders.entities.OrderElement; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.ICriterionType; + +public interface IOrderElementModel { + + public OrderElement getOrderElement(); + + public void setCurrent(OrderElement orderElement); + + public List> getCriterionTypes(); + + public ICriterionType getCriterionTypeByName(String name); + + public List getCriterionsFor(ICriterionType type); + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderModel.java index 85ac102bc..9c2331236 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderModel.java @@ -5,6 +5,7 @@ import java.util.List; import org.navalplanner.business.common.exceptions.ValidationException; import org.navalplanner.business.orders.entities.IOrderLineGroup; import org.navalplanner.business.orders.entities.Order; +import org.navalplanner.business.orders.entities.OrderElement; /** * Contract for {@link OrderModel}
@@ -26,6 +27,8 @@ public interface IOrderModel { void prepareForRemove(Order order); - OrderElementModel getOrderElementTreeModel(); + OrderElementTreeModel getOrderElementTreeModel(); + + IOrderElementModel getOrderElementModel(OrderElement orderElement); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementController.java index a56990b0c..9b99cb821 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementController.java @@ -1,6 +1,8 @@ package org.navalplanner.web.orders; import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -10,20 +12,25 @@ import org.navalplanner.business.orders.entities.OrderElement; import org.navalplanner.business.orders.entities.OrderLine; import org.navalplanner.business.orders.entities.OrderLineGroup; import org.navalplanner.business.orders.entities.HoursGroup.HoursPolicies; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.ICriterionType; import org.navalplanner.web.common.Util; import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.WrongValueException; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.util.GenericForwardComposer; +import org.zkoss.zul.Constraint; import org.zkoss.zul.Decimalbox; import org.zkoss.zul.Intbox; import org.zkoss.zul.Listbox; import org.zkoss.zul.Listcell; +import org.zkoss.zul.Listheader; import org.zkoss.zul.Listitem; import org.zkoss.zul.ListitemRenderer; import org.zkoss.zul.Popup; -import org.zkoss.zul.Textbox; +import org.zkoss.zul.api.Listhead; /** * Controller for {@link OrderElement} view of {@link Order} entities
@@ -32,10 +39,7 @@ import org.zkoss.zul.Textbox; */ public class OrderElementController extends GenericForwardComposer { - /** - * {@link OrderElement} that is managed - */ - private OrderElement orderElement; + private IOrderElementModel model; /** * {@link Popup} where {@link OrderElement} edition form is showed @@ -57,9 +61,14 @@ public class OrderElementController extends GenericForwardComposer { */ private Listbox hoursGroupsListbox; + private Set> selectedCriterionTypes = new HashSet>(); public OrderElement getOrderElement() { - return orderElement; + if (model == null) { + return new OrderLine(); + } + + return model.getOrderElement(); } public List getHoursGroupsModel() { @@ -86,15 +95,18 @@ public class OrderElementController extends GenericForwardComposer { * @param orderElement * The {@link OrderElement} to be edited */ - public void openPopup(OrderElement orderElement) { - this.orderElement = orderElement; + public void openPopup(IOrderElementModel model) { + + this.model = model; + + final OrderElement orderElement = model.getOrderElement(); this.hoursGroupsModel = orderElement.getHoursGroups(); // If is a container if (orderElement instanceof OrderLineGroup) { // Disable fields just used in the OrderLine - ((Textbox) popup.getFellow("totalHours")).setDisabled(true); + ((Intbox) popup.getFellow("totalHours")).setDisabled(true); // Hide not needed buttons popup.getFellow("manageCriterions").setVisible(false); @@ -102,17 +114,43 @@ public class OrderElementController extends GenericForwardComposer { popup.getFellow("deleteHoursGroup").setVisible(false); } else { // Enable fields just used in the OrderLine - ((Textbox) popup.getFellow("totalHours")).setDisabled(false); + ((Intbox) popup.getFellow("totalHours")).setDisabled(false); // Show needed buttons popup.getFellow("manageCriterions").setVisible(true); popup.getFellow("addHoursGroup").setVisible(true); popup.getFellow("deleteHoursGroup").setVisible(true); + + // Add EventListener to reload the popup when the value change + popup.getFellow("totalHours").addEventListener(Events.ON_CHANGE, + new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + Util.reloadBindings(popup); + } + }); + ((Intbox) popup.getFellow("totalHours")) + .setConstraint(new Constraint() { + + @Override + public void validate(Component comp, Object value) + throws WrongValueException { + if (!((OrderLine) orderElement) + .isTotalHoursValid((Integer) value)) { + throw new WrongValueException(comp, + "Value is not valid, taking into account " + + "the current list of HoursGroup"); + } + } + }); } Util.reloadBindings(popup); popup.open(popup.getParent(), "start-after"); + + reloadSelectedCriterionTypes(); } /** @@ -139,6 +177,8 @@ public class OrderElementController extends GenericForwardComposer { public void addHoursGroup() { HoursGroup hoursGroup = new HoursGroup(); + OrderElement orderElement = getOrderElement(); + ((OrderLine) orderElement).addHoursGroup(hoursGroup); this.hoursGroupsModel = orderElement.getHoursGroups(); @@ -153,6 +193,9 @@ public class OrderElementController extends GenericForwardComposer { */ public void deleteHoursGroups() { Set selectedItems = hoursGroupsListbox.getSelectedItems(); + + OrderElement orderElement = getOrderElement(); + for (Listitem item : selectedItems) { ((OrderLine) orderElement).deleteHoursGroup((HoursGroup) item .getValue()); @@ -162,6 +205,76 @@ public class OrderElementController extends GenericForwardComposer { Util.reloadBindings(popup); } + public void manageCriterions() { + Component selectCriterions = popup.getFellow("selectCriterions"); + + if (selectCriterions.isVisible()) { + selectCriterions.setVisible(false); + } else { + reloadSelectedCriterionTypes(); + selectCriterions.setVisible(true); + } + Util.reloadBindings(selectCriterions); + } + + public List> getCriterionTypes() { + if (model == null) { + return new ArrayList>(); + } + + List> list = model.getCriterionTypes(); + list.removeAll(getSelectedCriterionTypes()); + return list; + } + + public Set> getSelectedCriterionTypes() { + return selectedCriterionTypes; + } + + public void reloadSelectedCriterionTypes() { + OrderElement orderElement = getOrderElement(); + + if (orderElement == null) { + selectedCriterionTypes = new HashSet>(); + } else { + Set> criterionTypes = new HashSet>(); + + for (HoursGroup hoursGroup : orderElement.getHoursGroups()) { + Set criterions = hoursGroup.getCriterions(); + for (Criterion criterion : criterions) { + String type = criterion.getType(); + criterionTypes.add(model.getCriterionTypeByName(type)); + } + } + + selectedCriterionTypes = criterionTypes; + } + } + + public void assignCriterions(Set selectedItems) { + for (Listitem listitem : selectedItems) { + ICriterionType value = (ICriterionType) listitem.getValue(); + selectedCriterionTypes.add(value); + } + Util.reloadBindings(popup); + } + + public void unassignCriterions(Set selectedItems) { + for (Listitem listitem : selectedItems) { + ICriterionType value = (ICriterionType) listitem.getValue(); + selectedCriterionTypes.remove(value); + removeCriterionsFromHoursGroup(value); + } + Util.reloadBindings(popup); + } + + private void removeCriterionsFromHoursGroup(ICriterionType type) { + OrderElement orderElement = getOrderElement(); + for (HoursGroup hoursGroup : orderElement.getHoursGroups()) { + hoursGroup.removeCriterionByType(type); + } + } + /** * Represents every {@link HoursGroup} with an edition form if needed * @@ -173,6 +286,8 @@ public class OrderElementController extends GenericForwardComposer { public void render(Listitem item, Object data) throws Exception { final HoursGroup hoursGroup = (HoursGroup) data; + hoursGroup.getCriterions(); + item.setValue(hoursGroup); Listcell cellWorkingHours = new Listcell(); @@ -198,7 +313,7 @@ public class OrderElementController extends GenericForwardComposer { decimalBox.setScale(2); // If is a container - if (orderElement instanceof OrderLineGroup) { + if (getOrderElement() instanceof OrderLineGroup) { // Just getters are needed // Working hours @@ -244,6 +359,18 @@ public class OrderElementController extends GenericForwardComposer { } }); + // Add EventListener to reload the popup when the value change + workingHours.addEventListener(Events.ON_CHANGE, + new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + Util.reloadBindings(popup); + ((OrderLine) getOrderElement()) + .recalculatePercentages(); + } + }); + final Decimalbox percentage = Util.bind(decimalBox, new Util.Getter() { @@ -259,6 +386,18 @@ public class OrderElementController extends GenericForwardComposer { } }); + // Add EventListener to reload the popup when the value change + percentage.addEventListener(Events.ON_CHANGE, + new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + Util.reloadBindings(popup); + ((OrderLine) getOrderElement()) + .recalculatePercentages(); + } + }); + // Hours policy hoursPolicyListBox.setSelectedIndex(hoursGroup.getHoursPolicy() .ordinal()); @@ -286,6 +425,69 @@ public class OrderElementController extends GenericForwardComposer { cellPercentage.appendChild(percentage); cellHoursPolicy.appendChild(hoursPolicyListBox); + // For each ICriterionType selected + for (ICriterionType criterionType : getSelectedCriterionTypes()) { + Listcell cellCriterion = new Listcell(); + cellCriterion.setParent(item); + + // Add a new column on the HoursGroup table + Listhead header = ((Listbox) item.getParent()) + .getListheadApi(); + Listheader headerCriterion = new Listheader(); + headerCriterion.setLabel(criterionType.getName()); + headerCriterion.setParent(header); + + // Add a new Listbox for each ICriterionType + final Listbox criterionListbox = new Listbox(); + criterionListbox.setRows(1); + criterionListbox.setMold("select"); + + // Add an empty option to remove a Criterion + Listitem emptyListitem = new Listitem(); + emptyListitem.setParent(criterionListbox); + + // Get the Criterion of the current type in the HoursGroup + final Criterion criterionHoursGroup = hoursGroup + .getCriterionByType(criterionType); + + // For each possible Criterion of the current type + for (Criterion criterion : model + .getCriterionsFor(criterionType)) { + // Add the Criterion option + Listitem listitem = new Listitem(); + listitem.setValue(criterion); + listitem.setLabel(criterion.getName()); + listitem.setParent(criterionListbox); + + // Check if it matches with the HoursGroup criterion + if ((criterionHoursGroup != null) + && (criterionHoursGroup.getName() + .equals(criterion.getName()))) { + // Mark as selected + criterionListbox.setSelectedItem(listitem); + } + } + + // Add operation for Criterion selection + criterionListbox.addEventListener(Events.ON_SELECT, + new EventListener() { + + @Override + public void onEvent(Event event) + throws Exception { + Criterion criterion = (Criterion) criterionListbox + .getSelectedItem().getValue(); + if (criterion == null) { + hoursGroup + .removeCriterion(criterionHoursGroup); + } else { + hoursGroup.addCriterion(criterion); + } + } + }); + + cellCriterion.appendChild(criterionListbox); + } } } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementModel.java index a36447f37..99b5ae41f 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementModel.java @@ -1,201 +1,85 @@ package org.navalplanner.web.orders; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; -import org.navalplanner.business.orders.entities.IOrderLineGroup; -import org.navalplanner.business.orders.entities.Order; +import org.navalplanner.business.orders.daos.IOrderElementDao; import org.navalplanner.business.orders.entities.OrderElement; -import org.navalplanner.business.orders.entities.OrderLine; -import org.navalplanner.business.orders.entities.OrderLineGroup; -import org.zkoss.zul.SimpleTreeModel; -import org.zkoss.zul.SimpleTreeNode; +import org.navalplanner.business.resources.bootstrap.ICriterionsBootstrap; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.ICriterionType; +import org.navalplanner.business.resources.services.CriterionService; +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.springframework.transaction.annotation.Transactional; -/** - * Model for a the {@link OrderElement} tree for a {@link Order}
- * - * @author Lorenzo Tilve Álvaro - */ -public class OrderElementModel extends SimpleTreeModel { +@Component +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +public class OrderElementModel implements IOrderElementModel { - private static List asNodes(List orderElements) { - ArrayList result = new ArrayList(); - for (OrderElement orderElement : orderElements) { - result.add(asNode(orderElement)); + private OrderElement orderElement; + + @Autowired + private IOrderElementDao orderElementDao; + + @Autowired + private ICriterionsBootstrap criterionsBootstrap; + + @Autowired + private CriterionService criterionService; + + private Map> mapCriterionTypes = new HashMap>(); + + @Override + public OrderElement getOrderElement() { + return orderElement; + } + + @Override + @Transactional(readOnly = true) + public void setCurrent(OrderElement orderElement) { + // FIXME Review reattachment + boolean wasTransient = orderElement.isTransient(); + orderElementDao.save(orderElement); + orderElement.forceLoadHourGroupsCriterions(); + if (wasTransient) { + orderElement.makeTransientAgain(); } - return result; + this.orderElement = orderElement; } - private static SimpleTreeNode asNode(OrderElement orderElement) { - orderElement.forceLoadHourGroups(); - return new SimpleTreeNode(orderElement, asNodes(orderElement.getChildren())); - } + @Override + public List> getCriterionTypes() { + List> criterionTypes = criterionsBootstrap + .getTypes(); - private static SimpleTreeNode createRootNodeAndDescendants( - Order order) { - return new SimpleTreeNode(order, asNodes(order.getOrderElements())); - } - - public OrderElementModel(Order order) { - super(createRootNodeAndDescendants(order)); - } - - public void reloadFromOrder() { - Order root = getRootAsOrder(); - SimpleTreeNode rootAsNode = getRootAsNode(); - rootAsNode.getChildren().clear(); - rootAsNode.getChildren().addAll(asNodes(root.getOrderElements())); - } - - public void addOrderElement() { - addOrderElementAtImpl(getRootAsNode()); - reloadFromOrder(); - } - - private OrderElement createNewOrderElement() { - OrderElement newOrderElement = new OrderLine(); - newOrderElement.setName("New Order Element"); - return newOrderElement; - } - - public void addOrderElementAt(SimpleTreeNode node) { - addOrderElementAtImpl(node); - reloadFromOrder(); - } - - private void addOrderElementAtImpl(SimpleTreeNode node) { - addOrderElementAtImpl(node, createNewOrderElement()); - } - - private void addOrderElementAtImpl(SimpleTreeNode node, OrderElement orderElement) { - addOrderElementAtImpl(node, orderElement, node.getChildCount()); - } - - private void addOrderElementAtImpl(SimpleTreeNode destinationNode, OrderElement orderElement, - int position) { - IOrderLineGroup container = turnIntoContainerIfNeeded(destinationNode); - container.add(position, orderElement); - } - - private IOrderLineGroup turnIntoContainerIfNeeded( - SimpleTreeNode selectedForTurningIntoContainer) { - IOrderLineGroup parentContainer = asOrderLineGroup(getParent(selectedForTurningIntoContainer)); - if (selectedForTurningIntoContainer.getData() instanceof IOrderLineGroup) - return (IOrderLineGroup) selectedForTurningIntoContainer - .getData(); - OrderElement toBeTurned = asOrderLine(selectedForTurningIntoContainer); - OrderLineGroup asContainer = toBeTurned.asContainer(); - parentContainer.replace(toBeTurned, asContainer); - return asContainer; - } - - private SimpleTreeNode getParent(SimpleTreeNode node) { - int[] position = getPath(node); - SimpleTreeNode current = getRootAsNode(); - SimpleTreeNode[] path = new SimpleTreeNode[position.length]; - for (int i = 0; i < position.length; i++) { - path[i] = (SimpleTreeNode) current.getChildAt(position[i]); - current = path[i]; - } - int parentOfLast = path.length - 2; - if (parentOfLast >= 0) - return path[parentOfLast]; - else - return getRootAsNode(); - } - - public List getParents(SimpleTreeNode node) { - List parents = new ArrayList(); - SimpleTreeNode current = node; - - while (!current.equals(getRootAsNode())) { - current = getParent(current); - parents.add(current); + if (mapCriterionTypes.isEmpty()) { + for (ICriterionType criterionType : criterionTypes) { + mapCriterionTypes.put(criterionType.getName(), criterionType); + } } - return parents; + return criterionTypes; } - public void indent(SimpleTreeNode nodeToIndent) { - SimpleTreeNode parentOfSelected = getParent(nodeToIndent); - int position = parentOfSelected.getChildren().indexOf(nodeToIndent); - if (position == 0) { - return; + @Override + public ICriterionType getCriterionTypeByName(String name) { + if (mapCriterionTypes.isEmpty()) { + for (ICriterionType criterionType : criterionsBootstrap + .getTypes()) { + mapCriterionTypes.put(criterionType.getName(), criterionType); + } } - SimpleTreeNode destination = (SimpleTreeNode) parentOfSelected - .getChildren().get(position - 1); - moveImpl(nodeToIndent, destination, destination.getChildCount()); - reloadFromOrder(); + + return mapCriterionTypes.get(name); } - public void unindent(SimpleTreeNode nodeToUnindent) { - SimpleTreeNode parent = getParent(nodeToUnindent); - if (getRootAsNode() == parent) { - return; - } - SimpleTreeNode destination = getParent(parent); - moveImpl(nodeToUnindent, destination, destination.getChildren() - .indexOf(parent) + 1); - reloadFromOrder(); + @Override + public List getCriterionsFor(ICriterionType type) { + return (List) criterionService.getCriterionsFor(type); } - public void move(SimpleTreeNode toBeMoved, SimpleTreeNode destination) { - moveImpl(toBeMoved, destination, destination.getChildCount()); - reloadFromOrder(); - } - - private void moveImpl(SimpleTreeNode toBeMoved, SimpleTreeNode destination, - int position) { - if (destination.getChildren().contains(toBeMoved)) { - return;// it's already moved - } - removeNodeImpl(toBeMoved); - addOrderElementAtImpl(destination, asOrderLine(toBeMoved), position); - } - - public int[] getPath(SimpleTreeNode destination) { - int[] path = getPath(getRootAsNode(), destination); - return path; - } - - public void up(SimpleTreeNode node) { - IOrderLineGroup orderLineGroup = asOrderLineGroup(getParent(node)); - orderLineGroup.up(asOrderLine(node)); - reloadFromOrder(); - } - - public void down(SimpleTreeNode node) { - IOrderLineGroup orderLineGroup = asOrderLineGroup(getParent(node)); - orderLineGroup.down(asOrderLine(node)); - reloadFromOrder(); - } - - private Order getRootAsOrder() { - return (Order) getRootAsNode().getData(); - } - - private static OrderElement asOrderLine(SimpleTreeNode node) { - return (OrderElement) node.getData(); - } - - private static IOrderLineGroup asOrderLineGroup(SimpleTreeNode node) { - return (IOrderLineGroup) node.getData(); - } - - private SimpleTreeNode getRootAsNode() { - return (SimpleTreeNode) getRoot(); - } - - public void removeNode(SimpleTreeNode value) { - removeNodeImpl(value); - reloadFromOrder(); - } - - private void removeNodeImpl(SimpleTreeNode value) { - if (value == getRootAsNode()) - return; - IOrderLineGroup orderLineGroup = asOrderLineGroup(getParent(value)); - orderLineGroup.remove(asOrderLine(value)); - } - -} \ No newline at end of file +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java index 037e1a766..367efd85c 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java @@ -13,11 +13,13 @@ import org.navalplanner.business.orders.entities.OrderElement; import org.navalplanner.business.orders.entities.OrderLine; import org.navalplanner.web.common.Util; import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.WrongValueException; import org.zkoss.zk.ui.event.DropEvent; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.util.GenericForwardComposer; +import org.zkoss.zul.Constraint; import org.zkoss.zul.Datebox; import org.zkoss.zul.Intbox; import org.zkoss.zul.SimpleTreeNode; @@ -64,7 +66,7 @@ public class OrderElementTreeController extends GenericForwardComposer { } } - public OrderElementModel getOrderElementTreeModel() { + public OrderElementTreeModel getOrderElementTreeModel() { return orderModel.getOrderElementTreeModel(); } @@ -218,7 +220,7 @@ public class OrderElementTreeController extends GenericForwardComposer { map.put(t, intboxHours); if (orderElement instanceof OrderLine) { // If it's a leaf hours cell is editable - cellForHours.appendChild(Util.bind(intboxHours, + Intbox intbox = Util.bind(intboxHours, new Util.Getter() { @Override @@ -245,7 +247,23 @@ public class OrderElementTreeController extends GenericForwardComposer { .getWorkHours()); } } - })); + }); + // Checking hours value + intbox.setConstraint(new Constraint() { + + @Override + public void validate(Component comp, Object value) + throws WrongValueException { + if (!((OrderLine) orderElement) + .isTotalHoursValid((Integer) value)) { + throw new WrongValueException(comp, + "Value is not valid, taking into account " + + "the current list of HoursGroup"); + } + } + }); + + cellForHours.appendChild(intbox); } else { // If it's a container hours cell is not editable cellForHours.appendChild(Util.bind(intboxHours, @@ -326,7 +344,9 @@ public class OrderElementTreeController extends GenericForwardComposer { @Override public void onEvent(Event event) throws Exception { - orderElementController.openPopup(orderElement); + IOrderElementModel model = orderModel + .getOrderElementModel(orderElement); + orderElementController.openPopup(model); } }); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java new file mode 100644 index 000000000..109237e60 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java @@ -0,0 +1,201 @@ +package org.navalplanner.web.orders; + +import java.util.ArrayList; +import java.util.List; + +import org.navalplanner.business.orders.entities.IOrderLineGroup; +import org.navalplanner.business.orders.entities.Order; +import org.navalplanner.business.orders.entities.OrderElement; +import org.navalplanner.business.orders.entities.OrderLine; +import org.navalplanner.business.orders.entities.OrderLineGroup; +import org.zkoss.zul.SimpleTreeModel; +import org.zkoss.zul.SimpleTreeNode; + +/** + * Model for a the {@link OrderElement} tree for a {@link Order}
+ * + * @author Lorenzo Tilve Álvaro + */ +public class OrderElementTreeModel extends SimpleTreeModel { + + private static List asNodes(List orderElements) { + ArrayList result = new ArrayList(); + for (OrderElement orderElement : orderElements) { + result.add(asNode(orderElement)); + } + return result; + } + + private static SimpleTreeNode asNode(OrderElement orderElement) { + orderElement.forceLoadHourGroups(); + return new SimpleTreeNode(orderElement, asNodes(orderElement.getChildren())); + } + + private static SimpleTreeNode createRootNodeAndDescendants( + Order order) { + return new SimpleTreeNode(order, asNodes(order.getOrderElements())); + } + + public OrderElementTreeModel(Order order) { + super(createRootNodeAndDescendants(order)); + } + + public void reloadFromOrder() { + Order root = getRootAsOrder(); + SimpleTreeNode rootAsNode = getRootAsNode(); + rootAsNode.getChildren().clear(); + rootAsNode.getChildren().addAll(asNodes(root.getOrderElements())); + } + + public void addOrderElement() { + addOrderElementAtImpl(getRootAsNode()); + reloadFromOrder(); + } + + private OrderElement createNewOrderElement() { + OrderElement newOrderElement = new OrderLine(); + newOrderElement.setName("New Order Element"); + return newOrderElement; + } + + public void addOrderElementAt(SimpleTreeNode node) { + addOrderElementAtImpl(node); + reloadFromOrder(); + } + + private void addOrderElementAtImpl(SimpleTreeNode node) { + addOrderElementAtImpl(node, createNewOrderElement()); + } + + private void addOrderElementAtImpl(SimpleTreeNode node, OrderElement orderElement) { + addOrderElementAtImpl(node, orderElement, node.getChildCount()); + } + + private void addOrderElementAtImpl(SimpleTreeNode destinationNode, OrderElement orderElement, + int position) { + IOrderLineGroup container = turnIntoContainerIfNeeded(destinationNode); + container.add(position, orderElement); + } + + private IOrderLineGroup turnIntoContainerIfNeeded( + SimpleTreeNode selectedForTurningIntoContainer) { + IOrderLineGroup parentContainer = asOrderLineGroup(getParent(selectedForTurningIntoContainer)); + if (selectedForTurningIntoContainer.getData() instanceof IOrderLineGroup) + return (IOrderLineGroup) selectedForTurningIntoContainer + .getData(); + OrderElement toBeTurned = asOrderLine(selectedForTurningIntoContainer); + OrderLineGroup asContainer = toBeTurned.asContainer(); + parentContainer.replace(toBeTurned, asContainer); + return asContainer; + } + + private SimpleTreeNode getParent(SimpleTreeNode node) { + int[] position = getPath(node); + SimpleTreeNode current = getRootAsNode(); + SimpleTreeNode[] path = new SimpleTreeNode[position.length]; + for (int i = 0; i < position.length; i++) { + path[i] = (SimpleTreeNode) current.getChildAt(position[i]); + current = path[i]; + } + int parentOfLast = path.length - 2; + if (parentOfLast >= 0) + return path[parentOfLast]; + else + return getRootAsNode(); + } + + public List getParents(SimpleTreeNode node) { + List parents = new ArrayList(); + SimpleTreeNode current = node; + + while (!current.equals(getRootAsNode())) { + current = getParent(current); + parents.add(current); + } + + return parents; + } + + public void indent(SimpleTreeNode nodeToIndent) { + SimpleTreeNode parentOfSelected = getParent(nodeToIndent); + int position = parentOfSelected.getChildren().indexOf(nodeToIndent); + if (position == 0) { + return; + } + SimpleTreeNode destination = (SimpleTreeNode) parentOfSelected + .getChildren().get(position - 1); + moveImpl(nodeToIndent, destination, destination.getChildCount()); + reloadFromOrder(); + } + + public void unindent(SimpleTreeNode nodeToUnindent) { + SimpleTreeNode parent = getParent(nodeToUnindent); + if (getRootAsNode() == parent) { + return; + } + SimpleTreeNode destination = getParent(parent); + moveImpl(nodeToUnindent, destination, destination.getChildren() + .indexOf(parent) + 1); + reloadFromOrder(); + } + + public void move(SimpleTreeNode toBeMoved, SimpleTreeNode destination) { + moveImpl(toBeMoved, destination, destination.getChildCount()); + reloadFromOrder(); + } + + private void moveImpl(SimpleTreeNode toBeMoved, SimpleTreeNode destination, + int position) { + if (destination.getChildren().contains(toBeMoved)) { + return;// it's already moved + } + removeNodeImpl(toBeMoved); + addOrderElementAtImpl(destination, asOrderLine(toBeMoved), position); + } + + public int[] getPath(SimpleTreeNode destination) { + int[] path = getPath(getRootAsNode(), destination); + return path; + } + + public void up(SimpleTreeNode node) { + IOrderLineGroup orderLineGroup = asOrderLineGroup(getParent(node)); + orderLineGroup.up(asOrderLine(node)); + reloadFromOrder(); + } + + public void down(SimpleTreeNode node) { + IOrderLineGroup orderLineGroup = asOrderLineGroup(getParent(node)); + orderLineGroup.down(asOrderLine(node)); + reloadFromOrder(); + } + + private Order getRootAsOrder() { + return (Order) getRootAsNode().getData(); + } + + private static OrderElement asOrderLine(SimpleTreeNode node) { + return (OrderElement) node.getData(); + } + + private static IOrderLineGroup asOrderLineGroup(SimpleTreeNode node) { + return (IOrderLineGroup) node.getData(); + } + + private SimpleTreeNode getRootAsNode() { + return (SimpleTreeNode) getRoot(); + } + + public void removeNode(SimpleTreeNode value) { + removeNodeImpl(value); + reloadFromOrder(); + } + + private void removeNodeImpl(SimpleTreeNode value) { + if (value == getRootAsNode()) + return; + IOrderLineGroup orderLineGroup = asOrderLineGroup(getParent(value)); + orderLineGroup.remove(asOrderLine(value)); + } + +} \ No newline at end of file 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 e0f38e98e..24dcdb5e7 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 @@ -10,6 +10,7 @@ import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.common.exceptions.ValidationException; import org.navalplanner.business.orders.entities.IOrderLineGroup; import org.navalplanner.business.orders.entities.Order; +import org.navalplanner.business.orders.entities.OrderElement; import org.navalplanner.business.orders.services.IOrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; @@ -32,7 +33,10 @@ public class OrderModel implements IOrderModel { private ClassValidator orderValidator = new ClassValidator( Order.class); - private OrderElementModel orderElementTreeModel; + private OrderElementTreeModel orderElementTreeModel; + + @Autowired + private IOrderElementModel orderElementModel; @Autowired public OrderModel(IOrderService orderService) { @@ -52,7 +56,7 @@ public class OrderModel implements IOrderModel { Validate.notNull(order); try { this.order = orderService.find(order.getId()); - this.orderElementTreeModel = new OrderElementModel(this.order); + this.orderElementTreeModel = new OrderElementTreeModel(this.order); } catch (InstanceNotFoundException e) { throw new RuntimeException(e); } @@ -61,7 +65,7 @@ public class OrderModel implements IOrderModel { @Override public void prepareForCreate() { this.order = new Order(); - this.orderElementTreeModel = new OrderElementModel(this.order); + this.orderElementTreeModel = new OrderElementTreeModel(this.order); this.order.setInitDate(new Date()); } @@ -95,8 +99,14 @@ public class OrderModel implements IOrderModel { } @Override - public OrderElementModel getOrderElementTreeModel() { + public OrderElementTreeModel getOrderElementTreeModel() { return orderElementTreeModel; } + @Override + public IOrderElementModel getOrderElementModel(OrderElement orderElement) { + orderElementModel.setCurrent(orderElement); + return orderElementModel; + } + } diff --git a/navalplanner-webapp/src/main/webapp/orders/_editOrderElement.zul b/navalplanner-webapp/src/main/webapp/orders/_editOrderElement.zul index acfe99c4f..a1888c0df 100644 --- a/navalplanner-webapp/src/main/webapp/orders/_editOrderElement.zul +++ b/navalplanner-webapp/src/main/webapp/orders/_editOrderElement.zul @@ -35,7 +35,7 @@ @@ -54,9 +54,47 @@ onClick="orderElementController.addHoursGroup();" />