From 529bfc2456d172dacb9f6b244dd12fbf2de927d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Aragunde=20P=C3=A9rez?= Date: Wed, 2 Dec 2009 20:58:18 +0100 Subject: [PATCH] ItEr34S15CUAdministracionCategoriaCoste: implementing the relation between HourCost and CostCategory. Implemented the necessary methods to manage it so it can be navigated bidirectionally. Implemented tests to try it. TODO: implement Date attributes using the class org.joda.time.LocalDate instead of java.util.Date. TODO: implement the validator HourCostNotOverlapping. --- .../costcategories/daos/HourCostDAO.java | 12 +++++ .../costcategories/daos/IHourCostDAO.java | 3 ++ .../costcategories/entities/CostCategory.java | 42 ++++++++++++++++++ .../costcategories/entities/HourCost.java | 16 +++++++ .../entities/CostCategories.hbm.xml | 6 +++ .../daos/CostCategoryDAOTest.java | 44 +++++++++++++++++++ .../costcategories/daos/HourCostDAOTest.java | 37 ++++++++++++++++ 7 files changed, 160 insertions(+) diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/daos/HourCostDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/daos/HourCostDAO.java index 853af06a0..007a7dd51 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/daos/HourCostDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/daos/HourCostDAO.java @@ -21,6 +21,7 @@ package org.navalplanner.business.costcategories.daos; import org.navalplanner.business.common.daos.GenericDAOHibernate; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.costcategories.entities.HourCost; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; @@ -34,4 +35,15 @@ import org.springframework.stereotype.Repository; public class HourCostDAO extends GenericDAOHibernate implements IHourCostDAO { + @Override + public void remove(Long id) throws InstanceNotFoundException { + try { + find(id).getCategory().removeHourCost(find(id)); + } + catch(InstanceNotFoundException e) { + //it was already deleted from its parent + //we do nothing + } + super.remove(id); + } } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/daos/IHourCostDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/daos/IHourCostDAO.java index ff183ab34..67c0bc545 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/daos/IHourCostDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/daos/IHourCostDAO.java @@ -21,6 +21,7 @@ package org.navalplanner.business.costcategories.daos; import org.navalplanner.business.common.daos.IGenericDAO; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.costcategories.entities.HourCost; /** @@ -28,4 +29,6 @@ import org.navalplanner.business.costcategories.entities.HourCost; */ public interface IHourCostDAO extends IGenericDAO { + @Override + public void remove(Long id) throws InstanceNotFoundException; } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/entities/CostCategory.java b/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/entities/CostCategory.java index 6744a66bb..4c612dec5 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/entities/CostCategory.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/entities/CostCategory.java @@ -20,6 +20,11 @@ package org.navalplanner.business.costcategories.entities; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import org.hibernate.validator.AssertTrue; import org.hibernate.validator.NotEmpty; import org.navalplanner.business.common.BaseEntity; @@ -31,6 +36,8 @@ public class CostCategory extends BaseEntity { @NotEmpty private String name; + private Set hourCosts = new HashSet(); + // Default constructor, needed by Hibernate protected CostCategory() { @@ -51,4 +58,39 @@ public class CostCategory extends BaseEntity { public void setName(String name) { this.name = name; } + + public Set getHourCosts() { + return hourCosts; + } + + public void addHourCost(HourCost hourCost) { + hourCosts.add(hourCost); + if(hourCost.getCategory()!=this) + hourCost.setCategory(this); + } + + public void removeHourCost(HourCost hourCost) { + hourCosts.remove(hourCost); + if(hourCost.getCategory()==this) + hourCost.setCategory(null); + } + + public boolean canAddHourCost(HourCost hourCost) { + boolean overlap = false; + Date initDate = hourCost.getInitDate(); + Date endDate = hourCost.getEndDate(); + for(HourCost listElement:hourCosts) { + if((listElement.getEndDate().compareTo(initDate)>=0 && listElement.getEndDate().compareTo(endDate)<=0) || + (listElement.getInitDate().compareTo(initDate)>=0 && listElement.getInitDate().compareTo(endDate)<=0)) + overlap = true; + } + return !overlap; + } + + @AssertTrue + public boolean HourCostNotOverlapping() { + //TODO: implement a method to validate HourCost time intervals + //complementary with canAddHourCost(), this method is run when calling DAO.save() + return true; + } } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/entities/HourCost.java b/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/entities/HourCost.java index aaabf1639..be528f0cc 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/entities/HourCost.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/costcategories/entities/HourCost.java @@ -42,6 +42,9 @@ public class HourCost extends BaseEntity { @NotNull private TypeOfWorkHours type; + @NotNull + private CostCategory category; + // Default constructor, needed by Hibernate protected HourCost() { @@ -87,4 +90,17 @@ public class HourCost extends BaseEntity { public void setType(TypeOfWorkHours type) { this.type = type; } + + public CostCategory getCategory() { + return category; + } + + public void setCategory(CostCategory category) { + CostCategory oldCategory = this.category; + this.category = category; + if(oldCategory!=null) + oldCategory.removeHourCost(this); + if(category!=null && !category.getHourCosts().contains(this)) + category.addHourCost(this); + } } diff --git a/navalplanner-business/src/main/resources/org/navalplanner/business/costcategories/entities/CostCategories.hbm.xml b/navalplanner-business/src/main/resources/org/navalplanner/business/costcategories/entities/CostCategories.hbm.xml index 7193752bb..4df07a07d 100644 --- a/navalplanner-business/src/main/resources/org/navalplanner/business/costcategories/entities/CostCategories.hbm.xml +++ b/navalplanner-business/src/main/resources/org/navalplanner/business/costcategories/entities/CostCategories.hbm.xml @@ -13,6 +13,10 @@ + + + + @@ -32,6 +36,8 @@ + + diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/costcategories/daos/CostCategoryDAOTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/costcategories/daos/CostCategoryDAOTest.java index 1fb6fd3fe..19dd74d15 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/costcategories/daos/CostCategoryDAOTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/costcategories/daos/CostCategoryDAOTest.java @@ -23,10 +23,13 @@ package org.navalplanner.business.test.costcategories.daos; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE; import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE; +import java.math.BigDecimal; +import java.util.Date; import java.util.List; import java.util.UUID; @@ -35,6 +38,7 @@ import org.junit.runner.RunWith; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.costcategories.daos.ICostCategoryDAO; import org.navalplanner.business.costcategories.entities.CostCategory; +import org.navalplanner.business.costcategories.entities.HourCost; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -88,4 +92,44 @@ public class CostCategoryDAOTest { List list = costCategoryDAO.list(CostCategory.class); assertEquals(previous + 1, list.size()); } + + @Test + public void testCanAddHourCost() { + CostCategory costCategory = createValidCostCategory(); + HourCost hourCost1 = HourCost.create(BigDecimal.ONE, new Date(2009, 11,1)); + hourCost1.setEndDate(new Date(2009, 11,10)); + costCategory.addHourCost(hourCost1); + + HourCost hourCost2 = HourCost.create(BigDecimal.ONE, new Date(2009, 11,1)); + hourCost2.setEndDate(new Date(2009, 11,10)); + assertFalse(costCategory.canAddHourCost(hourCost2)); + + hourCost2.setInitDate(new Date(2009,10,15)); + hourCost2.setEndDate(new Date(2009,11,1)); + assertFalse(costCategory.canAddHourCost(hourCost2)); + + hourCost2.setInitDate(new Date(2009,11,10)); + hourCost2.setEndDate(new Date(2009,11,10)); + assertFalse(costCategory.canAddHourCost(hourCost2)); + + hourCost2.setInitDate(new Date(2009,10,15)); + hourCost2.setEndDate(new Date(2009,10,20)); + assertTrue(costCategory.canAddHourCost(hourCost2)); + } + + @Test + public void testListHourCosts() { + CostCategory costCategory = createValidCostCategory(); + HourCost hourCost = HourCost.create(BigDecimal.ONE, new Date(2009,11,1)); + int previous = costCategory.getHourCosts().size(); + + costCategory.addHourCost(hourCost); + costCategoryDAO.save(costCategory); + assertEquals(previous + 1, costCategory.getHourCosts().size()); + + costCategory.removeHourCost(hourCost); + costCategoryDAO.save(costCategory); + assertEquals(previous, costCategory.getHourCosts().size()); + assertNull(hourCost.getCategory()); + } } diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/costcategories/daos/HourCostDAOTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/costcategories/daos/HourCostDAOTest.java index ce15e7ee9..b7a217b32 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/costcategories/daos/HourCostDAOTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/costcategories/daos/HourCostDAOTest.java @@ -35,8 +35,10 @@ import java.util.UUID; import org.junit.Test; import org.junit.runner.RunWith; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +import org.navalplanner.business.costcategories.daos.ICostCategoryDAO; import org.navalplanner.business.costcategories.daos.IHourCostDAO; import org.navalplanner.business.costcategories.daos.ITypeOfWorkHoursDAO; +import org.navalplanner.business.costcategories.entities.CostCategory; import org.navalplanner.business.costcategories.entities.HourCost; import org.navalplanner.business.costcategories.entities.TypeOfWorkHours; import org.springframework.beans.factory.annotation.Autowired; @@ -62,6 +64,9 @@ public class HourCostDAOTest { @Autowired ITypeOfWorkHoursDAO typeOfWorkHoursDAO; + @Autowired + ICostCategoryDAO costCategoryDAO; + @Test public void testInSpringContainer() { assertNotNull(hourCostDAO); @@ -73,6 +78,11 @@ public class HourCostDAOTest { TypeOfWorkHours.create(UUID.randomUUID().toString(), UUID.randomUUID().toString()); hourCost.setType(type); typeOfWorkHoursDAO.save(type); + + CostCategory costCategory = CostCategory.create(UUID.randomUUID().toString()); + hourCost.setCategory(costCategory); + costCategoryDAO.save(costCategory); + return hourCost; } @@ -99,4 +109,31 @@ public class HourCostDAOTest { List list = hourCostDAO.list(HourCost.class); assertEquals(previous + 1, list.size()); } + + @Test + public void testCategoryNavigation() { + HourCost hourCost = createValidHourCost(); + assertTrue(hourCost.getCategory().getHourCosts().contains(hourCost)); + } + + @Test + public void testHourCostNotInTwoCategories() { + HourCost hourCost = createValidHourCost(); + CostCategory costCategory1 = CostCategory.create(UUID.randomUUID().toString()); + CostCategory costCategory2 = CostCategory.create(UUID.randomUUID().toString()); + + hourCost.setCategory(costCategory1); + hourCost.setCategory(costCategory2); + hourCostDAO.save(hourCost); + + assertFalse(costCategory1.getHourCosts().contains(hourCost)); + assertTrue(costCategory2.getHourCosts().contains(hourCost)); + + costCategory1.addHourCost(hourCost); + costCategory2.addHourCost(hourCost); + hourCostDAO.save(hourCost); + + assertFalse(costCategory1.getHourCosts().contains(hourCost)); + assertTrue(costCategory2.getHourCosts().contains(hourCost)); + } }