/* * 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.web.planner.chart; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.libreplan.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE; import static org.libreplan.web.WebappGlobalNames.WEBAPP_SPRING_CONFIG_FILE; import static org.libreplan.web.WebappGlobalNames.WEBAPP_SPRING_SECURITY_CONFIG_FILE; import static org.libreplan.web.test.WebappGlobalNames.WEBAPP_SPRING_CONFIG_TEST_FILE; import static org.libreplan.web.test.WebappGlobalNames.WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE; import java.math.BigDecimal; import java.util.Calendar; import java.util.SortedMap; import java.util.TreeMap; import java.util.UUID; import org.easymock.EasyMock; 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.calendars.daos.IBaseCalendarDAO; import org.libreplan.business.calendars.entities.BaseCalendar; import org.libreplan.business.common.IAdHocTransactionService; import org.libreplan.business.common.IOnTransaction; import org.libreplan.business.common.daos.IConfigurationDAO; 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.planner.entities.IOrderEarnedValueCalculator; import org.libreplan.business.planner.entities.SpecificDayAssignmentsContainer; import org.libreplan.business.planner.entities.SpecificResourceAllocation; import org.libreplan.business.planner.entities.Task; import org.libreplan.business.scenarios.entities.Scenario; import org.libreplan.business.workingday.ResourcesPerDay; import org.libreplan.web.calendars.BaseCalendarModel; import org.libreplan.web.calendars.IBaseCalendarModel; import org.libreplan.web.common.IConfigurationModel; import org.libreplan.web.orders.IOrderModel; import org.libreplan.web.planner.order.PlanningStateCreator; import org.libreplan.web.planner.order.PlanningStateCreator.PlanningState; import org.libreplan.web.resources.worker.IAssignedCriterionsModel; import org.libreplan.web.resources.worker.IWorkerModel; 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; import org.zkforge.timeplot.Timeplot; import org.zkoss.ganttz.util.Interval; import org.zkoss.zk.ui.Desktop; import javax.annotation.Resource; /** * Tests for {@link ChartFiller}. * * @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com> */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_TEST_FILE, WEBAPP_SPRING_SECURITY_CONFIG_FILE, WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE }) @Transactional public class ChartFillerTest { private ChartFiller chartFiller = new ChartFiller() { @Override public void fillChart(Timeplot chart, Interval interval, Integer size) { } }; private static final LocalDate START_DAY = new LocalDate(2009, 12, 1); private static final LocalDate FIRST_DAY = new LocalDate(2009, 12, 5); private static final LocalDate LAST_DAY = new LocalDate(2009, 12, 15); private static final LocalDate FINISH_DAY = new LocalDate(2009, 12, 30); private SortedMap<LocalDate, BigDecimal> givenExampleMap() { SortedMap<LocalDate, BigDecimal> result = new TreeMap<>(); result.put(FIRST_DAY, new BigDecimal(100)); result.put(LAST_DAY, new BigDecimal(150)); return result; } @Test public void testCalculatedValueForEveryDay() { SortedMap<LocalDate, BigDecimal> result = chartFiller.calculatedValueForEveryDay(givenExampleMap(), START_DAY, FINISH_DAY); assertThat(result.get(START_DAY), equalTo(BigDecimal.ZERO.setScale(2))); assertThat(result.get(START_DAY.plusDays(1)), equalTo(new BigDecimal(25).setScale(2))); assertThat(result.get(FIRST_DAY), equalTo(new BigDecimal(100).setScale(2))); assertThat(result.get(FIRST_DAY.plusDays(1)), equalTo(new BigDecimal(105).setScale(2))); assertThat(result.get(LAST_DAY), equalTo(new BigDecimal(150).setScale(2))); assertThat(result.get(LAST_DAY.plusDays(1)), equalTo(new BigDecimal(150).setScale(2))); assertThat(result.get(FINISH_DAY), equalTo(new BigDecimal(150).setScale(2))); } @Resource private IDataBootstrap defaultAdvanceTypesBootstrapListener; @Resource private IDataBootstrap scenariosBootstrap; @Resource private IDataBootstrap configurationBootstrap; @Autowired private IAdHocTransactionService transactionService; @Before public void loadRequiredData() { IOnTransaction<Void> load = new IOnTransaction<Void>() { @Override public Void execute() { defaultAdvanceTypesBootstrapListener.loadRequiredData(); configurationBootstrap.loadRequiredData(); scenariosBootstrap.loadRequiredData(); return null; } }; transactionService.runOnAnotherTransaction(load); } // Testing BAC values // 1. Create Worker // 2. Create Project // 3. Create 2 Tasks // 4. Assign Resources to Tasks // 5. Check BAC values @Resource IBaseCalendarModel baseCalendarModel; @Autowired IBaseCalendarDAO baseCalendarDAO; @Autowired IConfigurationModel configurationModel; @Test public void testBAC() { createAndSaveWorker(); createAndSaveProject(); createAndSaveTwoTasksForProject(); assignAndSaveResourcesForTasks(); BigDecimal BAC = earnedValueCalculator.getBudgetAtCompletion(orderModel.getOrder()); assertEquals(BAC, new BigDecimal(50)); } /** For creation of worker */ @Autowired IWorkerModel workerModel; @Autowired IAssignedCriterionsModel assignedCriterionsModel; private void createAndSaveWorker() { workerModel.prepareForCreate(); workerModel.getWorker().setFirstName("Neil"); workerModel.getWorker().setSurname("Armstrong"); workerModel.getWorker().setNif("666"); workerModel.getAssignedCriterionsModel().prepareForCreate(workerModel.getWorker()); workerModel.save(); } /** For project creation */ @Autowired IOrderModel orderModel; @Autowired private PlanningStateCreator planningStateCreator; @Autowired private IAdHocTransactionService adHocTransaction; @Autowired private IConfigurationDAO configurationDAO; private void createAndSaveProject() { final Order project = Order.create(); project.setDescription("Goal of project: do not be thirsty"); // Create initDate Calendar calendar = Calendar.getInstance(); calendar.clear(); calendar.set(Calendar.YEAR, 2016); project.setInitDate(calendar.getTime()); project.setName("To be not thirsty"); project.setResponsible("human"); project.setCode("code-" + UUID.randomUUID()); BaseCalendar baseCalendar = adHocTransaction.runOnReadOnlyTransaction(() -> { BaseCalendar result = configurationDAO.getConfigurationWithReadOnlyTransaction().getDefaultCalendar(); BaseCalendarModel.forceLoadBaseCalendar(result); return result; }); project.setCalendar(baseCalendar); // Create planningState PlanningState planningState = adHocTransaction.runOnAnotherReadOnlyTransaction( () -> planningStateCreator.createOn(EasyMock.createNiceMock(Desktop.class), project)); orderModel.setPlanningState(planningState); orderModel.save(); } private void createAndSaveTwoTasksForProject(){ OrderElement task1 = OrderLine.createOrderLineWithUnfixedPercentage(10); task1.setName("Take bottle"); task1.setCode(UUID.randomUUID().toString()); for (HoursGroup current : task1.getHoursGroups()) current.setCode(UUID.randomUUID().toString()); OrderElement task2 = OrderLine.createOrderLineWithUnfixedPercentage(40); task2.setName("Drink water"); task2.setCode(UUID.randomUUID().toString()); for (HoursGroup current : task2.getHoursGroups()) current.setCode(UUID.randomUUID().toString()); orderModel.getOrder().add(task1); orderModel.getOrder().add(task2); orderModel.save(); } /** For assigning resources to tasks */ @Autowired private IOrderEarnedValueCalculator earnedValueCalculator; private void assignAndSaveResourcesForTasks(){ // Task 1 Task task1 = (Task) orderModel.getOrder().getAllChildrenAssociatedTaskElements().get(0); SpecificResourceAllocation specificResourceAllocation1 = SpecificResourceAllocation.create(task1); specificResourceAllocation1.setResource(workerModel.getWorker()); Scenario orderScenario1 = null; for (Scenario scenario : orderModel.getOrder().getScenarios().keySet()) { orderScenario1 = scenario; } specificResourceAllocation1.copyAssignments(orderScenario1, orderScenario1); specificResourceAllocation1.allocate(ResourcesPerDay.amount(1)); for (SpecificDayAssignmentsContainer item : specificResourceAllocation1.getSpecificDayAssignmentsContainers()) { item.addAll(specificResourceAllocation1.getAssignments()); } task1.addResourceAllocation(specificResourceAllocation1); // Task 2 Task task2 = (Task) orderModel.getOrder().getAllChildrenAssociatedTaskElements().get(1); SpecificResourceAllocation specificResourceAllocation2 = SpecificResourceAllocation.create(task2); specificResourceAllocation2.setResource(workerModel.getWorker()); Scenario orderScenario2 = null; for (Scenario scenario : orderModel.getOrder().getScenarios().keySet()) { orderScenario2 = scenario; } specificResourceAllocation2.copyAssignments(orderScenario2, orderScenario2); specificResourceAllocation2.allocate(ResourcesPerDay.amount(1)); for (SpecificDayAssignmentsContainer item : specificResourceAllocation2.getSpecificDayAssignmentsContainers()) { item.addAll(specificResourceAllocation2.getAssignments()); } task2.addResourceAllocation(specificResourceAllocation2); } }