diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/materials/entities/Material.java b/navalplanner-business/src/main/java/org/navalplanner/business/materials/entities/Material.java index f5c9c5886..cb5245cf4 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/materials/entities/Material.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/materials/entities/Material.java @@ -34,6 +34,7 @@ import org.navalplanner.business.common.BaseEntity; */ public class Material extends BaseEntity { + @NotNull @NotEmpty private String code; diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/materials/entities/MaterialCategory.java b/navalplanner-business/src/main/java/org/navalplanner/business/materials/entities/MaterialCategory.java index 43de29182..40ecf17d9 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/materials/entities/MaterialCategory.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/materials/entities/MaterialCategory.java @@ -24,9 +24,10 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; -import org.apache.commons.collections.Unmodifiable; import org.apache.commons.lang.Validate; +import org.hibernate.validator.AssertTrue; import org.hibernate.validator.NotEmpty; +import org.hibernate.validator.Valid; import org.navalplanner.business.common.BaseEntity; /** @@ -42,8 +43,10 @@ public class MaterialCategory extends BaseEntity { private MaterialCategory parent = null; + @Valid private Set subcategories = new HashSet(); + @Valid private Set materials = new HashSet(); // Default constructor, needed by Hibernate @@ -97,7 +100,21 @@ public class MaterialCategory extends BaseEntity { materials.add(material); material.setCategory(this); } + public void removeMaterial(Material material) { materials.remove(material); } + + @AssertTrue(message="material code must be unique within a category") + public boolean checkConstraintNonRepeatedMaterialCodes() { + Set materialCodes = new HashSet(); + for (Material each: materials) { + final String code = each.getCode(); + if (materialCodes.contains(code)) { + return false; + } + materialCodes.add(code); + } + return true; + } } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/materials/MaterialsController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/materials/MaterialsController.java index ce25f4e48..1193f45e9 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/materials/MaterialsController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/materials/MaterialsController.java @@ -24,6 +24,7 @@ import static org.navalplanner.web.I18nHelper._; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; import org.apache.commons.logging.LogFactory; @@ -31,6 +32,7 @@ import org.hibernate.validator.InvalidValue; import org.navalplanner.business.common.exceptions.ValidationException; import org.navalplanner.business.materials.entities.Material; import org.navalplanner.business.materials.entities.MaterialCategory; +import org.navalplanner.web.common.ConstraintChecker; import org.navalplanner.web.common.IMessagesForUser; import org.navalplanner.web.common.Level; import org.navalplanner.web.common.MessagesForUser; @@ -211,6 +213,13 @@ public class MaterialsController extends } } + /** + * Finds which element in categoryTree has the same name as {@link MaterialCategory}, + * and returns name {@link Textbox} component + * + * @param materialCategory + * @return + */ private Component findInMaterialCategoryTree(MaterialCategory materialCategory) { final Treechildren children = categoriesTree.getTreechildren(); for(Treeitem each: (Collection) children.getItems()) { @@ -241,21 +250,64 @@ public class MaterialsController extends } public void saveAndExit() { - save(); - messagesForUser.showMessage(Level.INFO, _("Materials saved")); - } - - private void save() { - validate(); - try { - materialsModel.confirmSave(); - } catch (ValidationException e) { - messagesForUser.showInvalidValues(e); + if (save()) { + messagesForUser.showMessage(Level.INFO, _("Materials saved")); } } - private void validate() { - ConstraintChecker. + private boolean save() { + try { + materialsModel.confirmSave(); + return true; + } catch (ValidationException e) { + showInvalidValues(e); + } + return false; + } + + private void showInvalidValues(ValidationException validationException) { + final InvalidValue[] invalidValues = validationException.getInvalidValues(); + for (InvalidValue each: invalidValues) { + if (each.getBean() instanceof Material) { + final Material material = (Material) each.getBean(); + showConstraintErrorsFor(material.getCategory()); + } + } + } + + private void showConstraintErrorsFor(MaterialCategory materialCategory) { + Treeitem treeitem = findTreeItemByMaterialCategory(categoriesTree.getRoot(), materialCategory); + if (treeitem != null) { + treeitem.setSelected(true); + + // Load materials for category + final List materials = getMaterials(materialCategory); + gridMaterials.setModel(new SimpleListModel(materials)); + gridMaterials.renderAll(); + + // Show errors + ConstraintChecker.isValid(gridMaterials); + } + } + + private Treeitem findTreeItemByMaterialCategory(Component node, MaterialCategory materialCategory) { + if (node instanceof Treeitem) { + final Treeitem treeitem = (Treeitem) node; + final MaterialCategory _materialCategory = (MaterialCategory) treeitem.getValue(); + if (_materialCategory.equals(materialCategory)) { + return treeitem; + } + } + for (Iterator i = node.getChildren().iterator(); i.hasNext(); ) { + Object obj = i.next(); + if (obj instanceof Component) { + Treeitem treeitem = findTreeItemByMaterialCategory((Component) obj, materialCategory); + if (treeitem != null) { + return treeitem; + } + } + } + return null; } public void saveAndContinue() { @@ -279,10 +331,13 @@ public class MaterialsController extends private List getMaterials(Treeitem treeitem) { final List result = new ArrayList(); if (treeitem != null) { - final MaterialCategory materialCategory = (MaterialCategory) treeitem.getValue(); - result.addAll(materialsModel.getMaterials(materialCategory)); + result.addAll(getMaterials((MaterialCategory) treeitem.getValue())); } return result; } + private List getMaterials(MaterialCategory materialCategory) { + return materialsModel.getMaterials(materialCategory); + } + } diff --git a/navalplanner-webapp/src/main/webapp/materials/materials.zul b/navalplanner-webapp/src/main/webapp/materials/materials.zul index 81db15d58..f7a8f2c44 100644 --- a/navalplanner-webapp/src/main/webapp/materials/materials.zul +++ b/navalplanner-webapp/src/main/webapp/materials/materials.zul @@ -48,7 +48,7 @@