/* * This file is part of LibrePlan * * Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e * Desenvolvemento Tecnolóxico de Galicia * Copyright (C) 2010-2011 Igalia, S.L. * * 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 <http://www.gnu.org/licenses/>. */ package org.libreplan.business.test.orders.entities; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.libreplan.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE; import static org.libreplan.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE; import java.math.BigDecimal; import javax.annotation.Resource; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.joda.time.LocalDate; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.libreplan.business.IDataBootstrap; import org.libreplan.business.advance.daos.IAdvanceAssignmentDAO; import org.libreplan.business.advance.daos.IAdvanceTypeDAO; import org.libreplan.business.advance.entities.AdvanceAssignment; import org.libreplan.business.advance.entities.AdvanceMeasurement; import org.libreplan.business.advance.entities.AdvanceType; import org.libreplan.business.advance.entities.DirectAdvanceAssignment; import org.libreplan.business.advance.exceptions.DuplicateAdvanceAssignmentForOrderElementException; import org.libreplan.business.advance.exceptions.DuplicateValueTrueReportGlobalAdvanceException; import org.libreplan.business.common.daos.IConfigurationDAO; import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.orders.daos.IOrderDAO; import org.libreplan.business.orders.entities.HoursGroup; import org.libreplan.business.orders.entities.Order; import org.libreplan.business.orders.entities.OrderElement; import org.libreplan.business.orders.entities.OrderLine; import org.libreplan.business.orders.entities.OrderLineGroup; import org.libreplan.business.scenarios.IScenarioManager; import org.libreplan.business.scenarios.entities.OrderVersion; import org.libreplan.business.test.planner.daos.ResourceAllocationDAOTest; import org.libreplan.business.test.resources.daos.CriterionSatisfactionDAOTest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; /** * Tests for {@link AdvanceAssignment of OrderElement}. * <br /> * @author Susana Montes Pedreira <smontes@wirelessgalicia.com> */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE, BUSINESS_SPRING_CONFIG_TEST_FILE }) public class AddAdvanceAssignmentsToOrderElementTest { @Resource private IDataBootstrap defaultAdvanceTypesBootstrapListener; @Resource private IDataBootstrap configurationBootstrap; @Before public void loadRequiredData() { defaultAdvanceTypesBootstrapListener.loadRequiredData(); configurationBootstrap.loadRequiredData(); } @Autowired private SessionFactory sessionFactory; @Autowired private IOrderDAO orderDao; @Autowired private IAdvanceAssignmentDAO advanceAssignmentDao; @Autowired private IAdvanceTypeDAO advanceTypeDao; @Autowired private IConfigurationDAO configurationDAO; @Autowired private IScenarioManager scenarioManager; private Session getSession() { return sessionFactory.getCurrentSession(); } private Order createValidOrder() { Order order = Order.create(); OrderVersion orderVersion = ResourceAllocationDAOTest.setupVersionUsing(scenarioManager, order); order.useSchedulingDataFor(orderVersion); order.setDescription("description"); order.setInitDate(CriterionSatisfactionDAOTest.year(2000).toDateTimeAtStartOfDay().toDate()); order.setName("name"); order.setResponsible("responsible"); order.setCode("code"); order.setCalendar(configurationDAO.getConfiguration().getDefaultCalendar()); return order; } private OrderLine createValidLeaf(String name, String code) { OrderLine result = OrderLine.create(); result.setName(name); result.setCode(code); HoursGroup hoursGroup = HoursGroup.create(result); hoursGroup.setWorkingHours(0); hoursGroup.setCode("hoursGroupName"); result.addHoursGroup(hoursGroup); return result; } private AdvanceType createValidAdvanceType(String name) { BigDecimal value = new BigDecimal(120).setScale(2); BigDecimal precision = new BigDecimal(10).setScale(4); AdvanceType advanceType = AdvanceType.create(name, value, true, precision, true, false); return advanceType; } private AdvanceMeasurement createValidAdvanceMeasurement() { AdvanceMeasurement advanceMeasurement = AdvanceMeasurement.create(new LocalDate(), new BigDecimal(0)); return advanceMeasurement; } private DirectAdvanceAssignment createValidAdvanceAssignment(boolean reportGlobalAdvance) { return DirectAdvanceAssignment.create(reportGlobalAdvance, BigDecimal.TEN); } @Test @Transactional public void savingTheOrderSavesAlsoTheAddedAssignments() throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException { Order order = createValidOrder(); OrderElement orderLine = createValidLeaf("OrderLineA", "1k1k1k1k"); AdvanceType advanceType = createAndSaveType("tipoA"); DirectAdvanceAssignment advanceAssignment = createValidAdvanceAssignment(true); assertTrue(orderLine.getDirectAdvanceAssignments().isEmpty()); advanceAssignment.setAdvanceType(advanceType); order.add(orderLine); orderDao.save(order); orderLine.addAdvanceAssignment(advanceAssignment); orderDao.save(order); this.sessionFactory.getCurrentSession().flush(); assertFalse(orderLine.getDirectAdvanceAssignments().isEmpty()); assertTrue(advanceAssignmentDao.exists(advanceAssignment.getId())); } private AdvanceType createAndSaveType(String typeName) { AdvanceType advanceType = createValidAdvanceType(typeName); advanceTypeDao.save(advanceType); return advanceType; } @Test @Transactional public void addingSeveralAssignmentsOfDifferentTypes() throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException { Order order = createValidOrder(); OrderLine orderLine = createValidLeaf("OrderLineA", "1111111"); AdvanceType advanceTypeA = createAndSaveType("tipoA"); AdvanceType advanceTypeB = createAndSaveType("tipoB"); DirectAdvanceAssignment advanceAssignmentA = createValidAdvanceAssignment(true); advanceAssignmentA.setAdvanceType(advanceTypeA); order.add(orderLine); orderDao.save(order); orderLine.addAdvanceAssignment(advanceAssignmentA); DirectAdvanceAssignment advanceAssignmentB = createValidAdvanceAssignment(false); advanceAssignmentB.setAdvanceType(advanceTypeB); orderLine.addAdvanceAssignment(advanceAssignmentB); } @Test @Transactional public void cannotAddDuplicatedAssignment() throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException { OrderLine orderLine = createValidLeaf("OrderLineA", "22222222"); AdvanceType advanceTypeA = createAndSaveType("tipoA"); DirectAdvanceAssignment advanceAssignmentA = createValidAdvanceAssignment(true); advanceAssignmentA.setAdvanceType(advanceTypeA); orderLine.addAdvanceAssignment(advanceAssignmentA); DirectAdvanceAssignment advanceAssignmentB = createValidAdvanceAssignment(false); advanceAssignmentB.setAdvanceType(advanceTypeA); try { orderLine.addAdvanceAssignment(advanceAssignmentB); fail("It should throw an exception"); } catch (DuplicateAdvanceAssignmentForOrderElementException ignored) { // Ok } } @Test @Transactional public void cannotAddTwoAssignmentsWithGlobalReportValue() throws DuplicateAdvanceAssignmentForOrderElementException, DuplicateValueTrueReportGlobalAdvanceException { OrderLine orderLine = createValidLeaf("OrderLineA", "101010101"); AdvanceType advanceTypeA = createAndSaveType("tipoA"); AdvanceType advanceTypeB = createAndSaveType("tipoB"); DirectAdvanceAssignment advanceAssignmentA = createValidAdvanceAssignment(true); advanceAssignmentA.setAdvanceType(advanceTypeA); orderLine.addAdvanceAssignment(advanceAssignmentA); DirectAdvanceAssignment advanceAssignmentB = createValidAdvanceAssignment(true); advanceAssignmentB.setAdvanceType(advanceTypeB); try { orderLine.addAdvanceAssignment(advanceAssignmentB); fail("It should throw an exception "); } catch (DuplicateValueTrueReportGlobalAdvanceException ignored) { // Ok } } @Test @Transactional public void addingAssignmentsOfAnotherTypeToSon() throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException { Order validOrder = createValidOrder(); OrderLineGroup container = OrderLineGroup.create(); validOrder.add(container); container.setName("bla"); container.setCode("000000000"); OrderLine son = createValidLeaf("bla", "132"); container.add(son); AdvanceMeasurement advanceMeasurement = createValidAdvanceMeasurement(); AdvanceType advanceTypeA = createAndSaveType("tipoA"); AdvanceType advanceTypeB = createAndSaveType("tipoB"); DirectAdvanceAssignment advanceAssignmentA = createValidAdvanceAssignment(true); advanceAssignmentA.setAdvanceType(advanceTypeA); DirectAdvanceAssignment advanceAssignmentB = createValidAdvanceAssignment(false); advanceAssignmentB.setAdvanceType(advanceTypeB); OrderElementTest .removeReportGlobalAdvanceFromChildrenAdvance(container); container.addAdvanceAssignment(advanceAssignmentA); son.addAdvanceAssignment(advanceAssignmentB); advanceAssignmentA.addAdvanceMeasurements(advanceMeasurement); advanceAssignmentB.addAdvanceMeasurements(advanceMeasurement); } @Test @Transactional public void addingAnAdvanceAssignmentIncreasesTheNumberOfAdvanceAssignments() throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException { Order validOrder = createValidOrder(); final OrderLineGroup container = OrderLineGroup.create(); validOrder.add(container); container.setName("bla"); container.setCode("000000000"); container.add(createValidLeaf("bla", "979")); AdvanceType advanceTypeA = createAndSaveType("tipoA"); DirectAdvanceAssignment advanceAssignmentA = createValidAdvanceAssignment(true); advanceAssignmentA.setAdvanceType(advanceTypeA); OrderElementTest.removeReportGlobalAdvanceFromChildrenAdvance(container); container.addAdvanceAssignment(advanceAssignmentA); assertThat(container.getDirectAdvanceAssignments().size(), equalTo(1)); } @Test @Transactional public void cannotAddDuplicatedAssignmentToSon() throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException { Order validOrder = createValidOrder(); final OrderLineGroup father = OrderLineGroup.create(); validOrder.add(father); father.setName("bla"); father.setCode("000000000"); father.add(createValidLeaf("bla", "979")); AdvanceType advanceTypeA = createAndSaveType("tipoA"); DirectAdvanceAssignment advanceAssignmentA = createValidAdvanceAssignment(true); advanceAssignmentA.setAdvanceType(advanceTypeA); DirectAdvanceAssignment anotherAssignmentWithSameType = createValidAdvanceAssignment(false); anotherAssignmentWithSameType.setAdvanceType(advanceTypeA); OrderElementTest.removeReportGlobalAdvanceFromChildrenAdvance(father); father.addAdvanceAssignment(advanceAssignmentA); try { OrderElement child = father.getChildren().get(0); child.addAdvanceAssignment(anotherAssignmentWithSameType); fail("It should throw an exception "); } catch (DuplicateAdvanceAssignmentForOrderElementException ignored) { // Ok } } @Test @Transactional public void cannotAddDuplicateAssignmentToGrandParent() throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException { Order validOrder = createValidOrder(); OrderLineGroup parent = OrderLineGroup.create(); validOrder.add(parent); parent.setName("bla_"); parent.setCode("000000000"); OrderLineGroup son = OrderLineGroup.create(); son.setName("Son"); son.setCode("11111111"); parent.add(son); OrderLine grandSon = createValidLeaf("GranSon", "75757"); son.add(grandSon); AdvanceMeasurement advanceMeasurement = createValidAdvanceMeasurement(); AdvanceType advanceTypeA = createAndSaveType("tipoA"); DirectAdvanceAssignment advanceAssignmentA = createValidAdvanceAssignment(true); advanceAssignmentA.setAdvanceType(advanceTypeA); DirectAdvanceAssignment advanceAssignmentB = createValidAdvanceAssignment(false); advanceAssignmentB.setAdvanceType(advanceTypeA); grandSon.addAdvanceAssignment(advanceAssignmentA); advanceAssignmentA.addAdvanceMeasurements(advanceMeasurement); try { parent.addAdvanceAssignment(advanceAssignmentB); advanceAssignmentB.addAdvanceMeasurements(advanceMeasurement); fail("It should throw an exception "); } catch (DuplicateAdvanceAssignmentForOrderElementException ignored) { // Ok } } @Test(expected = DuplicateAdvanceAssignmentForOrderElementException.class) @Transactional public void addingAnotherAdvanceAssignmentWithAnEquivalentTypeButDifferentInstance() throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException { final Order order = createValidOrder(); final OrderLine line = createValidLeaf("GranSon", "75757"); order.add(line); orderDao.save(order); AdvanceType type = createAndSaveType("tipoA"); getSession().flush(); final DirectAdvanceAssignment assignment = createValidAdvanceAssignment(false); assignment.setAdvanceType(type); line.addAdvanceAssignment(assignment); getSession().evict(type); AdvanceType typeReloaded = reloadType(type); final DirectAdvanceAssignment assignmentWithSameType = createValidAdvanceAssignment(false); assignmentWithSameType.setAdvanceType(typeReloaded); line.addAdvanceAssignment(assignmentWithSameType); } private AdvanceType reloadType(AdvanceType type) { try { // New instance of id is created to avoid both types have the same id object Long newLong = new Long(type.getId()); return advanceTypeDao.find(newLong); } catch (InstanceNotFoundException e) { throw new RuntimeException(e); } } @Test(expected = DuplicateValueTrueReportGlobalAdvanceException.class) @Transactional public void cannotAddTwoAssignmentsDirectAndIndirectWithGlobalReportValue() throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException { OrderLineGroup orderLineGroup = OrderLineGroup.create(); orderLineGroup.setName("test"); orderLineGroup.setCode("1"); AdvanceType advanceType = createAndSaveType("test"); DirectAdvanceAssignment advanceAssignmentA = createValidAdvanceAssignment(true); advanceAssignmentA.setAdvanceType(advanceType); DirectAdvanceAssignment advanceAssignmentB = createValidAdvanceAssignment(true); advanceAssignmentB.setAdvanceType(advanceType); orderLineGroup.addAdvanceAssignment(advanceAssignmentA); orderLineGroup.addAdvanceAssignment(advanceAssignmentB); } }