From 331837adf5520e9e9bbd0e634257c96d312273f5 Mon Sep 17 00:00:00 2001 From: Susana Montes Pedreira Date: Tue, 23 Mar 2010 17:05:21 +0100 Subject: [PATCH] ItEr52S10AdaptacionServiciosRESTItEr51S10: Creation and Adapting of MaterialCategoryServiceRest. --- .../materials/daos/MaterialCategoryDAO.java | 7 + .../business/materials/entities/Material.java | 84 ++-- .../materials/entities/MaterialCategory.java | 80 ++++ .../business/materials/entities/UnitType.java | 4 + .../ws/materials/api/IMaterialService.java | 36 ++ .../ws/materials/api/MaterialCategoryDTO.java | 84 ++++ .../api/MaterialCategoryListDTO.java | 49 +++ .../ws/materials/api/MaterialDTO.java | 83 ++++ .../ws/materials/api/package-info.java | 30 ++ .../ws/materials/impl/MaterialConverter.java | 272 +++++++++++++ .../materials/impl/MaterialServiceREST.java | 95 +++++ .../navalplanner-webapp-spring-config.xml | 1 + .../ws/materials/MaterialServiceTest.java | 384 ++++++++++++++++++ .../ws/orders/OrderElementServiceTest.java | 2 +- .../criterion/api/CriterionServiceTest.java | 26 ++ .../export-material-categories.sh | 21 + .../import-material-categories.sh | 33 ++ .../material-categories-sample.xml | 19 + 18 files changed, 1260 insertions(+), 50 deletions(-) create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/IMaterialService.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/MaterialCategoryDTO.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/MaterialCategoryListDTO.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/MaterialDTO.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/package-info.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/impl/MaterialConverter.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/impl/MaterialServiceREST.java create mode 100644 navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/materials/MaterialServiceTest.java create mode 100755 scripts/rest-clients/export-material-categories.sh create mode 100755 scripts/rest-clients/import-material-categories.sh create mode 100644 scripts/rest-clients/material-categories-sample.xml diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/materials/daos/MaterialCategoryDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/materials/daos/MaterialCategoryDAO.java index f991cae28..6a46a72cd 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/materials/daos/MaterialCategoryDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/materials/daos/MaterialCategoryDAO.java @@ -23,6 +23,7 @@ package org.navalplanner.business.materials.daos; import java.util.List; import org.hibernate.Criteria; +import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.navalplanner.business.common.daos.IntegrationEntityDAO; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; @@ -88,4 +89,10 @@ public class MaterialCategoryDAO extends IntegrationEntityDAO return findUniqueByName(name); } + @Override + public List findAll() { + return getSession().createCriteria(MaterialCategory.class).add( + Restrictions.isNull("parent")).addOrder(Order.asc("code")) + .list(); + } } 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 966c74a3a..f7c4eb526 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 @@ -22,32 +22,26 @@ package org.navalplanner.business.materials.entities; import java.math.BigDecimal; -import org.hibernate.validator.AssertTrue; -import org.hibernate.validator.NotEmpty; +import org.apache.commons.lang.StringUtils; import org.hibernate.validator.NotNull; import org.navalplanner.business.common.IntegrationEntity; import org.navalplanner.business.common.Registry; -import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.materials.daos.IMaterialDAO; /** * Material entity - * * @author Jacobo Aragunde Perez * */ public class Material extends IntegrationEntity implements Comparable { - @NotEmpty(message = "code not specified") - private String code; - private String description; private BigDecimal defaultUnitPrice = new BigDecimal(0); private UnitType unitType; - private boolean disabled; + private Boolean disabled; @NotNull private MaterialCategory category = null; @@ -58,11 +52,38 @@ public class Material extends IntegrationEntity implements Comparable { } public static Material create(String code) { - return (Material) create(new Material(code)); + return (Material) create(new Material(), code); + } + + public static Material createUnvalidated(String code, String description, + BigDecimal defaultPrice, Boolean disabled) { + Material material = create(new Material(), code); + material.description = description; + material.defaultUnitPrice = defaultPrice; + material.disabled = disabled; + return material; + } + + public void updateUnvalidated(String description, + BigDecimal defaultUnitPrice, + Boolean disabled) { + + if (!StringUtils.isBlank(description)) { + this.description = description; + } + + if (defaultUnitPrice != null) { + this.defaultUnitPrice = defaultUnitPrice; + } + + if (disabled != null) { + this.disabled = disabled; + } + } protected Material(String code) { - this.code = code; + this.setCode(code); } public MaterialCategory getCategory() { @@ -73,14 +94,6 @@ public class Material extends IntegrationEntity implements Comparable { this.category = category; } - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - public String getDescription() { return description; } @@ -89,11 +102,11 @@ public class Material extends IntegrationEntity implements Comparable { this.description = description; } - public boolean getDisabled() { - return disabled; + public Boolean getDisabled() { + return disabled == null ? false : disabled; } - public void setDisabled(boolean disabled) { + public void setDisabled(Boolean disabled) { this.disabled = disabled; } @@ -116,34 +129,7 @@ public class Material extends IntegrationEntity implements Comparable { @Override public int compareTo(Object arg0) { final Material material = (Material) arg0; - return code.compareTo(material.getCode()); - } - - @AssertTrue(message="materialcode has to be unique. It is already used") - public boolean checkConstraintUniqueCode() { - boolean result; - if (isNewObject()) { - result = !existsMaterialWithTheCode(); - } else { - result = isIfExistsTheExistentMaterialThisOne(); - } - return result; - } - - private boolean existsMaterialWithTheCode() { - IMaterialDAO materialDAO = Registry.getMaterialDAO(); - return materialDAO.existsMaterialWithCodeInAnotherTransaction(code); - } - - private boolean isIfExistsTheExistentMaterialThisOne() { - IMaterialDAO materialDAO = Registry.getMaterialDAO(); - try { - Material material = - materialDAO.findUniqueByCodeInAnotherTransaction(code); - return material.getId().equals(getId()); - } catch (InstanceNotFoundException e) { - return true; - } + return getCode().compareTo(material.getCode()); } @Override 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 d014f727d..ddbb83f25 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 @@ -73,6 +73,20 @@ public class MaterialCategory extends IntegrationEntity { return (MaterialCategory) create(new MaterialCategory(name)); } + public static MaterialCategory createUnvalidated(String code, String name) { + MaterialCategory materialCategory = create(new MaterialCategory(), code); + materialCategory.name = name; + return materialCategory; + } + + public void updateUnvalidated(String name) { + + if (!StringUtils.isBlank(name)) { + this.name = name; + } + + } + protected MaterialCategory(String name) { this.name = name; } @@ -163,9 +177,75 @@ public class MaterialCategory extends IntegrationEntity { } + public MaterialCategory getSubcategoryByCode(String code) + throws InstanceNotFoundException { + + if (StringUtils.isBlank(code)) { + throw new InstanceNotFoundException(code, MaterialCategory.class + .getName()); + } + + for (MaterialCategory s : this.subcategories) { + if (s.getCode().equalsIgnoreCase(StringUtils.trim(code))) { + return s; + } + } + + throw new InstanceNotFoundException(code, MaterialCategory.class + .getName()); + + } + @Override protected IMaterialCategoryDAO getIntegrationEntityDAO() { return Registry.getMaterialCategoryDAO(); } + @SuppressWarnings("unused") + @AssertTrue(message = "The subcategories names must be unique.") + public boolean checkConstraintUniqueSubcategoryName() { + Set subcategoriesNames = new HashSet(); + for (MaterialCategory mc : this.getAllSubcategories()) { + if (!StringUtils.isBlank(mc.getName())) { + String name = StringUtils.deleteWhitespace(mc.getName() + .toLowerCase()); + if (subcategoriesNames.contains(name)) { + return false; + } else { + subcategoriesNames.add(name); + } + } + } + return true; + } + + @AssertTrue + public boolean checkConstraintNonRepeatedMaterialCategoryCodes() { + Set allSubcategories = getAllSubcategories(); + allSubcategories.add(this); + return getFirstRepeatedCode(allSubcategories) == null; + } + + private Set getAllSubcategories() { + Set result = new HashSet( + subcategories); + for (MaterialCategory subcategory : subcategories) { + result.addAll(subcategory.getAllSubcategories()); + } + return result; + } + + @AssertTrue + public boolean checkConstraintNonRepeatedMaterialCodes() { + Set allMaterials = getAllMaterials(); + return getFirstRepeatedCode(allMaterials) == null; + } + + private Set getAllMaterials() { + Set result = new HashSet(materials); + for (MaterialCategory subcategory : subcategories) { + result.addAll(subcategory.getAllMaterials()); + } + return result; + } } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/materials/entities/UnitType.java b/navalplanner-business/src/main/java/org/navalplanner/business/materials/entities/UnitType.java index b9c1853d2..5ebcbe67e 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/materials/entities/UnitType.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/materials/entities/UnitType.java @@ -33,6 +33,10 @@ import org.navalplanner.business.materials.daos.IUnitTypeDAO; */ public class UnitType extends IntegrationEntity{ + public static UnitType create(String code, String measure) { + return (UnitType) create(new UnitType(measure), code); + } + public static UnitType create(String measure) { return (UnitType) create(new UnitType(measure)); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/IMaterialService.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/IMaterialService.java new file mode 100644 index 000000000..6b1b8b82b --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/IMaterialService.java @@ -0,0 +1,36 @@ +/* + * This file is part of NavalPlan + * + * 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.ws.materials.api; + +import org.navalplanner.ws.common.api.InstanceConstraintViolationsListDTO; + +/** + * Service for managing material-related entities. + * @author Susana Montes Pedreira + */ +public interface IMaterialService { + + public MaterialCategoryListDTO getMaterials(); + + public InstanceConstraintViolationsListDTO addMaterials( + MaterialCategoryListDTO materialCategoryListDTO); + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/MaterialCategoryDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/MaterialCategoryDTO.java new file mode 100644 index 000000000..955ac6a69 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/MaterialCategoryDTO.java @@ -0,0 +1,84 @@ +/* + * This file is part of NavalPlan + * + * 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.ws.materials.api; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; + +import org.navalplanner.ws.common.api.IntegrationEntityDTO; + +/** + * DTO for MaterialCategory entity. + * @author Susana Montes Pedreira + */ +public class MaterialCategoryDTO extends IntegrationEntityDTO { + + public final static String ENTITY_TYPE = "material-category"; + + @XmlAttribute + public String name; + + @XmlAttribute + public String parent; + + @XmlElement + public MaterialCategoryListDTO subcategories; + + @XmlElementWrapper(name = "material-list") + @XmlElement(name = "material") + public List materials = new ArrayList(); + + public MaterialCategoryDTO() { + } + + public MaterialCategoryDTO(String code, String name, String parent, + MaterialCategoryListDTO subcategories, List materials) { + + super(code); + this.name = name; + this.parent = parent; + this.subcategories = subcategories; + this.materials = materials; + + } + + /** + * This constructor automatically generates a unique code. It is intended to + * facilitate the implementation of test cases that add new instances (such + * instances will have a unique code). + */ + public MaterialCategoryDTO(String name, String parent, + MaterialCategoryListDTO subcategories, List materials) { + + this(generateCode(), name, parent, subcategories, materials); + + } + + @Override + public String getEntityType() { + return ENTITY_TYPE; + } + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/MaterialCategoryListDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/MaterialCategoryListDTO.java new file mode 100644 index 000000000..fd97ab77e --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/MaterialCategoryListDTO.java @@ -0,0 +1,49 @@ +/* + * This file is part of NavalPlan + * + * 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.ws.materials.api; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * DTO for a list of MaterialCategory entities. + * @author Susana Montes Pedreira + */ +@XmlRootElement(name = "material-category-list") +public class MaterialCategoryListDTO { + + @XmlElement(name = "material-category") + public List materialCategoryDTOs = new ArrayList(); + + public MaterialCategoryListDTO() { + } + + public MaterialCategoryListDTO( + List materialCategoryDTOs) { + if (materialCategoryDTOs != null) { + this.materialCategoryDTOs = materialCategoryDTOs; + } + } + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/MaterialDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/MaterialDTO.java new file mode 100644 index 000000000..b9b618a32 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/MaterialDTO.java @@ -0,0 +1,83 @@ +/* + * This file is part of NavalPlan + * + * 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.ws.materials.api; + +import java.math.BigDecimal; + +import javax.xml.bind.annotation.XmlAttribute; + +import org.navalplanner.ws.common.api.IntegrationEntityDTO; + +/** + * DTO for Material entity. + * @author Susana Montes Pedreira + */ +public class MaterialDTO extends IntegrationEntityDTO { + + public final static String ENTITY_TYPE = "material"; + + @XmlAttribute + public String name; + + @XmlAttribute + public String description; + + @XmlAttribute + public BigDecimal defaultPrice; + + @XmlAttribute + public String unitType; + + @XmlAttribute + public Boolean disabled; + + public MaterialDTO() { + } + + public MaterialDTO(String code, String description, + BigDecimal defaultPrice, String unitType, Boolean disabled) { + + super(code); + this.description = description; + this.defaultPrice = defaultPrice; + this.unitType = unitType; + this.disabled = disabled; + + } + + /** + * This constructor automatically generates a unique code. It is intended to + * facilitate the implementation of test cases that add new instances (such + * instances will have a unique code). + */ + public MaterialDTO(String description, BigDecimal defaultPrice, + String unitType, Boolean disabled) { + + this(generateCode(), description, defaultPrice, unitType, disabled); + + } + + @Override + public String getEntityType() { + return ENTITY_TYPE; + } + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/package-info.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/package-info.java new file mode 100644 index 000000000..54a090bc4 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/api/package-info.java @@ -0,0 +1,30 @@ +/* + * This file is part of NavalPlan + * + * 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 . + */ + +/** + * Specification of namespace for REST-based services. + * @author Susana Montes Pedreira + */ +@javax.xml.bind.annotation.XmlSchema( + elementFormDefault=javax.xml.bind.annotation.XmlNsForm.QUALIFIED, + namespace=WSCommonGlobalNames.REST_NAMESPACE +) +package org.navalplanner.ws.materials.api; +import org.navalplanner.ws.common.api.WSCommonGlobalNames; diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/impl/MaterialConverter.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/impl/MaterialConverter.java new file mode 100644 index 000000000..ae171ee34 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/impl/MaterialConverter.java @@ -0,0 +1,272 @@ +/* + * This file is part of NavalPlan + * + * 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.ws.materials.impl; + +import static org.navalplanner.web.I18nHelper._; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.navalplanner.business.common.Registry; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +import org.navalplanner.business.common.exceptions.ValidationException; +import org.navalplanner.business.materials.entities.Material; +import org.navalplanner.business.materials.entities.MaterialCategory; +import org.navalplanner.business.materials.entities.UnitType; +import org.navalplanner.ws.materials.api.MaterialCategoryDTO; +import org.navalplanner.ws.materials.api.MaterialCategoryListDTO; +import org.navalplanner.ws.materials.api.MaterialDTO; + +/** + * Converter from/to material-related entities to/from DTOs. + * @author Susana Montes Pedreira + */ +public final class MaterialConverter { + + private MaterialConverter() { + } + + public final static MaterialCategoryDTO toDTO( + MaterialCategory materialCategory) { + + // converter the materials + List materialDTOs = new ArrayList(); + + for (Material m : materialCategory.getMaterials()) { + materialDTOs.add(toDTO(m)); + } + + if (materialDTOs.isEmpty()) { + materialDTOs = null; + } + + // converter the subcategories + MaterialCategoryListDTO subcategories = createSubcategoriesList(materialCategory + .getSubcategories()); + + // get the parent code + String parentCode = null; + if (materialCategory.getParent() != null) { + parentCode = materialCategory.getParent().getCode(); + } + + return new MaterialCategoryDTO(materialCategory.getCode(), + materialCategory.getName(), parentCode, subcategories, + materialDTOs); + + } + + private static MaterialCategoryListDTO createSubcategoriesList( + Set subcategories) { + + List DTOs = new ArrayList(); + + for (MaterialCategory m : subcategories) { + DTOs.add(toDTO(m)); + } + + if (DTOs.isEmpty()) { + return null; + } + + return new MaterialCategoryListDTO(DTOs); + } + + public final static MaterialDTO toDTO(Material material) { + + String unitTypeCode = null; + if (material.getUnitType() != null) { + unitTypeCode = material.getUnitType().getCode(); + } + + return new MaterialDTO(material.getCode(), material.getDescription(), + material.getDefaultUnitPrice(), unitTypeCode, material + .getDisabled()); + + } + + public final static MaterialCategory toEntity( + MaterialCategoryDTO materialCategoryDTO) { + MaterialCategory materialCategory = toEntityCategory(materialCategoryDTO); + + // find the parent + if (materialCategoryDTO.parent != null) { + try { + MaterialCategory parentCategory = Registry + .getMaterialCategoryDAO().findByCode( + materialCategoryDTO.parent); + materialCategory.setParent(parentCategory); + } catch (InstanceNotFoundException e) { + throw new ValidationException( + _("There is no material category with this code")); + } + } + + return materialCategory; + } + + public final static MaterialCategory toEntityCategory( + MaterialCategoryDTO materialCategoryDTO) { + + MaterialCategory materialCategory = MaterialCategory.createUnvalidated( + StringUtils.trim(materialCategoryDTO.code), StringUtils + .trim(materialCategoryDTO.name)); + + // Create and add the materials + if (materialCategoryDTO.materials != null) { + for (MaterialDTO materialDTO : materialCategoryDTO.materials) { + materialCategory.addMaterial(toEntity(materialDTO)); + } + } + + // Create and add the subcategories + if (materialCategoryDTO.subcategories != null) { + for (MaterialCategoryDTO subCategoryDTO : materialCategoryDTO.subcategories.materialCategoryDTOs) { + materialCategory.addSubcategory(toEntitySubCategories( + subCategoryDTO, materialCategory)); + } + } + + return materialCategory; + + } + + public final static MaterialCategory toEntitySubCategories( + MaterialCategoryDTO materialCategoryDTO, MaterialCategory parent) { + + MaterialCategory materialCategory = toEntityCategory(materialCategoryDTO); + + // find the parent + if (materialCategoryDTO.parent != null) { + if (!materialCategoryDTO.parent.equalsIgnoreCase(parent.getCode())) { + throw new ValidationException(_("inconsistent parent code.")); + } + } + + return materialCategory; + + } + + private static Material toEntity(MaterialDTO materialDTO) { + + Material material = Material.createUnvalidated(StringUtils + .trim(materialDTO.code), StringUtils + .trim(materialDTO.description), materialDTO.defaultPrice, + materialDTO.disabled); + + if (materialDTO.unitType != null) { + try { + UnitType unitType = Registry.getUnitTypeDAO().findByCode( + materialDTO.unitType); + material.setUnitType(unitType); + } catch (InstanceNotFoundException e) { + material.setUnitType(null); + } + } + + return material; + + } + + public final static void updateMaterialCategory( + MaterialCategory materialCategory, + MaterialCategoryDTO materialCategoryDTO) throws ValidationException { + + /* check the parent code */ + if (((materialCategoryDTO.parent != null) + && (materialCategory.getParent() != null) + && (!materialCategory.getParent().getCode().equalsIgnoreCase( + materialCategoryDTO.parent))) + || ((!(materialCategoryDTO.parent == null) && (materialCategory + .getParent() == null)))) { + throw new ValidationException(_("inconsistent parent code.")); + } + + /* + * 1: Update basic properties in existing material category and add new + * materials. + */ + if (materialCategoryDTO.materials != null) { + for (MaterialDTO materialDTO : materialCategoryDTO.materials) { + + /* Step 1.1 requires each material DTO to have a code. */ + if (StringUtils.isBlank(materialDTO.code)) { + throw new ValidationException( + _("missing code in a material")); + } + + try { + Material material = materialCategory + .getMaterialByCode(materialDTO.code); + updateMaterial(material, materialDTO); + } catch (InstanceNotFoundException e) { + materialCategory.addMaterial(toEntity(materialDTO)); + } + } + } + + /* + * 2: Update basic properties in existing subcategories and add new + * subcategories. + */ + if (materialCategoryDTO.subcategories != null) { + for (MaterialCategoryDTO subcategoryDTO : materialCategoryDTO.subcategories.materialCategoryDTOs) { + + /* Step 2.1 requires each subcategory DTO to have a code. */ + if (StringUtils.isBlank(subcategoryDTO.code)) { + throw new ValidationException( + _("missing code in a subcategory")); + } + + try { + MaterialCategory subcategory = materialCategory + .getSubcategoryByCode(subcategoryDTO.code); + updateMaterialCategory(subcategory, subcategoryDTO); + } catch (InstanceNotFoundException e) { + materialCategory + .addSubcategory(toEntity(subcategoryDTO)); + } + } + } + + /* 3: Update material category basic properties. */ + materialCategory.updateUnvalidated(StringUtils + .trim(materialCategoryDTO.name)); + + } + + public final static void updateMaterial(Material material, + MaterialDTO materialDTO) throws ValidationException { + if (materialDTO.unitType != null) { + try { + UnitType type = Registry.getUnitTypeDAO().findByCode( + materialDTO.unitType); + material.setUnitType(type); + } catch (InstanceNotFoundException e) { + throw new ValidationException(_("unit type code not found")); + } + } + material.updateUnvalidated(StringUtils.trim(materialDTO.description), + materialDTO.defaultPrice, materialDTO.disabled); + } +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/impl/MaterialServiceREST.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/impl/MaterialServiceREST.java new file mode 100644 index 000000000..72ee56bdd --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/materials/impl/MaterialServiceREST.java @@ -0,0 +1,95 @@ +/* + * This file is part of NavalPlan + * + * 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.ws.materials.impl; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.navalplanner.business.common.daos.IIntegrationEntityDAO; +import org.navalplanner.business.common.exceptions.ValidationException; +import org.navalplanner.business.materials.daos.IMaterialCategoryDAO; +import org.navalplanner.business.materials.entities.MaterialCategory; +import org.navalplanner.ws.common.api.InstanceConstraintViolationsListDTO; +import org.navalplanner.ws.common.impl.GenericRESTService; +import org.navalplanner.ws.materials.api.IMaterialService; +import org.navalplanner.ws.materials.api.MaterialCategoryDTO; +import org.navalplanner.ws.materials.api.MaterialCategoryListDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * REST-based implementation of IMaterialService. + * @author Susana Montes Pedreira + */ +@Path("/materialcategories/") +@Produces("application/xml") +@Service("materialServiceREST") +public class MaterialServiceREST extends + GenericRESTService implements + IMaterialService { + + @Autowired + private IMaterialCategoryDAO materialCategoryDAO; + + @Override + @GET + @Transactional(readOnly = true) + public MaterialCategoryListDTO getMaterials() { + return new MaterialCategoryListDTO(findAll()); + } + + @Override + @POST + @Consumes("application/xml") + public InstanceConstraintViolationsListDTO addMaterials( + MaterialCategoryListDTO materialCategoryListDTO) { + return save(materialCategoryListDTO.materialCategoryDTOs); + } + + @Override + protected MaterialCategory toEntity(MaterialCategoryDTO entityDTO) { + return MaterialConverter.toEntity(entityDTO); + } + + @Override + protected MaterialCategoryDTO toDTO(MaterialCategory entity) { + return MaterialConverter.toDTO(entity); + } + + @Override + protected IIntegrationEntityDAO getIntegrationEntityDAO() { + return materialCategoryDAO; + } + + @Override + protected void updateEntity(MaterialCategory entity, + MaterialCategoryDTO entityDTO) + throws ValidationException { + + MaterialConverter.updateMaterialCategory(entity, entityDTO); + + } + +} diff --git a/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml b/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml index 5ade06edc..d182fef5d 100644 --- a/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml +++ b/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml @@ -73,6 +73,7 @@ + diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/materials/MaterialServiceTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/materials/MaterialServiceTest.java new file mode 100644 index 000000000..19abdc1c8 --- /dev/null +++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/materials/MaterialServiceTest.java @@ -0,0 +1,384 @@ +/* + * This file is part of NavalPlan + * + * 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.test.ws.materials; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE; +import static org.navalplanner.web.WebappGlobalNames.WEBAPP_SPRING_CONFIG_FILE; +import static org.navalplanner.web.test.WebappGlobalNames.WEBAPP_SPRING_CONFIG_TEST_FILE; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Resource; + +import org.hibernate.SessionFactory; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.navalplanner.business.IDataBootstrap; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +import org.navalplanner.business.materials.daos.IMaterialCategoryDAO; +import org.navalplanner.business.materials.daos.IMaterialDAO; +import org.navalplanner.business.materials.daos.IUnitTypeDAO; +import org.navalplanner.business.materials.entities.Material; +import org.navalplanner.business.materials.entities.MaterialCategory; +import org.navalplanner.business.materials.entities.UnitType; +import org.navalplanner.ws.common.api.InstanceConstraintViolationsDTO; +import org.navalplanner.ws.materials.api.IMaterialService; +import org.navalplanner.ws.materials.api.MaterialCategoryDTO; +import org.navalplanner.ws.materials.api.MaterialCategoryListDTO; +import org.navalplanner.ws.materials.api.MaterialDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +/** + * Tests for IMaterialService. + * @author Susana Montes Pedreira + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE, + WEBAPP_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_TEST_FILE }) +@Transactional +public class MaterialServiceTest { + + @Autowired + private SessionFactory sessionFactory; + + @Autowired + private IMaterialService materialService; + + @Autowired + private IMaterialCategoryDAO materialCategoryDAO; + + @Autowired + private IMaterialDAO materialDAO; + + @Autowired + private IUnitTypeDAO unitTypeDAO; + + @Resource + private IDataBootstrap materialCategoryBootstrap; + + @Resource + private IDataBootstrap unitTypeBootstrap; + + private String unitTypeCodeA = "unitTypeA"; + private String unitTypeCodeB = "unitTypeB"; + + @Test + @Rollback(false) + public void CreateUnitType() { + UnitType entityA = UnitType.create(unitTypeCodeA, "uninewUnitTypeA"); + UnitType entityB = UnitType.create(unitTypeCodeB, "uninewUnitTypeB"); + unitTypeDAO.save(entityA); + unitTypeDAO.save(entityB); + unitTypeDAO.flush(); + sessionFactory.getCurrentSession().evict(entityA); + sessionFactory.getCurrentSession().evict(entityB); + } + + @Test + @Rollback(false) + public void loadRequiredaData() { + materialCategoryBootstrap.loadRequiredData(); + unitTypeBootstrap.loadRequiredData(); + } + + @Test + public void testAddAndGetMaterialCategories() { + /* Build materialCategory (0 constraint violations). */ + // Missing material name and the unit type. + MaterialDTO m1 = new MaterialDTO(null, new BigDecimal(13), + unitTypeCodeA, true); + // Missing default unit price + MaterialDTO m2 = new MaterialDTO("material 2", null, unitTypeCodeA, + true); + // Missing unit type + MaterialDTO m3 = new MaterialDTO("material 3", new BigDecimal(13), + null, true); + // Missing unit type, same name + MaterialDTO m4 = new MaterialDTO("material 3", new BigDecimal(13), + unitTypeCodeA, null); + + List materialDTOs = new ArrayList(); + materialDTOs.add(m1); + materialDTOs.add(m2); + materialDTOs.add(m3); + materialDTOs.add(m4); + + MaterialCategoryDTO materialCategoryDTO = new MaterialCategoryDTO( + "categoryA", null, null, materialDTOs); + + MaterialCategoryListDTO materialCategoryListDTO = createMaterialCategoryListDTO(materialCategoryDTO); + + List instanceConstraintViolationsList = materialService + .addMaterials(materialCategoryListDTO).instanceConstraintViolationsList; + + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 0); + } + + @Test + public void testAddMaterialRepeatedCodes() { + /* Build material with same code (1 constraint violations). */ + MaterialDTO m1 = new MaterialDTO("CodeA", "material1", new BigDecimal( + 13), unitTypeCodeA, true); + MaterialDTO m2 = new MaterialDTO("CodeA", "material2", new BigDecimal( + 13), unitTypeCodeA, true); + + List materialDTOs = new ArrayList(); + materialDTOs.add(m1); + materialDTOs.add(m2); + + MaterialCategoryDTO materialCategoryDTO = new MaterialCategoryDTO( + "category1", null, null, materialDTOs); + + MaterialCategoryListDTO materialCategoryListDTO = createMaterialCategoryListDTO(materialCategoryDTO); + + List instanceConstraintViolationsList = materialService + .addMaterials(materialCategoryListDTO).instanceConstraintViolationsList; + + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 1); + } + + @Test + public void testAddValidMaterialCategory() { + /* Build material (0 constraint violations). */ + MaterialDTO m1 = new MaterialDTO("CodeM1", "material1", new BigDecimal( + 13), unitTypeCodeA, true); + MaterialDTO m2 = new MaterialDTO("CodeM2", "material2", new BigDecimal( + 13), unitTypeCodeA, true); + + List materialDTOs1 = new ArrayList(); + List materialDTOs2 = new ArrayList(); + materialDTOs1.add(m1); + materialDTOs2.add(m2); + + /* Build material (0 constraint violations). */ + MaterialCategoryDTO mc1 = new MaterialCategoryDTO("CodeMC1", + "subCategory1", "mainMaterialCode", null, materialDTOs1); + MaterialCategoryDTO mc2 = new MaterialCategoryDTO("CodeMC2", + "subCategory2", null, null, materialDTOs2); + MaterialCategoryListDTO subCategoryListDTO = createMaterialCategoryListDTO( + mc1, mc2); + + /* Build main material category */ + MaterialCategoryDTO materialCategoryDTO = new MaterialCategoryDTO( + "mainMaterialCode", "mainCategory1", null, subCategoryListDTO, + null); + + MaterialCategoryListDTO materialCategoryListDTO = createMaterialCategoryListDTO(materialCategoryDTO); + + List instanceConstraintViolationsList = materialService + .addMaterials(materialCategoryListDTO).instanceConstraintViolationsList; + + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 0); + } + + @Test + public void testAddMaterialCategoryWithSameName() { + /* Build material (0 constraint violations). */ + MaterialCategoryDTO mc1 = new MaterialCategoryDTO("subMC1", + "subCategory", "subMC2", null, null); + MaterialCategoryListDTO subCategoryListDTOC = createMaterialCategoryListDTO(mc1); + + MaterialCategoryDTO mc2 = new MaterialCategoryDTO("subMC2", + "subCategory", null, subCategoryListDTOC, null); + MaterialCategoryListDTO subCategoryListDTOB = createMaterialCategoryListDTO(mc2); + + /* Build main material category */ + MaterialCategoryDTO materialCategoryDTO = new MaterialCategoryDTO( + "mainMaterialCode", "mainCategory1", null, subCategoryListDTOB, + null); + + MaterialCategoryListDTO materialCategoryListDTOA = createMaterialCategoryListDTO(materialCategoryDTO); + + List instanceConstraintViolationsList = materialService + .addMaterials(materialCategoryListDTOA).instanceConstraintViolationsList; + + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 1); + } + + @Test + public void testAddMaterialCategoryWithInconsistentParent() { + /* Build material (0 constraint violations). */ + MaterialCategoryDTO mc1 = new MaterialCategoryDTO("subMCX1", + "subCategoryC", "mainMaterialCode", null, null); + MaterialCategoryListDTO subCategoryListDTOC = createMaterialCategoryListDTO(mc1); + + MaterialCategoryDTO mc2 = new MaterialCategoryDTO("subMCX2", + "subCategoryB", null, subCategoryListDTOC, null); + MaterialCategoryListDTO subCategoryListDTOB = createMaterialCategoryListDTO(mc2); + + /* Build main material category */ + MaterialCategoryDTO materialCategoryDTO = new MaterialCategoryDTO( + "mainMaterialCodeX", "mainCategory1", null, + subCategoryListDTOB, + null); + + MaterialCategoryListDTO materialCategoryListDTOA = createMaterialCategoryListDTO(materialCategoryDTO); + + List instanceConstraintViolationsList = materialService + .addMaterials(materialCategoryListDTOA).instanceConstraintViolationsList; + + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 1); + } + + @Test + public void testAddAndUpdateMaterialCategory() { + /* Build material (0 constraint violations). */ + MaterialDTO m1 = new MaterialDTO("M-1", "tornillos", + new BigDecimal(13), unitTypeCodeA, true); + + List materialDTOs1 = new ArrayList(); + materialDTOs1.add(m1); + + MaterialCategoryDTO mc1 = new MaterialCategoryDTO("MC-C", "MC-C", + "MC-B", + null, null); + MaterialCategoryListDTO subCategoryListDTOC = createMaterialCategoryListDTO(mc1); + + MaterialCategoryDTO mc2 = new MaterialCategoryDTO("MC-B", "MC-B", null, + subCategoryListDTOC, materialDTOs1); + MaterialCategoryListDTO subCategoryListDTOB = createMaterialCategoryListDTO(mc2); + + /* Build main material category */ + MaterialCategoryDTO materialCategoryDTO = new MaterialCategoryDTO( + "C-A", "C-A", null, subCategoryListDTOB, null); + + MaterialCategoryListDTO materialCategoryListDTOA = createMaterialCategoryListDTO(materialCategoryDTO); + + List instanceConstraintViolationsList = materialService + .addMaterials(materialCategoryListDTOA).instanceConstraintViolationsList; + + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 0); + + try { + MaterialCategory mc = materialCategoryDAO.findByCode("MC-B"); + assertTrue(mc.getMaterials().size() == 1); + assertTrue(mc.getSubcategories().size() == 1); + assertTrue(mc.getName().equalsIgnoreCase("MC-B")); + materialCategoryDAO.flush(); + sessionFactory.getCurrentSession().evict(mc); + } catch (InstanceNotFoundException e) { + fail(); + } + + // Update data + m1 = new MaterialDTO("M-1", "update-tornillos", new BigDecimal(20), + unitTypeCodeB, false); + + materialDTOs1 = new ArrayList(); + materialDTOs1.add(m1); + + mc1 = new MaterialCategoryDTO("MC-C", "update-MC-C", "MC-B", null, null); + subCategoryListDTOC = createMaterialCategoryListDTO(mc1); + + mc2 = new MaterialCategoryDTO("MC-B", "update-MC-B", null, + subCategoryListDTOC, materialDTOs1); + subCategoryListDTOB = createMaterialCategoryListDTO(mc2); + + /* Build main material category */ + materialCategoryDTO = new MaterialCategoryDTO("C-A", "update-C-A", + null, subCategoryListDTOB, null); + + materialCategoryListDTOA = createMaterialCategoryListDTO(materialCategoryDTO); + + instanceConstraintViolationsList = materialService + .addMaterials(materialCategoryListDTOA).instanceConstraintViolationsList; + + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 0); + + try { + MaterialCategory mc = materialCategoryDAO.findByCode("C-A"); + MaterialCategory mcb = materialCategoryDAO.findByCode("MC-B"); + MaterialCategory mcc = materialCategoryDAO.findByCode("MC-C"); + + assertTrue(mcb.getMaterials().size() == 1); + assertTrue(mcb.getSubcategories().size() == 1); + assertTrue(mc.getName().equalsIgnoreCase("update-C-A")); + assertTrue(mcb.getName().equalsIgnoreCase("update-MC-B")); + assertTrue(mcc.getName().equalsIgnoreCase("update-MC-C")); + + Material m = materialDAO.findByCode("M-1"); + assertTrue(m.getDescription().equalsIgnoreCase("update-tornillos")); + assertTrue(m.getDefaultUnitPrice().compareTo(new BigDecimal(20)) == 0); + assertTrue(m.getUnitType().getCode().equals(unitTypeCodeB)); + assertTrue(!m.getDisabled()); + } catch (InstanceNotFoundException e) { + fail(); + } + + // invalid parent code. The parent not is updatable + mc1 = new MaterialCategoryDTO("MC-C", "update-MC-C", "C-A", null, null); + subCategoryListDTOC = createMaterialCategoryListDTO(mc1); + + /* Build main material category */ + materialCategoryDTO = new MaterialCategoryDTO("C-A", "update-C-A", + null, subCategoryListDTOC, null); + + materialCategoryListDTOA = createMaterialCategoryListDTO(materialCategoryDTO); + + instanceConstraintViolationsList = materialService + .addMaterials(materialCategoryListDTOA).instanceConstraintViolationsList; + + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 1); + + /* Build main material category */ + materialCategoryDTO = new MaterialCategoryDTO("C-A", "update-C-A", + "XXX", subCategoryListDTOC, null); + + materialCategoryListDTOA = createMaterialCategoryListDTO(materialCategoryDTO); + + instanceConstraintViolationsList = materialService + .addMaterials(materialCategoryListDTOA).instanceConstraintViolationsList; + + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 1); + + } + + private MaterialCategoryListDTO createMaterialCategoryListDTO( + MaterialCategoryDTO... materialCategoryDTOs) { + + List materialCategoryList = new ArrayList(); + + for (MaterialCategoryDTO c : materialCategoryDTOs) { + materialCategoryList.add(c); + } + + return new MaterialCategoryListDTO(materialCategoryList); + + } + +} diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/orders/OrderElementServiceTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/orders/OrderElementServiceTest.java index 29cdced63..c454992c0 100644 --- a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/orders/OrderElementServiceTest.java +++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/orders/OrderElementServiceTest.java @@ -475,7 +475,7 @@ public class OrderElementServiceTest { List constraintViolations = instanceConstraintViolationsList .get(0).constraintViolations; // Mandatory fields: material code - assertThat(constraintViolations.size(), equalTo(2)); + assertThat(constraintViolations.size(), equalTo(1)); assertThat(constraintViolations.get(0).fieldName, mustEnd("code")); assertThat(orderDAO.getOrders().size(), equalTo(previous)); diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/criterion/api/CriterionServiceTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/criterion/api/CriterionServiceTest.java index 34056c363..445d40af0 100644 --- a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/criterion/api/CriterionServiceTest.java +++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/criterion/api/CriterionServiceTest.java @@ -68,6 +68,32 @@ public class CriterionServiceTest { @Autowired private ICriterionTypeDAO criterionTypeDAO; + @Test + public void testAddCriterionWithSameCodeDistinctTypes() { + + /* Build criterion type "ct1" (5 constraint violations). */ + CriterionDTO c1 = new CriterionDTO("new_c1_code", "new_c1", true, + new ArrayList()); + + List ct1Criterions = new ArrayList(); + ct1Criterions.add(c1); + + CriterionTypeDTO ct1 = new CriterionTypeDTO("new_type_A", "desc", + false, true, true, ResourceEnumDTO.RESOURCE, ct1Criterions); + + CriterionTypeDTO ct2 = new CriterionTypeDTO("new_type_B", "desc", true, + true, false, ResourceEnumDTO.RESOURCE, null); + + /* Criterion type list. */ + CriterionTypeListDTO criterionTypes = createCriterionTypeListDTO(ct1, + ct2); + + List instanceConstraintViolationsList = criterionService + .addCriterionTypes(criterionTypes).instanceConstraintViolationsList; + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 1); + } + @Test public void testAddAndGetCriterionTypes() { diff --git a/scripts/rest-clients/export-material-categories.sh b/scripts/rest-clients/export-material-categories.sh new file mode 100755 index 000000000..fdd242d5a --- /dev/null +++ b/scripts/rest-clients/export-material-categories.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +. ./rest-common-env.sh + +printf "Login name: " +read loginName +printf "Password: " +read password + +if [ "$1" = "--prod" ]; then + baseServiceURL=$PRODUCTION_BASE_SERVICE_URL + certificate=$PRODUCTION_CERTIFICATE +else + baseServiceURL=$DEVELOPMENT_BASE_SERVICE_URL + certificate=$DEVELOPMENT_CERTIFICATE +fi + +authorization=`./base64.sh $loginName:$password` + +curl -sv -X GET $certificate --header "Authorization: Basic $authorization" \ + $baseServiceURL/materialcategories | tidy -xml -i -q -utf8 diff --git a/scripts/rest-clients/import-material-categories.sh b/scripts/rest-clients/import-material-categories.sh new file mode 100755 index 000000000..91419197c --- /dev/null +++ b/scripts/rest-clients/import-material-categories.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +. ./rest-common-env.sh + +printf "Login name: " +read loginName +printf "Password: " +read password + +baseServiceURL=$DEVELOPMENT_BASE_SERVICE_URL +certificate=$DEVELOPMENT_CERTIFICATE + +for i in "$@" +do + if [ "$i" = "--prod" ]; then + baseServiceURL=$PRODUCTION_BASE_SERVICE_URL + certificate=$PRODUCTION_CERTIFICATE + else + file=$i + fi +done + +if [ "$file" = "" ]; then + printf "Missing file\n" 1>&2 + exit 1 +fi + +authorization=`./base64.sh $loginName:$password` + +curl -sv -X POST $certificate -d @$file \ + --header "Content-type: application/xml" \ + --header "Authorization: Basic $authorization" \ + $baseServiceURL/materialcategories | tidy -xml -i -q -utf8 diff --git a/scripts/rest-clients/material-categories-sample.xml b/scripts/rest-clients/material-categories-sample.xml new file mode 100644 index 000000000..72a1b7f12 --- /dev/null +++ b/scripts/rest-clients/material-categories-sample.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + +