From d080447e2556d9961b21f68ca79d3f2889035cb5 Mon Sep 17 00:00:00 2001 From: Susana Montes Pedreira Date: Mon, 9 Nov 2009 18:31:35 +0100 Subject: [PATCH] ItEr34S07CUObtencionRequisitosEnProxectoTraballoItEr33S07 : Assign criterion requirements to order and its orderElements. --- .../entities/CriterionRequirementHandler.java | 414 ++++++++++++++++++ .../business/orders/entities/HoursGroup.java | 55 ++- .../ICriterionRequirementHandler.java | 28 ++ .../orders/entities/IOrderLineGroup.java | 1 - .../orders/entities/OrderElement.java | 109 ++++- .../business/orders/entities/OrderLine.java | 31 +- .../orders/entities/OrderLineGroup.java | 6 +- .../entities/CriterionRequirement.java | 3 +- .../entities/DirectCriterionRequirement.java | 1 - .../IndirectCriterionRequirement.java | 18 +- .../resources/entities/Criterion.java | 23 +- .../resources/entities/ICriterion.java | 2 +- .../navalplanner-business-spring-config.xml | 4 + .../business/orders/entities/Orders.hbm.xml | 2 +- .../entities/Requirements.hbm.xml | 2 +- .../resources/entities/Resources.hbm.xml | 5 + .../orders/entities/OrderElementTest.java | 39 ++ ...onRequirementToOrderElementController.java | 243 ++++++++++ ...iterionRequirementToOrderElementModel.java | 307 +++++++++++++ .../web/orders/CriterionRequirementDTO.java | 196 +++++++++ ...iterionRequirementToOrderElementModel.java | 30 ++ .../web/orders/OrderCRUDController.java | 15 + .../web/orders/OrderElementController.java | 22 +- .../web/orders/OrderElementModel.java | 2 + .../orders/OrderElementTreeController.java | 22 +- .../web/orders/OrderElementTreeModel.java | 19 +- .../navalplanner/web/orders/OrderModel.java | 31 +- .../worker/CriterionsController.java | 2 - .../main/webapp/orders/_editOrderElement.zul | 15 +- .../src/main/webapp/orders/_edition.zul | 6 +- ..._listOrderElementCriterionRequirements.zul | 90 ++++ 31 files changed, 1677 insertions(+), 66 deletions(-) create mode 100644 navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/CriterionRequirementHandler.java create mode 100644 navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/ICriterionRequirementHandler.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/orders/AssignedCriterionRequirementToOrderElementController.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/orders/AssignedCriterionRequirementToOrderElementModel.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/orders/CriterionRequirementDTO.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IAssignedCriterionRequirementToOrderElementModel.java create mode 100644 navalplanner-webapp/src/main/webapp/orders/_listOrderElementCriterionRequirements.zul diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/CriterionRequirementHandler.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/CriterionRequirementHandler.java new file mode 100644 index 000000000..2ee31c708 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/CriterionRequirementHandler.java @@ -0,0 +1,414 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.business.orders.entities; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.navalplanner.business.requirements.entities.CriterionRequirement; +import org.navalplanner.business.requirements.entities.DirectCriterionRequirement; +import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement; +import org.navalplanner.business.resources.entities.Criterion; + +/** + * @author Susana Montes Pedreira + */ +public class CriterionRequirementHandler implements + ICriterionRequirementHandler { + + private static final CriterionRequirementHandler singleton = new CriterionRequirementHandler(); + + private CriterionRequirementHandler() { + + } + + public static CriterionRequirementHandler getInstance() { + return singleton; + } + + // Operations to add a criterionRequirement + public void propagateDirectCriterionRequirementAddition( + OrderElement orderElement, CriterionRequirement directo) { + propagateIndirectCriterionRequirement(orderElement, + (DirectCriterionRequirement) directo); + } + + private void propagateIndirectCriterionRequirement( + OrderElement orderElement, + CriterionRequirement directo) { + if (orderElement instanceof OrderLine) { + propagateIndirectCriterionRequirementToChildren( + (OrderLine) orderElement, + (DirectCriterionRequirement) directo); + } else { + propagateIndirectCriterionRequirementToChildren( + (OrderLineGroup) orderElement, + (DirectCriterionRequirement) directo); + } + } + + void propagateIndirectCriterionRequirementToChildren( + OrderLineGroup orderLineGroup, DirectCriterionRequirement parent) { + Criterion criterion = parent.getCriterion(); + for (OrderElement child : orderLineGroup.getChildren()) { + IndirectCriterionRequirement indirect = IndirectCriterionRequirement + .create(parent, criterion); + child.addIndirectCriterionRequirement(indirect); + propagateIndirectCriterionRequirement(child, parent); + } + } + + void propagateIndirectCriterionRequirementToChildren(OrderLine orderLine, + DirectCriterionRequirement parent) { + Criterion criterion = parent.getCriterion(); + for (HoursGroup hoursGroup : orderLine.getHoursGroups()) { + CriterionRequirement indirect = IndirectCriterionRequirement + .create(parent, criterion); + hoursGroup.addCriterionRequirement(indirect); + } + } + + boolean canAddCriterionRequirement(OrderElement orderElement, + CriterionRequirement newRequirement) { + List listOrderElements = orderElement.getAllChildren(); + listOrderElements.add(orderElement); + for (OrderElement element : listOrderElements) { + if (existSameCriterionRequirement(element, newRequirement)) + return false; + } + return true; + } + + private boolean existSameCriterionRequirement(OrderElement orderElement, + CriterionRequirement newRequirement){ + if (orderElement instanceof OrderLine) { + return existSameCriterionRequirementIntoOrderLine( + (OrderLine) orderElement,newRequirement); + } else { + return existSameCriterionRequirementIntoOrderElement( + (OrderLineGroup) orderElement, newRequirement); + } + } + + private boolean existSameCriterionRequirementIntoOrderElement( + OrderElement orderElement, + CriterionRequirement newRequirement) { + Criterion criterion = newRequirement.getCriterion(); + for (CriterionRequirement requirement : orderElement + .getCriterionRequirements()) { + if (requirement.getCriterion().equals(criterion)) + return true; + } + return false; + } + + boolean existSameCriterionRequirementIntoOrderLine(OrderLine orderLine, + CriterionRequirement newRequirement) { + if (existSameCriterionRequirementIntoOrderElement(orderLine, + newRequirement)) { + return true; + } + for (HoursGroup hoursGroup : orderLine.getHoursGroups()) { + if (hoursGroup.existSameCriterionRequirement(newRequirement)) + return true; + } + return false; + } + + /* + * Operations to set the valid value of a criterion Requirements and the + * criterion Requirement of its children. + */ + + public void propagateValidCriterionRequirement(OrderElement orderElement, + DirectCriterionRequirement parent, boolean valid) { + if (orderElement instanceof OrderLine) { + setValidCriterionRequirementChildren((OrderLine) orderElement, + parent, valid); + } else { + setValidCriterionRequirementChildren((OrderLineGroup) orderElement, + parent, valid); + } + } + + protected void setValidCriterionRequirementChildren( + OrderLineGroup orderLineGroup, + DirectCriterionRequirement parent, boolean valid) { + for (OrderElement child : orderLineGroup.getChildren()) { + IndirectCriterionRequirement indirect = findIndirectRequirementByParent( + child.getIndirectCriterionRequirement(), parent); + if (indirect != null) { + indirect.setIsValid(valid); + } + propagateValidCriterionRequirement(child, parent, valid); + } + } + + protected void setValidCriterionRequirementChildren(OrderLine orderLine, + DirectCriterionRequirement parent, boolean valid) { + for (HoursGroup hoursGroup : orderLine.getHoursGroups()) { + IndirectCriterionRequirement indirect = findIndirectRequirementByParent( + hoursGroup.getIndirectCriterionRequirement(), parent); + if (indirect != null) { + indirect.setIsValid(valid); + } + } + } + + /* + * Operation to update the criterions requirements of the orderElement and + * its children + */ + public void propagateRemoveCriterionRequirement(OrderElement orderElement, + DirectCriterionRequirement parent) { + if (orderElement instanceof OrderLine) { + removeIndirectCriterionRequirement((OrderLine) orderElement, parent); + } else { + removeIndirectCriterionRequirement((OrderLineGroup) orderElement, + parent); + } + } + + protected void removeIndirectCriterionRequirement( + OrderLineGroup orderLineGroup, DirectCriterionRequirement parent) { + for (OrderElement child : orderLineGroup.getChildren()) { + IndirectCriterionRequirement indirect = findIndirectRequirementByParent( + child.getIndirectCriterionRequirement(), parent); + if (indirect != null) { + propagateRemoveCriterionRequirement(child, parent); + child.removeCriterionRequirement(indirect); + } + } + } + + protected void removeIndirectCriterionRequirement(OrderLine orderLine, + DirectCriterionRequirement parent) { + for (HoursGroup hoursGroup : orderLine.getHoursGroups()) { + IndirectCriterionRequirement indirect = findIndirectRequirementByParent( + hoursGroup.getIndirectCriterionRequirement(), parent); + if (indirect != null) { + hoursGroup.removeCriterionRequirement(indirect); + } + } + } + + /* + * Operation to update the criterions requirements of the orderElement and + * its children + */ + + public void propagateUpdateCriterionRequirements(OrderElement orderElement) { + if (orderElement instanceof OrderLine) { + updateCriterionRequirementsIntoOrderLine((OrderLine) orderElement); + } else { + updateCriterionRequirementsIntoOrderLineGroup((OrderLineGroup) orderElement); + } + } + + private void updateCriterionRequirementsIntoOrderLineGroup( + OrderElement orderLineGroup) { + for (OrderElement child : orderLineGroup.getChildren()) { + child.updateMyCriterionRequirements(); + propagateUpdateCriterionRequirements(child); + } + } + + private void updateCriterionRequirementsIntoOrderLine(OrderLine orderLine) { + for (HoursGroup hoursGroup : orderLine.getHoursGroups()) { + hoursGroup.updateMyCriterionRequirements(); + } + } + + void transformDirectToIndirectIfNeeded(OrderElement orderElement, + Set currents) { + for (DirectCriterionRequirement direct : orderElement + .getDirectCriterionRequirement()) { + IndirectCriterionRequirement indirect = findIndirectRequirementByCriterion( + currents, direct.getCriterion()); + if (indirect != null) { + orderElement.removeDirectCriterionRequirement(direct); + } + } + } + + void addNewsIndirects(OrderElement orderElement, + Set currents) { + Set indirects = orderElement + .getIndirectCriterionRequirement(); + for (IndirectCriterionRequirement current : currents) { + if (!indirects.contains(current)) { + orderElement.addCriterionRequirement(current); + } + } + } + + void removeOldIndirects(OrderElement orderElement, + Set currents) { + for (IndirectCriterionRequirement indirect : orderElement + .getIndirectCriterionRequirement()) { + if (!currents.contains(indirect)) { + orderElement.removeCriterionRequirement(indirect); + } + } + } + + void transformDirectToIndirectIfNeeded(HoursGroup hoursGroup, + Set currents) { + for (DirectCriterionRequirement direct : hoursGroup + .getDirectCriterionRequirement()) { + IndirectCriterionRequirement indirect = findIndirectRequirementByCriterion( + currents, direct.getCriterion()); + if (indirect != null) { + hoursGroup.removeCriterionRequirement(direct); + } + } + } + + void addNewsIndirects(HoursGroup hoursGroup, + Set currents) { + Set indirects = hoursGroup + .getIndirectCriterionRequirement(); + for (IndirectCriterionRequirement current : currents) { + if (!indirects.contains(current)) { + hoursGroup.addCriterionRequirement(current); + } + } + } + + void removeOldIndirects(HoursGroup hoursGroup, + Set currents) { + for (IndirectCriterionRequirement indirect : hoursGroup + .getIndirectCriterionRequirement()) { + if (!currents.contains(indirect)) { + hoursGroup.removeCriterionRequirement(indirect); + } + } + } + + Set getCurrentIndirectRequirements( + Set oldIndirects, OrderElement parent) { + Set currentIndirects = new HashSet(); + for (CriterionRequirement requirement : parent + .getCriterionRequirements()) { + IndirectCriterionRequirement indirect = getCurrentIndirectRequirement( + oldIndirects, requirement); + currentIndirects.add(indirect); + } + return currentIndirects; + } + + IndirectCriterionRequirement getCurrentIndirectRequirement( + Set oldIndirects, + CriterionRequirement requirement) { + IndirectCriterionRequirement indirect; + DirectCriterionRequirement parent; + if (requirement instanceof DirectCriterionRequirement) { + parent = (DirectCriterionRequirement) requirement; + indirect = findIndirectRequirementByParent(oldIndirects, parent); + } else { + parent = ((IndirectCriterionRequirement) requirement).getParent(); + indirect = findIndirectRequirementByParent(oldIndirects, parent); + } + if (indirect == null) { + indirect = IndirectCriterionRequirement.create(parent, requirement + .getCriterion()); + } + return (IndirectCriterionRequirement) indirect; + } + + private IndirectCriterionRequirement findIndirectRequirementByParent( + Set indirects, + DirectCriterionRequirement newParent) { + for (IndirectCriterionRequirement requirement : indirects) { + if (requirement.getParent().equals(newParent)) { + return requirement; + } + } + return null; + } + + private IndirectCriterionRequirement findIndirectRequirementByCriterion( + Set indirects, Criterion criterion) { + for (IndirectCriterionRequirement requirement : indirects) { + if (requirement.getCriterion().equals(criterion)) { + return requirement; + } + } + return null; + } + /* + * Operation to create and add to a orderElement new criterion requirements + * that it is copied of the criterion requirements of other orderElement + */ + protected void copyRequirementToOrderElement(OrderLine orderLine, + OrderLineGroup container) { + // copy the directCriterionRequirement + for (DirectCriterionRequirement newRequirement : copyDirectRequirements(orderLine + .getDirectCriterionRequirement())) { + container.addCriterionRequirement(newRequirement); + } + // copy the IndirectCriterionRequirement + for (IndirectCriterionRequirement newRequirement : copyIndirectRequirements(orderLine + .getIndirectCriterionRequirement())) { + container.addCriterionRequirement(newRequirement); + } + } + + protected void copyRequirementToOrderElement(OrderLineGroup orderLineGroup, + OrderLine leaf) { + // copy the directCriterionRequirement + for (DirectCriterionRequirement newRequirement : copyDirectRequirements(orderLineGroup + .getDirectCriterionRequirement())) { + leaf.addDirectCriterionRequirement(newRequirement); + } + // copy the IndirectCriterionRequirement + for (IndirectCriterionRequirement newRequirement : copyIndirectRequirements(orderLineGroup + .getIndirectCriterionRequirement())) { + leaf.addIndirectCriterionRequirement(newRequirement); + propagateIndirectCriterionRequirementToChildren(leaf, + newRequirement.getParent()); + } + } + + private Set copyDirectRequirements(Set collection){ + Set result = new HashSet(); + for (DirectCriterionRequirement requirement : collection) { + DirectCriterionRequirement newRequirement = DirectCriterionRequirement + .create(requirement.getCriterion()); + result.add(newRequirement); + } + return result; + } + + private Set copyIndirectRequirements( + Set collection) { + Set result = new HashSet(); + for (IndirectCriterionRequirement requirement : collection) { + DirectCriterionRequirement parent = requirement.getParent(); + IndirectCriterionRequirement newRequirement = IndirectCriterionRequirement + .create(parent, requirement.getCriterion()); + result.add(newRequirement); + } + return result; + } + +} 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 91774e395..50661534e 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 @@ -20,16 +20,16 @@ package org.navalplanner.business.orders.entities; import java.math.BigDecimal; -import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.Set; import org.hibernate.validator.NotNull; +import org.hibernate.validator.Valid; import org.navalplanner.business.common.BaseEntity; import org.navalplanner.business.requirements.entities.CriterionRequirement; import org.navalplanner.business.requirements.entities.DirectCriterionRequirement; +import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement; import org.navalplanner.business.resources.entities.Criterion; @@ -53,6 +53,9 @@ public class HoursGroup extends BaseEntity implements Cloneable { @NotNull private OrderLine parentOrderLine; + protected CriterionRequirementHandler criterionRequirementHandler = CriterionRequirementHandler + .getInstance(); + /** * Constructor for hibernate. Do not use! */ @@ -113,6 +116,7 @@ public class HoursGroup extends BaseEntity implements Cloneable { this.criterionRequirements = criterionRequirements; } + @Valid public Set getCriterionRequirements() { return criterionRequirements; } @@ -133,7 +137,7 @@ public class HoursGroup extends BaseEntity implements Cloneable { throw new IllegalStateException( " The " + requirement.getCriterion().getName() - + " can not be assigned to this hoursGroup because it already exist in other hoursGroup"); + + " can not be assigned to this hoursGroup because it already exist into the hoursGroup"); } } @@ -157,8 +161,16 @@ public class HoursGroup extends BaseEntity implements Cloneable { } } - public void removeCriterionRequirement(CriterionRequirement criterionRequirement) { - criterionRequirements.remove(criterionRequirement); + public void removeCriterionRequirement(CriterionRequirement requirement) { + criterionRequirements.remove(requirement); + if (requirement instanceof IndirectCriterionRequirement) { + ((IndirectCriterionRequirement) requirement).getParent() + .getChildren().remove( + (IndirectCriterionRequirement) requirement); + } + requirement.setCriterion(null); + requirement.setHoursGroup(null); + requirement.setOrderElement(null); } /* TO REMOVE */ @@ -198,8 +210,27 @@ public class HoursGroup extends BaseEntity implements Cloneable { return parentOrderLine; } - private List getDirectCriterionRequirement() { - List list = new ArrayList(); + void updateMyCriterionRequirements() { + OrderElement newParent = this.getParentOrderLine(); + Set currentIndirects = criterionRequirementHandler + .getCurrentIndirectRequirements( + getIndirectCriterionRequirement(), newParent); + criterionRequirementHandler.removeOldIndirects(this, currentIndirects); + criterionRequirementHandler.addNewsIndirects(this, currentIndirects); + } + + Set getIndirectCriterionRequirement() { + Set list = new HashSet(); + for(CriterionRequirement criterionRequirement : criterionRequirements ){ + if(criterionRequirement instanceof IndirectCriterionRequirement){ + list.add((IndirectCriterionRequirement) criterionRequirement); + } + } + return list; + } + + public Set getDirectCriterionRequirement() { + Set list = new HashSet(); for(CriterionRequirement criterionRequirement : criterionRequirements ){ if(criterionRequirement instanceof DirectCriterionRequirement){ list.add((DirectCriterionRequirement) criterionRequirement); @@ -207,4 +238,14 @@ public class HoursGroup extends BaseEntity implements Cloneable { } return list; } + + public boolean existSameCriterionRequirement(CriterionRequirement newRequirement){ + Criterion criterion = newRequirement.getCriterion(); + for(CriterionRequirement requirement : getCriterionRequirements()){ + if(requirement.getCriterion().equals(criterion)) + return true; + } + return false; + } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/ICriterionRequirementHandler.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/ICriterionRequirementHandler.java new file mode 100644 index 000000000..491cce94d --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/ICriterionRequirementHandler.java @@ -0,0 +1,28 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.business.orders.entities; + +/** + * @author Susana Montes Pedreira + */ +public interface ICriterionRequirementHandler { + +} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/IOrderLineGroup.java b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/IOrderLineGroup.java index 5f19d1621..19b7e9ebf 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/IOrderLineGroup.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/orders/entities/IOrderLineGroup.java @@ -39,5 +39,4 @@ public interface IOrderLineGroup { public void down(OrderElement orderElement); public void add(int position, OrderElement orderElement); - } \ No newline at end of file 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 ed5f3767d..3b33e2653 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 @@ -30,6 +30,7 @@ import java.util.Set; import org.apache.commons.lang.Validate; import org.hibernate.validator.NotEmpty; +import org.hibernate.validator.Valid; import org.joda.time.LocalDate; import org.navalplanner.business.advance.entities.AdvanceAssignment; import org.navalplanner.business.advance.entities.AdvanceType; @@ -42,7 +43,9 @@ import org.navalplanner.business.labels.entities.Label; import org.navalplanner.business.planner.entities.Task; import org.navalplanner.business.planner.entities.TaskElement; import org.navalplanner.business.requirements.entities.CriterionRequirement; +import org.navalplanner.business.requirements.entities.DirectCriterionRequirement; import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement; +import org.navalplanner.business.resources.entities.Criterion; public abstract class OrderElement extends BaseEntity { @@ -72,6 +75,9 @@ public abstract class OrderElement extends BaseEntity { protected OrderLineGroup parent; + protected CriterionRequirementHandler criterionRequirementHandler = CriterionRequirementHandler + .getInstance(); + public OrderLineGroup getParent() { return parent; } @@ -326,22 +332,98 @@ public abstract class OrderElement extends BaseEntity { return result; } + public void setCriterionRequirements( + Set criterionRequirements) { + this.criterionRequirements = criterionRequirements; + } + + @Valid public Set getCriterionRequirements() { return Collections.unmodifiableSet(criterionRequirements); } - public void removeCriterionRequirement(CriterionRequirement criterionRequirement){ - //Remove the criterionRequirement into orderelement. - criterionRequirements.remove(criterionRequirement); + protected Set myCriterionRequirements() { + return criterionRequirements; } - public void addCriterionRequirement(CriterionRequirement criterionRequirement){ - criterionRequirement.setOrderElement(this); - this.criterionRequirements.add(criterionRequirement); + + /* + * Operations to manage the criterion requirements of a orderElement + * (remove, adding, update of the criterion requirement of the orderElement + * such as the descendent's criterion requirement) + */ + + public void setValidCriterionRequirement(IndirectCriterionRequirement requirement,boolean valid){ + requirement.setIsValid(valid); + criterionRequirementHandler.propagateValidCriterionRequirement(this, + requirement.getParent(), valid); } - protected List getIndirectCriterionRequirement() { - List list = new ArrayList(); + public void removeDirectCriterionRequirement(DirectCriterionRequirement criterionRequirement){ + criterionRequirementHandler.propagateRemoveCriterionRequirement(this, + criterionRequirement); + removeCriterionRequirement(criterionRequirement); + + } + + protected void removeCriterionRequirement(CriterionRequirement requirement) { + criterionRequirements.remove(requirement); + if(requirement instanceof IndirectCriterionRequirement){ + ((IndirectCriterionRequirement)requirement).getParent(). + getChildren().remove((IndirectCriterionRequirement)requirement); + } + } + + public void addDirectCriterionRequirement( + CriterionRequirement newRequirement) { + if (criterionRequirementHandler.canAddCriterionRequirement(this, + newRequirement)) { + addCriterionRequirement(newRequirement); + criterionRequirementHandler + .propagateDirectCriterionRequirementAddition(this, + newRequirement); + } else { + Criterion criterion = newRequirement.getCriterion(); + throw new IllegalStateException(" The " + criterion.getName() + + " already exist into other order element"); + } + } + + void addIndirectCriterionRequirement( + IndirectCriterionRequirement criterionRequirement) { + addCriterionRequirement(criterionRequirement); + } + + protected void addCriterionRequirement( + CriterionRequirement criterionRequirement) { + criterionRequirement.setOrderElement(this); + this.criterionRequirements.add(criterionRequirement); + } + + public void updateCriterionRequirements() { + updateMyCriterionRequirements(); + criterionRequirementHandler.propagateUpdateCriterionRequirements(this); + } + + void updateMyCriterionRequirements() { + OrderElement newParent = this.getParent(); + Set currentIndirects = criterionRequirementHandler + .getCurrentIndirectRequirements( + getIndirectCriterionRequirement(), newParent); + criterionRequirementHandler.transformDirectToIndirectIfNeeded(this, + currentIndirects); + criterionRequirementHandler.removeOldIndirects(this, currentIndirects); + criterionRequirementHandler.addNewsIndirects(this, currentIndirects); + } + + public boolean canAddCriterionRequirement( + DirectCriterionRequirement newRequirement) { + return criterionRequirementHandler.canAddCriterionRequirement(this, + newRequirement); + } + + protected Set getIndirectCriterionRequirement() { + Set list = new HashSet(); for (CriterionRequirement criterionRequirement : criterionRequirements) { if (criterionRequirement instanceof IndirectCriterionRequirement) { list.add((IndirectCriterionRequirement) criterionRequirement); @@ -364,4 +446,15 @@ public abstract class OrderElement extends BaseEntity { protected void applyStartConstraintTo(Task task) { task.getStartConstraint().notEarlierThan(this.getInitDate()); } + + public Set getDirectCriterionRequirement() { + Set list = new HashSet(); + for (CriterionRequirement criterionRequirement : criterionRequirements) { + if (criterionRequirement instanceof DirectCriterionRequirement) { + list.add((DirectCriterionRequirement) criterionRequirement); + } + } + return list; + } + } 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 e63e5beae..ccc048ba4 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 @@ -29,6 +29,8 @@ import java.util.Set; import org.joda.time.LocalDate; import org.navalplanner.business.advance.entities.AdvanceType; import org.navalplanner.business.advance.entities.DirectAdvanceAssignment; +import org.navalplanner.business.requirements.entities.CriterionRequirement; +import org.navalplanner.business.requirements.entities.DirectCriterionRequirement; public class OrderLine extends OrderElement { @@ -85,6 +87,12 @@ public class OrderLine extends OrderElement { result.setInitDate(getInitDate()); result.setDeadline(getDeadline()); + // copy the criterion requirements to container + copyRequirementToOrderElement(result); + + // removed the direct criterion requirements + removeAllDirectCriterionRequirement(); + this.setName(getName() + " (copy)"); this.setCode(getCode() + " (copy)"); result.add(this); @@ -92,6 +100,14 @@ public class OrderLine extends OrderElement { return result; } + private void removeAllDirectCriterionRequirement() { + Set directRequirements = new HashSet( + getDirectCriterionRequirement()); + for (DirectCriterionRequirement requirement : directRequirements) { + removeDirectCriterionRequirement(requirement); + } + } + @Override public List getHoursGroups() { return new ArrayList(hoursGroups); @@ -386,7 +402,6 @@ public class OrderLine extends OrderElement { protected Set getAllDirectAdvanceAssignments( AdvanceType advanceType) { Set result = new HashSet(); - for (DirectAdvanceAssignment directAdvanceAssignment : directAdvanceAssignments) { if (directAdvanceAssignment.getAdvanceType().getUnitName().equals( advanceType.getUnitName())) { @@ -394,7 +409,6 @@ public class OrderLine extends OrderElement { return result; } } - return result; } @@ -406,7 +420,6 @@ public class OrderLine extends OrderElement { @Override protected Set getAllDirectAdvanceAssignmentsReportGlobal() { Set result = new HashSet(); - for (DirectAdvanceAssignment directAdvanceAssignment : directAdvanceAssignments) { if (directAdvanceAssignment.getReportGlobalAdvance()) { result.add(directAdvanceAssignment); @@ -415,4 +428,16 @@ public class OrderLine extends OrderElement { } return result; } + + public boolean existSameCriterionRequirement( + CriterionRequirement newRequirement) { + return criterionRequirementHandler + .existSameCriterionRequirementIntoOrderLine(this, + newRequirement); + } + + protected void copyRequirementToOrderElement(OrderLineGroup container) { + criterionRequirementHandler.copyRequirementToOrderElement(this, + container); + } } 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 78334d0b0..3ad3f1ac5 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 @@ -159,7 +159,7 @@ public class OrderLineGroup extends OrderElement implements IOrderLineGroup { result.setWorkHours(0); result.directAdvanceAssignments = new HashSet( this.directAdvanceAssignments); - + copyRequirementToOrderElement(result); return result; } @@ -672,4 +672,8 @@ public class OrderLineGroup extends OrderElement implements IOrderLineGroup { } } } + + protected void copyRequirementToOrderElement(OrderLine leaf) { + criterionRequirementHandler.copyRequirementToOrderElement(this, leaf); + } } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/requirements/entities/CriterionRequirement.java b/navalplanner-business/src/main/java/org/navalplanner/business/requirements/entities/CriterionRequirement.java index 7550e335e..f46dc6e9e 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/requirements/entities/CriterionRequirement.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/requirements/entities/CriterionRequirement.java @@ -19,7 +19,6 @@ */ package org.navalplanner.business.requirements.entities; - import org.hibernate.validator.NotNull; import org.navalplanner.business.common.BaseEntity; import org.navalplanner.business.orders.entities.HoursGroup; @@ -36,7 +35,6 @@ public class CriterionRequirement extends BaseEntity{ private OrderElement orderElement; - @NotNull private Criterion criterion; public CriterionRequirement(){ @@ -54,6 +52,7 @@ public class CriterionRequirement extends BaseEntity{ this.hoursGroup = hoursGroup; } + @NotNull public Criterion getCriterion() { return criterion; } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/requirements/entities/DirectCriterionRequirement.java b/navalplanner-business/src/main/java/org/navalplanner/business/requirements/entities/DirectCriterionRequirement.java index 192e822fb..a5402e050 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/requirements/entities/DirectCriterionRequirement.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/requirements/entities/DirectCriterionRequirement.java @@ -78,5 +78,4 @@ public class DirectCriterionRequirement extends CriterionRequirement{ children) { this.children = children; } - } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/requirements/entities/IndirectCriterionRequirement.java b/navalplanner-business/src/main/java/org/navalplanner/business/requirements/entities/IndirectCriterionRequirement.java index 2962cf267..5f09961dc 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/requirements/entities/IndirectCriterionRequirement.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/requirements/entities/IndirectCriterionRequirement.java @@ -31,20 +31,14 @@ import org.navalplanner.business.orders.entities.OrderElement; */ public class IndirectCriterionRequirement extends CriterionRequirement{ - @NotNull private DirectCriterionRequirement parent; private Boolean isValid = true; - public static IndirectCriterionRequirement create() { - IndirectCriterionRequirement result = new IndirectCriterionRequirement(); - result.setNewObject(true); - return result; - } - public static IndirectCriterionRequirement create(DirectCriterionRequirement parent,Criterion criterion) { IndirectCriterionRequirement result = new IndirectCriterionRequirement(criterion); + result.setNewObject(true); result.setParent(parent); return result; } @@ -57,14 +51,6 @@ public class IndirectCriterionRequirement extends CriterionRequirement{ return result; } - public static IndirectCriterionRequirement create(DirectCriterionRequirement - parent,Boolean isValid) { - IndirectCriterionRequirement result = create(); - result.setParent(parent); - result.setIsValid(isValid); - return result; - } - /** * Constructor for hibernate. Do not use! */ @@ -81,6 +67,7 @@ public class IndirectCriterionRequirement extends CriterionRequirement{ super(criterion,orderElement,hoursGroup); } + @NotNull public DirectCriterionRequirement getParent() { return parent; } @@ -97,5 +84,4 @@ public class IndirectCriterionRequirement extends CriterionRequirement{ public void setIsValid(boolean isValid) { this.isValid = isValid; } - } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java index b519fc0ae..491528273 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java @@ -21,6 +21,7 @@ package org.navalplanner.business.resources.entities; +import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Set; @@ -32,6 +33,7 @@ import org.hibernate.validator.NotEmpty; import org.hibernate.validator.NotNull; import org.hibernate.validator.Valid; import org.navalplanner.business.common.BaseEntity; +import org.navalplanner.business.requirements.entities.CriterionRequirement; /** * A criterion stored in the database
@@ -71,6 +73,7 @@ public class Criterion extends BaseEntity implements ICriterion { private boolean active = true; + private Set criterionRequirements = new HashSet(); /* * Just for Hibernate mapping in order to have an unique constraint with * name and type properties. @@ -177,9 +180,27 @@ public class Criterion extends BaseEntity implements ICriterion { } } } - return true; } + public Set getCriterionRequirements() { + return Collections.unmodifiableSet(criterionRequirements); + } + + public void setCriterionRequirements( + Set criterionRequirements) { + this.criterionRequirements = criterionRequirements; + } + + public void removeCriterionRequirement( + CriterionRequirement criterionRequirement) { + this.criterionRequirements.remove(criterionRequirement); + } + + public void addCriterionRequirement( + CriterionRequirement criterionRequirement) { + criterionRequirement.setCriterion(this); + this.criterionRequirements.add(criterionRequirement); + } } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterion.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterion.java index c2454b07b..10d20217a 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterion.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterion.java @@ -32,4 +32,4 @@ public interface ICriterion { boolean isSatisfiedBy(Resource resource, Date start, Date end); -} +} \ No newline at end of file diff --git a/navalplanner-business/src/main/resources/navalplanner-business-spring-config.xml b/navalplanner-business/src/main/resources/navalplanner-business-spring-config.xml index 0d6c68170..e5b188a36 100644 --- a/navalplanner-business/src/main/resources/navalplanner-business-spring-config.xml +++ b/navalplanner-business/src/main/resources/navalplanner-business-spring-config.xml @@ -75,4 +75,8 @@ class="org.navalplanner.business.common.Registry" factory-method="getInstance" /> + + 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 e9770da1c..c1b4e8e74 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 @@ -30,7 +30,7 @@ - + diff --git a/navalplanner-business/src/main/resources/org/navalplanner/business/requirements/entities/Requirements.hbm.xml b/navalplanner-business/src/main/resources/org/navalplanner/business/requirements/entities/Requirements.hbm.xml index 0e6e25213..da4af62db 100644 --- a/navalplanner-business/src/main/resources/org/navalplanner/business/requirements/entities/Requirements.hbm.xml +++ b/navalplanner-business/src/main/resources/org/navalplanner/business/requirements/entities/Requirements.hbm.xml @@ -17,7 +17,7 @@ - + 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 e9e7dc502..d44e52c78 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 @@ -66,6 +66,11 @@ + + + + + orderElementValidator = + new ClassValidator(OrderElement.class); + private static OrderLine givenOrderLine(String name, String code, Integer hours) { OrderLine orderLine = OrderLine @@ -166,6 +177,34 @@ public class OrderElementTest { return advanceType; } + @Test + public void checkValidPropagation()throws ValidationException{ + OrderElement orderElement = givenOrderLineGroupWithTwoOrderLines(1000, + 2000); + try { + InvalidValue[] invalidValues = + orderElementValidator.getInvalidValues(orderElement); + if (invalidValues.length > 0) + throw new ValidationException(invalidValues); + } catch (ValidationException e) { + fail("It not should throw an exception"); + } + CriterionType type = CriterionType.create("", ""); + Criterion criterion = Criterion.create(type); + CriterionRequirement requirement = DirectCriterionRequirement + .create(criterion); + requirement.setOrderElement(orderElement); + orderElement.addDirectCriterionRequirement(requirement); + try { + InvalidValue[] invalidValues = + orderElementValidator.getInvalidValues(orderElement); + if (invalidValues.length > 0) + throw new ValidationException(invalidValues); + } catch (ValidationException e) { + fail("It no should throw an exception"); + } + } + @Test public void checkAdvancePercentageEmptyOrderLine() { OrderLine orderLine = givenOrderLine("name", "code", 1000); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/AssignedCriterionRequirementToOrderElementController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/AssignedCriterionRequirementToOrderElementController.java new file mode 100644 index 000000000..01c9a0c59 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/AssignedCriterionRequirementToOrderElementController.java @@ -0,0 +1,243 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.orders; + +import static org.navalplanner.web.I18nHelper._; + +import java.util.List; + +import org.hibernate.validator.InvalidValue; +import org.navalplanner.business.common.exceptions.ValidationException; +import org.navalplanner.business.orders.entities.OrderElement; +import org.navalplanner.business.resources.entities.CriterionWithItsType; +import org.navalplanner.business.workreports.entities.WorkReportLine; +import org.navalplanner.web.common.IMessagesForUser; +import org.navalplanner.web.common.MessagesForUser; +import org.navalplanner.web.common.Util; +import org.navalplanner.web.common.components.NewDataSortableGrid; +import org.navalplanner.web.resources.worker.CriterionSatisfactionDTO; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.WrongValueException; +import org.zkoss.zk.ui.util.GenericForwardComposer; +import org.zkoss.zul.Bandbox; +import org.zkoss.zul.Hbox; +import org.zkoss.zul.Listitem; +import org.zkoss.zul.Row; +import org.zkoss.zul.Rows; +import org.zkoss.zul.Vbox; + +/** + * Controller for showing OrderElement assigned labels + * + * @author Susana Montes Pedreira + */ +public class AssignedCriterionRequirementToOrderElementController extends + GenericForwardComposer { + + private IAssignedCriterionRequirementToOrderElementModel assignedCriterionRequirementToOrderElementModel; + + private Vbox vbox; + + private NewDataSortableGrid listingRequirements; + + private IMessagesForUser messages; + + private Component messagesContainer; + + @Override + public void doAfterCompose(Component comp) throws Exception { + super.doAfterCompose(comp); + if (messagesContainer == null) + throw new RuntimeException(_("MessagesContainer is needed")); + messages = new MessagesForUser(messagesContainer); + comp.setVariable("assignedCriterionRequirementController", this, true); + vbox = (Vbox) comp; + } + + public OrderElement getOrderElement() { + return assignedCriterionRequirementToOrderElementModel.getOrderElement(); + } + + public void setOrderElement(OrderElement orderElement) { + assignedCriterionRequirementToOrderElementModel.setOrderElement(orderElement); + } + + public void openWindow(IOrderElementModel orderElementModel) { + assignedCriterionRequirementToOrderElementModel.setOrderModel(orderElementModel + .getOrderModel()); + openWindow(orderElementModel.getOrderElement()); + } + + public void openWindow(OrderElement orderElement) { + assignedCriterionRequirementToOrderElementModel.init(orderElement); + Util.reloadBindings(vbox); + } + + public boolean close() { + try{ + assignedCriterionRequirementToOrderElementModel.confirm(); + return true; + }catch (ValidationException e) { + showInvalidValues(e); + } + return false; + } + + public List criterionRequirementDTOs(){ + return assignedCriterionRequirementToOrderElementModel. + getCriterionRequirementDTOs(); + } + + public List getCriterionWithItsTypes(){ + return assignedCriterionRequirementToOrderElementModel.getCriterionWithItsTypes(); + } + + public void addCriterionRequirementDTO(){ + assignedCriterionRequirementToOrderElementModel.assignCriterionRequirementDTO(); + reload(); + } + + public void remove(CriterionRequirementDTO requirement){ + assignedCriterionRequirementToOrderElementModel. + deleteCriterionRequirementDTO(requirement); + reload(); + } + + public void invalidate(CriterionRequirementDTO requirement){ + assignedCriterionRequirementToOrderElementModel. + setValidCriterionRequirementDTO(requirement,false); + reload(); + } + + public void validate(CriterionRequirementDTO requirement){ + assignedCriterionRequirementToOrderElementModel. + setValidCriterionRequirementDTO(requirement,true); + reload(); + } + + public void selectCriterionAndType(Listitem item,Bandbox bandbox, + CriterionRequirementDTO criterionRequirementDTO){ + if(item != null){ + try{ + criterionRequirementDTO = updateRetrievedCriterionRequirement(criterionRequirementDTO); + CriterionWithItsType criterionAndType = + (CriterionWithItsType)item.getValue(); + bandbox.close(); + validateCriterionWithItsType(bandbox, + criterionAndType,criterionRequirementDTO); + bandbox.setValue(criterionAndType.getNameAndType()); + criterionRequirementDTO.setCriterionWithItsType(criterionAndType); + }catch(WrongValueException e){ + bandbox.setValue(""); + criterionRequirementDTO.setCriterionWithItsType(null); + throw e; + } + }else{ + bandbox.setValue(""); + } + } + + private CriterionRequirementDTO updateRetrievedCriterionRequirement( + CriterionRequirementDTO requirementDTO){ + return assignedCriterionRequirementToOrderElementModel. + updateRetrievedCriterionRequirement(requirementDTO); + + } + + private void validateCriterionWithItsType(Bandbox bandbox, + CriterionWithItsType criterionAndType, + CriterionRequirementDTO requirementDTO)throws WrongValueException{ + if(!assignedCriterionRequirementToOrderElementModel. + canAddCriterionRequirement(requirementDTO,criterionAndType)){ + throw new WrongValueException(bandbox, + _("The criterion " + criterionAndType.getNameAndType() + " is not valid," + + " exist the same criterion into the order element or into its children.")); + } + } + + private void reload() { + Util.reloadBindings(listingRequirements); + } + + private void showInvalidValues(ValidationException e) { + for (InvalidValue invalidValue : e.getInvalidValues()) { + Object value = invalidValue.getBean(); + if(value instanceof CriterionRequirementDTO){ + validateCriterionRequirementDTO(invalidValue, + (CriterionRequirementDTO)value); + } + } + } + + /** + * Validates {@link CriterionSatisfactionDTO} data constraints + * + * @param invalidValue + */ + private void validateCriterionRequirementDTO(InvalidValue invalidValue, + CriterionRequirementDTO requirementDTO) { + if(listingRequirements != null){ + // Find which listItem contains CriterionSatisfaction inside listBox + Row row = findRowOfCriterionSatisfactionDTO(listingRequirements.getRows(), + requirementDTO); + if (row != null) { + String propertyName = invalidValue.getPropertyName(); + + if (CriterionRequirementDTO.CRITERION_WITH_ITS_TYPE.equals(propertyName)) { + Bandbox bandType = getBandType(row); + bandType.setValue(null); + throw new WrongValueException(bandType, + _("The criterion and its type cannot be null")); + } + } + } + } + + /** + * Locates which {@link row} is bound to {@link WorkReportLine} in + * rows + * + * @param Rows + * @param CriterionSatisfactionDTO + * @return + */ + private Row findRowOfCriterionSatisfactionDTO(Rows rows, + CriterionRequirementDTO requirementDTO) { + List listRows = (List) rows.getChildren(); + for (Row row : listRows) { + if (requirementDTO.equals(row.getValue())) { + return row; + } + } + return null; + } + + /** + * Locates {@link Bandbox} criterion requirement in {@link row} + * + * @param row + * @return Bandbox + */ + private Bandbox getBandType(Row row) { + return (Bandbox)((Hbox) row.getChildren().get(0)) + .getChildren().get(0); + } +} \ No newline at end of file diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/AssignedCriterionRequirementToOrderElementModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/AssignedCriterionRequirementToOrderElementModel.java new file mode 100644 index 000000000..abc7c39ef --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/AssignedCriterionRequirementToOrderElementModel.java @@ -0,0 +1,307 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.orders; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.hibernate.validator.ClassValidator; +import org.hibernate.validator.InvalidValue; +import org.navalplanner.business.common.exceptions.ValidationException; +import org.navalplanner.business.orders.daos.IOrderElementDAO; +import org.navalplanner.business.orders.entities.HoursGroup; +import org.navalplanner.business.orders.entities.OrderElement; +import org.navalplanner.business.orders.entities.OrderLine; +import org.navalplanner.business.requirements.entities.CriterionRequirement; +import org.navalplanner.business.requirements.entities.DirectCriterionRequirement; +import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.CriterionType; +import org.navalplanner.business.resources.entities.CriterionWithItsType; +import org.navalplanner.web.orders.CriterionRequirementDTO.FlagState; +import org.navalplanner.web.orders.CriterionRequirementDTO.Type; +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; + +/** + * + * @author Susana Montes Pedreira + */ +@Service +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +public class AssignedCriterionRequirementToOrderElementModel implements + IAssignedCriterionRequirementToOrderElementModel{ + + @Autowired + IOrderElementDAO orderElementDAO; + + OrderElement orderElement; + + IOrderModel orderModel; + + private ClassValidator requirementDTOValidator = new ClassValidator( + CriterionRequirementDTO.class); + + private List criterionWithItsTypes = + new ArrayList(); + + private List criterionRequirementDTOs = + new ArrayList(); + + @Override + public OrderElement getOrderElement() { + return orderElement; + } + + @Override + public void setOrderElement(OrderElement orderElement) { + this.orderElement = orderElement; + } + + @Override + @Transactional(readOnly = true) + public void init(OrderElement orderElement) { + this.orderElement = orderElement; + if(orderElement != null){ + reattachOrderElement(); + initializeDTOs(); + initializeCriterionWithItsType(); + } + } + + private void reattachOrderElement() { + orderElementDAO.reattach(orderElement); + for(OrderElement child : orderElement.getAllChildren()){ + child.getName(); + reattachCriterionRequirement(child.getCriterionRequirements()); + if(child instanceof OrderLine){ + for(HoursGroup hoursGroup : child.getHoursGroups()){ + hoursGroup.getWorkingHours(); + reattachCriterionRequirement(hoursGroup.getCriterionRequirements()); + } + } + } + } + + private void reattachCriterionRequirement(Set list){ + for(CriterionRequirement requirement : list){ + requirement.getCriterion().getName(); + requirement.getCriterion().getType().getName(); + } + } + + private void initializeDTOs() { + criterionRequirementDTOs = new ArrayList(); + for(CriterionRequirement requirement : + orderElement.getCriterionRequirements()){ + CriterionRequirementDTO dto = + new CriterionRequirementDTO(requirement); + criterionRequirementDTOs.add(dto); + } + } + + private void initializeCriterionWithItsType() { + criterionWithItsTypes = new ArrayList(); + for(CriterionType type : getTypes()){ + if(type.isEnabled()){ + for (Criterion criterion : orderModel.getCriterionsFor(type)) { + if(criterion.isActive()){ + CriterionWithItsType criterionAndType = + new CriterionWithItsType(type,criterion); + criterionWithItsTypes.add(criterionAndType); + } + } + } + } + } + + private Set getTypes(){ + return getMapCriterions().keySet(); + } + + private Map> getMapCriterions(){ + return orderModel.getMapCriterions(); + } + + @Override + public List getCriterionWithItsTypes(){ + return criterionWithItsTypes; + } + + @Override + @Transactional(readOnly = true) + public void assignCriterionRequirementDTO() { + if((orderModel != null) && (orderElement != null)){ + CriterionRequirementDTO requirement = new CriterionRequirementDTO(Type.DIRECT); + criterionRequirementDTOs.add(requirement); + } + } + + @Override + public void deleteCriterionRequirementDTO(CriterionRequirementDTO requirement) { + if(requirement.isOldObject()){ + requirement.setFlagState(FlagState.REMOVED); + }else{ + criterionRequirementDTOs.remove(requirement); + } + } + + @Override + @Transactional(readOnly = true) + public void confirm() throws ValidationException{ + reattachOrderElement(); + validateDTOs(); + saveDTOs(); + } + + @Override + public void setOrderModel(IOrderModel orderModel) { + this.orderModel = orderModel; + } + + @Override + public List getCriterionRequirementDTOs() { + List requirementDTOs = + new ArrayList(); + if((orderModel != null)&&(getOrderElement() != null)){ + for(CriterionRequirementDTO requirementDTO : criterionRequirementDTOs){ + if(!requirementDTO.getFlagState().equals(FlagState.REMOVED)){ + requirementDTOs.add(requirementDTO); + } + } + } + return requirementDTOs; + } + + @Override + public CriterionRequirementDTO updateRetrievedCriterionRequirement( + CriterionRequirementDTO requirementDTO){ + if(requirementDTO.getFlagState().equals(FlagState.RETRIEVED)){ + CriterionRequirementDTO newRequirement = new CriterionRequirementDTO(Type.DIRECT); + criterionRequirementDTOs.add(newRequirement); + requirementDTO.setFlagState(FlagState.REMOVED); + return newRequirement; + } + return requirementDTO; + } + + @Override + public boolean canAddCriterionRequirement(CriterionRequirementDTO requirementDTO, + CriterionWithItsType criterionAndType){ + CriterionRequirementDTO removedDTO = findRemovedRequirementDTOWithSameCriterion( + criterionAndType.getCriterion()); + if(removedDTO != null){ + deleteCriterionRequirementDTO(requirementDTO); + removedDTO.setFlagState(FlagState.RETRIEVED); + return true; + }else{ + return canAddCriterionRequirement(criterionAndType); + } + } + + private CriterionRequirementDTO findRemovedRequirementDTOWithSameCriterion( + Criterion criterion){ + for(CriterionRequirementDTO removedDTO : this.criterionRequirementDTOs){ + if(removedDTO.getFlagState().equals(FlagState.REMOVED)){ + Criterion removedCriterion = removedDTO. + getCriterionWithItsType().getCriterion(); + if(criterion.getId().equals(removedCriterion.getId())) + return removedDTO; + } + } + return null; + } + + private boolean canAddCriterionRequirement(CriterionWithItsType criterionAndType){ + if(orderElement != null){ + return (!existSameCriterionRequirementInDTOs(criterionAndType) && + (canAddCriterionRequirementInOrderElement(criterionAndType))); + } + return true; + } + + private boolean existSameCriterionRequirementInDTOs( + CriterionWithItsType newCriterionAndType){ + for(CriterionRequirementDTO requirementDTO : criterionRequirementDTOs){ + CriterionWithItsType criterionAndType = requirementDTO.getCriterionWithItsType(); + if((criterionAndType != null) && + (criterionAndType.getCriterion().equals(newCriterionAndType.getCriterion()))){ + return true; + } + } + return false; + } + + private boolean canAddCriterionRequirementInOrderElement( + CriterionWithItsType newCriterionAndType){ + return orderElement.canAddCriterionRequirement(DirectCriterionRequirement. + create(newCriterionAndType.getCriterion())); + } + + @Override + public void setValidCriterionRequirementDTO( + CriterionRequirementDTO requirement,boolean valid){ + requirement.setValid(valid); + } + + private void validateDTOs() throws ValidationException{ + Set listDTOs = + new HashSet(criterionRequirementDTOs); + for(CriterionRequirementDTO requirementDTO : listDTOs){ + InvalidValue[] invalidValues; + invalidValues = requirementDTOValidator.getInvalidValues(requirementDTO); + if (invalidValues.length > 0){ + throw new ValidationException(invalidValues); + } + } + } + + private void saveDTOs(){ + updateRemoved(); + for(CriterionRequirementDTO requirementDTO : this.criterionRequirementDTOs){ + if(requirementDTO.isNewObject()){ + Criterion criterion = requirementDTO.getCriterionWithItsType().getCriterion(); + CriterionRequirement requirement = DirectCriterionRequirement.create(criterion); + orderElement.addDirectCriterionRequirement(requirement); + }else if(requirementDTO._getType().equals(Type.INDIRECT)){ + boolean valid = requirementDTO.isValid(); + CriterionRequirement requirement = requirementDTO.getCriterionRequirement(); + orderElement.setValidCriterionRequirement((IndirectCriterionRequirement)requirement,valid); + } + } + + } + + private void updateRemoved(){ + for(CriterionRequirementDTO requirementDTO : criterionRequirementDTOs){ + if(requirementDTO.getFlagState().equals(FlagState.REMOVED)){ + orderElement.removeDirectCriterionRequirement( + (DirectCriterionRequirement)requirementDTO.getCriterionRequirement()); + } + } + } +} \ No newline at end of file diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/CriterionRequirementDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/CriterionRequirementDTO.java new file mode 100644 index 000000000..9aa1ee43b --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/CriterionRequirementDTO.java @@ -0,0 +1,196 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package org.navalplanner.web.orders; +import static org.navalplanner.web.I18nHelper._; + +import org.hibernate.validator.NotNull; +import org.navalplanner.business.INewObject; +import org.navalplanner.business.requirements.entities.CriterionRequirement; +import org.navalplanner.business.requirements.entities.DirectCriterionRequirement; +import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.CriterionType; +import org.navalplanner.business.resources.entities.CriterionWithItsType; + +/** + * DTO represents the handled data in the form of assigning criterion requirement. + * + * @author Susana Montes Pedreira + */ +public class CriterionRequirementDTO implements INewObject { + + public static enum Type { + DIRECT, INDIRECT; + } + + public static enum FlagState { + NORMAL, REMOVED, RETRIEVED; + } + + private static final String DIRECT = _("Direct"); + + private static final String INDIRECT = _("Indirect"); + + public static final String CRITERION_WITH_ITS_TYPE = "criterionWithItsType"; + + private String type; + + private String criterionAndType; + + private Boolean newObject = false; + + private CriterionRequirement criterionRequirement; + + private Boolean valid = true; + + private FlagState flagState = FlagState.NORMAL; + + @NotNull + private CriterionWithItsType criterionWithItsType; + + public CriterionRequirementDTO(Type type){ + this.setNewObject(true); + this.setType(type); + this.setValid(true); + this.criterionAndType = ""; + } + + public CriterionRequirementDTO(CriterionRequirement criterionRequirement) { + this.criterionAndType = ""; + this.setCriterionRequirement(criterionRequirement); + this.setType(criterionRequirement); + this.setValid(criterionRequirement); + + Criterion criterion = criterionRequirement.getCriterion(); + CriterionType type = criterion.getType(); + setCriterionWithItsType(new CriterionWithItsType(type, criterion)); + } + + public CriterionWithItsType getCriterionWithItsType() { + return criterionWithItsType; + } + + public void setCriterionWithItsType(CriterionWithItsType criterionWithItsType) { + this.criterionWithItsType = criterionWithItsType; + } + + public void setCriterionAndType(String criterionAndType) { + this.criterionAndType = criterionAndType; + } + + public String getCriterionAndType() { + if(criterionWithItsType == null) return criterionAndType; + return criterionWithItsType.getNameAndType(); + } + + public void setNewObject(Boolean isNewObject) { + this.newObject = isNewObject; + } + + public boolean isOldObject(){ + return !isNewObject(); + } + + @Override + public boolean isNewObject() { + return newObject == null ? false : newObject; + } + + public void setCriterionRequirement(CriterionRequirement criterionRequirement) { + this.criterionRequirement = criterionRequirement; + } + + public CriterionRequirement getCriterionRequirement() { + return criterionRequirement; + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public Type _getType() { + if(type.equals(DIRECT)){ + return Type.DIRECT; + }else{ + return Type.INDIRECT; + } + } + + private void setType(CriterionRequirement criterionRequirement){ + if(criterionRequirement instanceof DirectCriterionRequirement){ + type = DIRECT; + }else if(criterionRequirement instanceof IndirectCriterionRequirement){ + type = INDIRECT; + } + } + + private void setType(Type type){ + if(type.equals(Type.DIRECT)){ + this.type = DIRECT; + }else{ + this.type = INDIRECT; + } + } + + public boolean isDirect(){ + return (type.equals(DIRECT)) ? true : false; + } + + public boolean isIndirectValid(){ + return (!isDirect()) && (isValid()); + } + + public boolean isIndirectInvalid(){ + return (!isDirect()) && (isInvalid()); + } + + public void setValid(Boolean valid) { + this.valid = valid; + } + + public void setValid(CriterionRequirement requirement) { + this.valid = true; + if(criterionRequirement instanceof IndirectCriterionRequirement){ + this.valid = ((IndirectCriterionRequirement)criterionRequirement).isIsValid(); + } + } + + public boolean isValid() { + return valid == null ? false : valid; + } + + public boolean isInvalid(){ + return !isValid(); + } + + public String getLabelValidate(){ + if(isValid()){ + return _("Invalidate"); + }else{ + return _("Validate"); + } + } + + public void setFlagState(FlagState flagState) { + this.flagState = flagState; + } + + public FlagState getFlagState() { + return flagState; + } + + public boolean isUpdatable(){ + return (isNewObject() || getFlagState().equals(FlagState.RETRIEVED)); + } + + public boolean isUnmodifiable(){ + return !isUpdatable(); + } +} \ No newline at end of file diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IAssignedCriterionRequirementToOrderElementModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IAssignedCriterionRequirementToOrderElementModel.java new file mode 100644 index 000000000..6fce593ed --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IAssignedCriterionRequirementToOrderElementModel.java @@ -0,0 +1,30 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package org.navalplanner.web.orders; + +import java.util.List; +import org.navalplanner.business.common.exceptions.ValidationException; +import org.navalplanner.business.orders.entities.OrderElement; +import org.navalplanner.business.resources.entities.CriterionWithItsType; + +/** + * + * @author Susana Montes Pedreira + */ +public interface IAssignedCriterionRequirementToOrderElementModel { + OrderElement getOrderElement(); + void setOrderElement(OrderElement orderElement); + void init(OrderElement orderElement); + void assignCriterionRequirementDTO(); + void deleteCriterionRequirementDTO(CriterionRequirementDTO requirement); + void confirm()throws ValidationException; + void setOrderModel(IOrderModel orderModel); + List getCriterionRequirementDTOs(); + List getCriterionWithItsTypes(); + boolean canAddCriterionRequirement(CriterionRequirementDTO requirement,CriterionWithItsType criterionAndType); + void setValidCriterionRequirementDTO(CriterionRequirementDTO requirement, boolean valid); + CriterionRequirementDTO updateRetrievedCriterionRequirement(CriterionRequirementDTO requirementDTO); +} \ No newline at end of file diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderCRUDController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderCRUDController.java index 96aeb950d..d5200ddae 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderCRUDController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderCRUDController.java @@ -114,6 +114,7 @@ public class OrderCRUDController extends GenericForwardComposer { setupAsignedHoursToOrderElementController(comp); setupManageOrderElementAdvancesController(comp); setupAssignedLabelsToOrderElementController(comp); + setupAssignedCriterionRequirementsToOrderElementController(comp); } private void setupOrderElementTreeController(Component comp, @@ -161,6 +162,16 @@ public class OrderCRUDController extends GenericForwardComposer { orderElementLabels.getVariable("assignedLabelsController", true); } + private AssignedCriterionRequirementToOrderElementController assignedCriterionRequirementController; + + private void setupAssignedCriterionRequirementsToOrderElementController( + Component comp) throws Exception { + Component orderElementCriterionRequirements = editWindow + .getFellowIfAny("orderElementCriterionRequirements"); + assignedCriterionRequirementController = (AssignedCriterionRequirementToOrderElementController) orderElementCriterionRequirements + .getVariable("assignedCriterionRequirementController", true); + } + public List getOrders() { return orderModel.getOrders(); } @@ -194,6 +205,9 @@ public class OrderCRUDController extends GenericForwardComposer { if (!manageOrderElementAdvancesController.save()) { selectTab("tabAdvances"); } + if (!assignedCriterionRequirementController.close()) { + selectTab("tabRequirements"); + } try { orderModel.save(); messagesForUser.showMessage(Level.INFO, _("Order saved")); @@ -299,6 +313,7 @@ public class OrderCRUDController extends GenericForwardComposer { assignedHoursController.openWindow(orderElementModel); manageOrderElementAdvancesController.openWindow(orderElementModel); assignedLabelsController.openWindow(orderElementModel); + assignedCriterionRequirementController.openWindow(orderElementModel); } private void clearEditWindow() { 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 acd73ee00..3a52de3af 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 @@ -52,7 +52,7 @@ public class OrderElementController extends GenericForwardComposer { private Component orderElementHours; - private AsignedHoursToOrderElementController assignedHoursController; + private AsignedHoursToOrderElementController asignedHoursToOrderElementController; private Component orderElementAdvances; @@ -62,6 +62,10 @@ public class OrderElementController extends GenericForwardComposer { private AssignedLabelsToOrderElementController assignedLabelsController; + private Component orderElementCriterionRequirements; + + private AssignedCriterionRequirementToOrderElementController assignedCriterionRequirementController; + @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); @@ -70,6 +74,7 @@ public class OrderElementController extends GenericForwardComposer { setupAsignedHoursToOrderElementController(comp); setupManageOrderElementAdvancesController(comp); setupAssignedLabelsToOrderElementController(comp); + setupAssignedCriterionRequirementToOrderElementController(comp); } private void setupDetailsOrderElementController(Component comp) throws Exception{ @@ -78,7 +83,7 @@ public class OrderElementController extends GenericForwardComposer { } private void setupAsignedHoursToOrderElementController(Component comp) throws Exception{ - assignedHoursController = (AsignedHoursToOrderElementController) + asignedHoursToOrderElementController = (AsignedHoursToOrderElementController) orderElementHours.getVariable("asignedHoursToOrderElementController", true); } @@ -93,6 +98,12 @@ public class OrderElementController extends GenericForwardComposer { orderElementLabels.getVariable("assignedLabelsController", true); } + private void setupAssignedCriterionRequirementToOrderElementController( + Component comp) throws Exception { + assignedCriterionRequirementController = (AssignedCriterionRequirementToOrderElementController) orderElementCriterionRequirements + .getVariable("assignedCriterionRequirementController", true); + } + public OrderElement getOrderElement() { return (orderElementModel == null) ? OrderLine.create() : orderElementModel.getOrderElement(); } @@ -108,9 +119,10 @@ public class OrderElementController extends GenericForwardComposer { setOrderElementModel(model); detailsController.openWindow(model); - assignedHoursController.openWindow(model); + asignedHoursToOrderElementController.openWindow(model); manageOrderElementAdvancesController.openWindow(model); assignedLabelsController.openWindow(model); + assignedCriterionRequirementController.openWindow(model); try { ((Window) self).doModal(); @@ -156,6 +168,10 @@ public class OrderElementController extends GenericForwardComposer { selectTab("tabAdvances"); return; } + if (!assignedCriterionRequirementController.close()) { + selectTab("tabRequirements"); + return; + } close(); } 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 dcb265666..3a29b1693 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 @@ -22,6 +22,7 @@ package org.navalplanner.web.orders; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -73,6 +74,7 @@ public class OrderElementModel implements IOrderElementModel { orderElementDAO.reattach(orderElement); for (HoursGroup hoursGroup : orderElement.getHoursGroups()) { + hoursGroup.getCriterionRequirements().size(); hoursGroup.getCriterions().size(); } 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 c9b58efbb..da0b276e2 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 @@ -33,6 +33,9 @@ import java.util.Set; import org.navalplanner.business.orders.entities.Order; import org.navalplanner.business.orders.entities.OrderElement; import org.navalplanner.business.orders.entities.OrderLine; +import org.navalplanner.web.common.IMessagesForUser; +import org.navalplanner.web.common.Level; +import org.navalplanner.web.common.MessagesForUser; import org.navalplanner.web.common.Util; import org.navalplanner.web.common.components.bandboxsearch.BandboxSearch; import org.zkoss.zk.ui.Component; @@ -65,6 +68,10 @@ import org.zkoss.zul.Treerow; */ public class OrderElementTreeController extends GenericForwardComposer { + private IMessagesForUser messagesForUser; + + private Component messagesContainer; + private Combobox cbFilterType; private BandboxSearch bdFilter; @@ -177,12 +184,16 @@ public class OrderElementTreeController extends GenericForwardComposer { public void addOrderElement() { snapshotOfOpenedNodes = TreeViewStateSnapshot.snapshotOpened(tree); - if (tree.getSelectedCount() == 1) { - getModel().addOrderElementAt(getSelectedNode()); - } else { - getModel().addOrderElement(); + try{ + if (tree.getSelectedCount() == 1) { + getModel().addOrderElementAt(getSelectedNode()); + } else { + getModel().addOrderElement(); + } + filterByPredicateIfAny(); + } catch (IllegalStateException e) { + messagesForUser.showMessage(Level.ERROR, e.getMessage()); } - filterByPredicateIfAny(); } private void filterByPredicateIfAny() { @@ -260,6 +271,7 @@ public class OrderElementTreeController extends GenericForwardComposer { @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); + messagesForUser = new MessagesForUser(messagesContainer); comp.setVariable("orderElementTreeController", this, true); } 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 index f0329010f..fc2ad7eef 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java @@ -67,14 +67,9 @@ public class OrderElementTreeModel { for (OrderElement orderElement : orderElements) { treeModel.add(orderElement, orderElement.getChildren()); addChildren(treeModel, orderElement.getChildren()); - reattach(orderElement); } } - private static void reattach(OrderElement orderElement) { - orderElement.getHoursGroups().size(); - } - private MutableTreeModel tree; public OrderElementTreeModel(Order order) { @@ -125,6 +120,8 @@ public class OrderElementTreeModel { IOrderLineGroup container = turnIntoContainerIfNeeded(parent); container.add(orderElement); addToTree(toNode(container), orderElement); + updateCriterionRequirementsInHierarchy(parent, orderElement, + (OrderElement) container); } private void addOrderElementAt(OrderElement destinationNode, @@ -132,6 +129,18 @@ public class OrderElementTreeModel { IOrderLineGroup container = turnIntoContainerIfNeeded(destinationNode); container.add(position, elementToAdd); addToTree(toNode(container), position, elementToAdd); + updateCriterionRequirementsInHierarchy(destinationNode, elementToAdd, + (OrderElement) container); + } + + private void updateCriterionRequirementsInHierarchy( + OrderElement destination, OrderElement origin, + OrderElement container) { + if (destination instanceof OrderLine) { + container.updateCriterionRequirements(); + } else { + origin.updateCriterionRequirements(); + } } private OrderElement toNode(IOrderLineGroup container) { 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 525576f09..73a1580df 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 @@ -52,6 +52,7 @@ import org.navalplanner.business.planner.daos.ITaskElementDAO; import org.navalplanner.business.planner.entities.Task; import org.navalplanner.business.planner.entities.TaskElement; import org.navalplanner.business.planner.entities.TaskGroup; +import org.navalplanner.business.requirements.entities.DirectCriterionRequirement; import org.navalplanner.business.resources.daos.ICriterionDAO; import org.navalplanner.business.resources.daos.ICriterionTypeDAO; import org.navalplanner.business.resources.entities.Criterion; @@ -131,6 +132,7 @@ public class OrderModel implements IOrderModel { } } + @Override public Map> getMapCriterions(){ final Map> result = new HashMap>(); @@ -147,6 +149,7 @@ public class OrderModel implements IOrderModel { this.order = getFromDB(order); this.orderElementTreeModel = new OrderElementTreeModel(this.order); forceLoadAdvanceAssignmentsAndMeasurements(this.order); + forceLoadCriterionRequirements(this.order); } private void initializeCacheLabels() { @@ -169,6 +172,29 @@ public class OrderModel implements IOrderModel { label.getType().getName(); } + private static void forceLoadCriterionRequirements(OrderElement orderElement) { + orderElement.getHoursGroups().size(); + for (HoursGroup hoursGroup : orderElement.getHoursGroups()) { + attachDirectCriterionRequirement(hoursGroup + .getDirectCriterionRequirement()); + } + attachDirectCriterionRequirement(orderElement + .getDirectCriterionRequirement()); + + for (OrderElement child : orderElement.getChildren()) { + forceLoadCriterionRequirements(child); + } + } + + private static void attachDirectCriterionRequirement( + Set requirements) { + for (DirectCriterionRequirement requirement : requirements) { + requirement.getChildren().size(); + requirement.getCriterion().getName(); + requirement.getCriterion().getType().getName(); + } + } + private void forceLoadAdvanceAssignmentsAndMeasurements( OrderElement orderElement) { for (DirectAdvanceAssignment directAdvanceAssignment : orderElement @@ -215,10 +241,10 @@ public class OrderModel implements IOrderModel { public void save() throws ValidationException { reattachCriterions(); this.orderDAO.save(order); - deleteOrderElementNotParent(); + deleteOrderElementWithoutParent(); } - private void deleteOrderElementNotParent() throws ValidationException { + private void deleteOrderElementWithoutParent() throws ValidationException { List listToBeRemoved = orderElementDAO .findWithoutParent(); for (OrderElement orderElement : listToBeRemoved) { @@ -311,6 +337,7 @@ public class OrderModel implements IOrderModel { return getFromDB(order).isSomeTaskElementScheduled(); } + @Override public List getCriterionsFor(CriterionType criterionType) { return mapCriterions.get(criterionType); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/CriterionsController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/CriterionsController.java index 1595fc58e..d215956f8 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/CriterionsController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/CriterionsController.java @@ -62,8 +62,6 @@ public class CriterionsController extends GenericForwardComposer { } messages = new MessagesForUser(messagesContainer); comp.setVariable("assignedCriterionsController", this, true); - //comboboxFilter = (Combobox) comp.getFellow("comboboxfilter"); - //listingCriterions = (Grid) comp.getFellow("listingCriterions"); } public IAssignedCriterionsModel getModel(){ diff --git a/navalplanner-webapp/src/main/webapp/orders/_editOrderElement.zul b/navalplanner-webapp/src/main/webapp/orders/_editOrderElement.zul index e95c75cf4..2cae5224d 100644 --- a/navalplanner-webapp/src/main/webapp/orders/_editOrderElement.zul +++ b/navalplanner-webapp/src/main/webapp/orders/_editOrderElement.zul @@ -18,23 +18,25 @@ along with this program. If not, see . --> + - + - - + + - + + - + @@ -46,6 +48,9 @@ + + + diff --git a/navalplanner-webapp/src/main/webapp/orders/_edition.zul b/navalplanner-webapp/src/main/webapp/orders/_edition.zul index 34447ecde..cc8829bfb 100644 --- a/navalplanner-webapp/src/main/webapp/orders/_edition.zul +++ b/navalplanner-webapp/src/main/webapp/orders/_edition.zul @@ -23,7 +23,7 @@ - + @@ -33,6 +33,7 @@ + @@ -94,6 +95,9 @@ + + + diff --git a/navalplanner-webapp/src/main/webapp/orders/_listOrderElementCriterionRequirements.zul b/navalplanner-webapp/src/main/webapp/orders/_listOrderElementCriterionRequirements.zul new file mode 100644 index 000000000..e782a3f36 --- /dev/null +++ b/navalplanner-webapp/src/main/webapp/orders/_listOrderElementCriterionRequirements.zul @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file