Package org.libreplan.web.planner.allocation.streches

Source Code of org.libreplan.web.planner.allocation.streches.GraphicForStreches$ForInterpolation

/*
* 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.allocation.streches;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.libreplan.business.calendars.entities.BaseCalendar;
import org.libreplan.business.planner.entities.ResourceAllocation;
import org.libreplan.business.planner.entities.Stretch;
import org.libreplan.business.planner.entities.StretchesFunction;
import org.libreplan.business.planner.entities.StretchesFunction.Interval;
import org.libreplan.business.planner.entities.StretchesFunctionTypeEnum;
import org.libreplan.web.planner.allocation.streches.StretchesFunctionController.IGraphicGenerator;
import org.zkoss.zul.SimpleXYModel;
import org.zkoss.zul.XYModel;

/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
*
*/
public abstract class GraphicForStreches implements IGraphicGenerator {

    public static IGraphicGenerator forType(StretchesFunctionTypeEnum type) {
        switch (type) {
        case STRETCHES:
            return new ForDefaultStreches();
        case INTERPOLATED:
            return new ForInterpolation();
        default:
            throw new RuntimeException();
        }
    }

    @Override
    public XYModel getAccumulatedHoursChartData(
            IStretchesFunctionModel stretchesFunctionModel) {
        List<Stretch> stretches = stretchesFunctionModel.getStretchesPlusConsolidated();
        if (stretches.isEmpty()) {
            return new SimpleXYModel();
        }
        return getAccumulatedHoursChartData(stretches,
                stretchesFunctionModel.getResourceAllocation(), new BigDecimal(
                        stretchesFunctionModel.getAllocationHours()));
    }

    @Override
    public XYModel getDedicationChart(
            IStretchesFunctionModel stretchesFunctionModel) {
        List<Stretch> stretches = stretchesFunctionModel
                .getStretchesPlusConsolidated();
        if (stretches.isEmpty()) {
            return new SimpleXYModel();
        }
        return getDedicationChart(stretches,
                stretchesFunctionModel.getResourceAllocation(), new BigDecimal(
                        stretchesFunctionModel.getAllocationHours()),
                stretchesFunctionModel.getTaskCalendar());
    }

    protected abstract XYModel getDedicationChart(List<Stretch> stretches,
            ResourceAllocation<?> allocation, BigDecimal totalHours,
            BaseCalendar taskCalendar);

    protected abstract XYModel getAccumulatedHoursChartData(
            List<Stretch> stretches, ResourceAllocation<?> allocation,
            BigDecimal taskHours);

    private static class ForDefaultStreches extends GraphicForStreches {

        @Override
        public boolean areChartsEnabled(IStretchesFunctionModel model) {
            return true;
        }

        @Override
        public XYModel getAccumulatedHoursChartData(List<Stretch> stretches,
                ResourceAllocation<?> allocation, BigDecimal taskHours) {
            XYModel xymodel = new SimpleXYModel();

            String title = "percentage";

            xymodel.addValue(title, allocation.getStartDate()
                    .toDateTimeAtStartOfDay().getMillis(), 0);

            for (Stretch stretch : stretches) {
                BigDecimal amountWork = stretch.getAmountWorkPercentage()
                        .multiply(taskHours);

                xymodel.addValue(title, stretch.getDateIn(allocation)
                        .toDateTimeAtStartOfDay().getMillis(), amountWork);
            }

            return xymodel;
        }

        protected XYModel getDedicationChart(List<Stretch> stretches,
                ResourceAllocation<?> allocation, BigDecimal taskHours,
                BaseCalendar calendar){
            XYModel xymodel = new SimpleXYModel();
            String title = "hours";

            LocalDate previousDate = allocation.getStartDate();
            BigDecimal previousPercentage = BigDecimal.ZERO;
            xymodel.addValue(title, previousDate.toDateTimeAtStartOfDay()
                    .getMillis(), 0);

            for (Stretch stretch : stretches) {
                BigDecimal amountWork = stretch.getAmountWorkPercentage()
                        .subtract(previousPercentage).multiply(taskHours);
                LocalDate endDate = stretch.getDateIn(allocation);
                Integer days = Days.daysBetween(previousDate, endDate)
                        .getDays();

                if (calendar != null) {
                    days -= calendar.getNonWorkableDays(previousDate,
                            endDate.minusDays(1)).size();
                }

                BigDecimal hoursPerDay = BigDecimal.ZERO;
                if (days > 0) {
                    hoursPerDay = amountWork.divide(new BigDecimal(days),
                            RoundingMode.DOWN);
                }

                xymodel.addValue(title, previousDate.toDateTimeAtStartOfDay()
                        .getMillis(), hoursPerDay);
                if (days > 0) {
                    xymodel.addValue(title, endDate.toDateTimeAtStartOfDay()
                            .getMillis() - 1, hoursPerDay);
                }

                previousDate = endDate;
                previousPercentage = stretch.getAmountWorkPercentage();
            }

            xymodel.addValue(title, previousDate.toDateTimeAtStartOfDay()
                    .getMillis() + 1, 0);

            return xymodel;
        }

    }

    private static class ForInterpolation extends GraphicForStreches {

        @Override
        public boolean areChartsEnabled(IStretchesFunctionModel model) {
            return canComputeChartFrom(model.getStretchesPlusConsolidated());
        }

        @Override
        protected XYModel getAccumulatedHoursChartData(List<Stretch> stretches,
                ResourceAllocation<?> allocation, BigDecimal taskHours) {
            if (!canComputeChartFrom(stretches)) {
                return new SimpleXYModel();
            }
            int[] hoursForEachDayUsingSplines = hoursForEachDayInterpolatedUsingSplines(
                    stretches, allocation, taskHours);
            return createModelFrom(allocation.getStartDate(),
                    accumulatedFrom(hoursForEachDayUsingSplines));
        }

        @Override
        protected XYModel getDedicationChart(List<Stretch> stretches,
                ResourceAllocation<?> allocation, BigDecimal totalHours,
                BaseCalendar taskCalendar) {
            if (!canComputeChartFrom(stretches)) {
                return new SimpleXYModel();
            }
            int[] dataForChart = hoursForEachDayInterpolatedUsingSplines(
                    stretches, allocation, totalHours);
            return createModelFrom(allocation.getStartDate(), dataForChart);
        }

        private boolean canComputeChartFrom(List<Stretch> stretches) {
            return StretchesFunctionModel.areValidForInterpolation(stretches);
        }

        private int[] hoursForEachDayInterpolatedUsingSplines(
                List<Stretch> stretches, ResourceAllocation<?> allocation,
                BigDecimal taskHours) {
            List<Interval> intervals = StretchesFunction.intervalsFor(
                    allocation, stretches);
            double[] dayPoints = Interval.getDayPointsFor(
                    allocation.getStartDate(), intervals);
            double[] hourPoints = Interval.getHoursPointsFor(taskHours
                    .intValue(), intervals);
            final Stretch lastStretch = stretches.get(stretches.size() - 1);
            return StretchesFunctionTypeEnum.hoursForEachDayUsingSplines(
                    dayPoints, hourPoints, allocation.getStartDate(),
                    lastStretch.getDateIn(allocation));
        }

        private int[] accumulatedFrom(int[] hoursForEachDayUsingSplines) {
            int[] result = new int[hoursForEachDayUsingSplines.length];
            int accumulated = 0;
            for (int i = 0; i < hoursForEachDayUsingSplines.length; i++) {
                accumulated += hoursForEachDayUsingSplines[i];
                result[i] = accumulated;
            }
            return result;
        }

        private XYModel createModelFrom(LocalDate startDate,
                int[] hoursForEachDay) {
            SimpleXYModel result = new SimpleXYModel();
            for (int i = 0; i < hoursForEachDay.length; i++) {
                result.addValue("series",
                        asMilliseconds(startDate.plusDays(i)),
                        hoursForEachDay[i]);
            }
            return result;
        }

        private long asMilliseconds(LocalDate day) {
            return day.toDateTimeAtStartOfDay().getMillis();
        }
    }

}
TOP

Related Classes of org.libreplan.web.planner.allocation.streches.GraphicForStreches$ForInterpolation

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.