Package org.libreplan.web.reports

Source Code of org.libreplan.web.reports.ProjectStatusReportModel

/*
* This file is part of LibrePlan
*
* Copyright (C) 2012 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.reports;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.libreplan.business.labels.daos.ILabelDAO;
import org.libreplan.business.labels.entities.Label;
import org.libreplan.business.orders.daos.IOrderDAO;
import org.libreplan.business.orders.daos.IOrderElementDAO;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.planner.entities.IMoneyCostCalculator;
import org.libreplan.business.reports.dtos.ProjectStatusReportDTO;
import org.libreplan.business.requirements.entities.IndirectCriterionRequirement;
import org.libreplan.business.resources.daos.ICriterionDAO;
import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.scenarios.IScenarioManager;
import org.libreplan.business.users.daos.IOrderAuthorizationDAO;
import org.libreplan.business.workingday.EffortDuration;
import org.libreplan.web.security.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


/**
* Model for Project Status report.
*
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class ProjectStatusReportModel implements IProjectStatusReportModel {

    @Autowired
    private IOrderDAO orderDAO;

    @Autowired
    private ILabelDAO labelDAO;

    @Autowired
    private ICriterionDAO criterionDAO;

    @Autowired
    private IOrderElementDAO orderElementDAO;

    @Autowired
    private IOrderAuthorizationDAO orderAuthorizationDAO;

    @Autowired
    private IScenarioManager scenarioManager;

    @Autowired
    private IMoneyCostCalculator moneyCostCalculator;

    private Set<Label> selectedLabels = new HashSet<Label>();

    private Set<Criterion> selectedCriteria = new HashSet<Criterion>();

    private ProjectStatusReportDTO totalDTO;

    @SuppressWarnings("unchecked")
    @Override
    @Transactional(readOnly = true)
    public List<Order> getOrders() {
        List<Order> result = orderDAO.getOrdersByReadAuthorizationByScenario(
                SecurityUtils.getSessionUserLoginName(),
                scenarioManager.getCurrent());
        Collections.sort(result);
        return result;
    }

    @Override
    @Transactional(readOnly = true)
    public List<ProjectStatusReportDTO> getProjectStatusReportDTOs(Order order) {
        moneyCostCalculator.resetMoneyCostMap();

        List<OrderElement> orderElements;
        if (order != null) {
            orderDAO.reattach(order);
            order.useSchedulingDataFor(scenarioManager.getCurrent());
            orderElements = order.getAllChildren();

            orderElements = filterBySelectedLabels(orderElements);
            orderElements = filterBySelectedCriteria(orderElements);
        } else {
            orderElements = orderElementDAO.findByLabelsAndCriteria(
                    selectedLabels, selectedCriteria);
            for (OrderElement each : orderElements) {
                each.useSchedulingDataFor(orderDAO.loadOrderAvoidingProxyFor(
                        each).getOrderVersionFor(
                        scenarioManager.getCurrent()));
            }

            orderElements = filterByOrderAuthorizations(orderElements);
        }

        List<ProjectStatusReportDTO> dtos = new ArrayList<ProjectStatusReportDTO>();
        for (OrderElement element : orderElements) {
            dtos.add(calculateDTO(element, order == null));
        }

        calculateTotalDTO(order, dtos);

        return dtos;
    }

    private ProjectStatusReportDTO calculateDTO(OrderElement orderElement, boolean appendProjectInName) {
        ProjectStatusReportDTO dto = new ProjectStatusReportDTO(orderElement,
                appendProjectInName ? orderDAO
                        .loadOrderAvoidingProxyFor(orderElement) : null);
        dto.setHoursCost(moneyCostCalculator.getHoursMoneyCost(orderElement));
        dto.setExpensesCost(moneyCostCalculator
                .getExpensesMoneyCost(orderElement));
        dto.setTotalCost(moneyCostCalculator.getTotalMoneyCost(orderElement));

        if (!isNotFilteringByCriteria()) {
            dto = discountChildrenWithInvalidatedCriteria(orderElement, dto);
        }

        dto.calculateMarks();

        return dto;
    }

    private ProjectStatusReportDTO discountChildrenWithInvalidatedCriteria(
            OrderElement orderElement, ProjectStatusReportDTO dto) {
        List<ProjectStatusReportDTO> dtosToDiscount = new ArrayList<ProjectStatusReportDTO>();

        for (OrderElement child : orderElement.getChildren()) {
            for (IndirectCriterionRequirement criterionRequirement : child
                    .getIndirectCriterionRequirement()) {
                if (isCriterionSelected(criterionRequirement.getCriterion()
                        .getCode())) {
                    if (!criterionRequirement.isValid()) {
                        dtosToDiscount.add(calculateDTO(child, false));
                    }
                }
            }
        }

        return discount(dto, dtosToDiscount);
    }

    private ProjectStatusReportDTO discount(ProjectStatusReportDTO originalDto,
            List<ProjectStatusReportDTO> toDiscount) {
        if (toDiscount.isEmpty()) {
            return originalDto;
        }

        EffortDuration estimatedHours = originalDto.getEstimatedHoursAsEffortDuration();
        EffortDuration plannedHours = originalDto.getPlannedHoursAsEffortDuration();
        EffortDuration imputedHours = originalDto.getImputedHoursAsEffortDuration();

        BigDecimal budget = originalDto.getBudget();
        BigDecimal resourcesBudget = originalDto.getResourcesBudget();
        BigDecimal expensesBudget = originalDto.getExpensesBudget();

        BigDecimal hoursCost = originalDto.getHoursCost();
        BigDecimal expensesCost = originalDto.getExpensesCost();
        BigDecimal totalCost = originalDto.getTotalCost();

        for (ProjectStatusReportDTO each : toDiscount) {
            estimatedHours = subtractIfNotNull(estimatedHours,
                    each.getEstimatedHoursAsEffortDuration());
            plannedHours = subtractIfNotNull(plannedHours,
                    each.getPlannedHoursAsEffortDuration());
            imputedHours = subtractIfNotNull(imputedHours,
                    each.getImputedHoursAsEffortDuration());

            resourcesBudget = subtractIfNotNull(budget,
                    each.getResourcesBudget());
            expensesBudget = subtractIfNotNull(budget, each.getExpensesBudget());
            budget = subtractIfNotNull(budget, each.getBudget());

            hoursCost = subtractIfNotNull(hoursCost, each.getHoursCost());
            expensesCost = subtractIfNotNull(expensesCost,
                    each.getExpensesCost());
            totalCost = subtractIfNotNull(totalCost, each.getTotalCost());
        }

        ProjectStatusReportDTO projectStatusReportDTO = new ProjectStatusReportDTO(
                originalDto.getCode(), originalDto.getName(), estimatedHours,
                plannedHours, imputedHours, resourcesBudget, expensesBudget,
                budget, hoursCost, expensesCost,
                totalCost);
        return projectStatusReportDTO;
    }

    public boolean isCriterionSelected(String code) {
        for (Criterion criterion : selectedCriteria) {
            if (criterion.getCode().equals(code)) {
                return true;
            }
        }

        return false;
    }

    private void calculateTotalDTO(Order order,
            List<ProjectStatusReportDTO> dtos) {
        if (isNotFiltering()) {
            totalDTO = calculateDTO(order, false);
        } else {
            EffortDuration estimatedHours = EffortDuration.zero();
            EffortDuration plannedHours = EffortDuration.zero();
            EffortDuration imputedHours = EffortDuration.zero();

            BigDecimal budget = BigDecimal.ZERO.setScale(2);
            BigDecimal hoursBudget = BigDecimal.ZERO.setScale(2);
            BigDecimal expensesBudget = BigDecimal.ZERO.setScale(2);

            BigDecimal hoursCost = BigDecimal.ZERO.setScale(2);
            BigDecimal expensesCost = BigDecimal.ZERO.setScale(2);
            BigDecimal totalCost = BigDecimal.ZERO.setScale(2);

            for (ProjectStatusReportDTO dto : dtos) {
                estimatedHours = addIfNotNull(estimatedHours,
                        dto.getEstimatedHoursAsEffortDuration());
                plannedHours = addIfNotNull(plannedHours,
                        dto.getPlannedHoursAsEffortDuration());
                imputedHours = addIfNotNull(imputedHours,
                        dto.getImputedHoursAsEffortDuration());

                hoursBudget = addIfNotNull(budget, dto.getResourcesBudget());
                expensesBudget = addIfNotNull(budget, dto.getExpensesBudget());
                budget = addIfNotNull(budget, dto.getBudget());

                hoursCost = addIfNotNull(hoursCost, dto.getHoursCost());
                expensesCost = addIfNotNull(expensesCost, dto.getExpensesCost());
                totalCost = addIfNotNull(totalCost, dto.getTotalCost());
            }

            totalDTO = new ProjectStatusReportDTO(estimatedHours, plannedHours,
                    imputedHours, hoursBudget, expensesBudget, budget,
                    hoursCost, expensesCost, totalCost);
            totalDTO.calculateMarks();
        }
    }

    @Override
    public boolean isNotFiltering() {
        return isNotFilteringByLabels() && isNotFilteringByCriteria();
    }

    private boolean isNotFilteringByLabels() {
        return selectedLabels.isEmpty();
    }

    private boolean isNotFilteringByCriteria() {
        return selectedCriteria.isEmpty();
    }

    private List<OrderElement> filterBySelectedLabels(
            List<OrderElement> orderElements) {
        if (isNotFilteringByLabels()) {
            return orderElements;
        }

        List<OrderElement> result = new ArrayList<OrderElement>();
        for (OrderElement orderElement : orderElements) {
            if (orderElement.containsLabels(selectedLabels)) {
                result.add(orderElement);
            }
        }
        return result;
    }

    private List<OrderElement> filterBySelectedCriteria(
            List<OrderElement> orderElements) {
        if (isNotFilteringByCriteria()) {
            return orderElements;
        }

        List<OrderElement> result = new ArrayList<OrderElement>();
        for (OrderElement orderElement : orderElements) {
            if (orderElement.containsCriteria(selectedCriteria)) {
                result.add(orderElement);
            }
        }
        return result;
    }

    private List<OrderElement> filterByOrderAuthorizations(
            List<OrderElement> orderElements) {
        List<Order> orders = getOrders();

        List<OrderElement> result = new ArrayList<OrderElement>();
        for (OrderElement each : orderElements) {
            if (orders.contains(orderDAO.loadOrderAvoidingProxyFor(each))) {
                result.add(each);
            }
        }
        return result;
    }

    private EffortDuration addIfNotNull(EffortDuration total,
            EffortDuration other) {
        if (other == null) {
            return total;
        }
        return total.plus(other);
    }

    private EffortDuration subtractIfNotNull(EffortDuration total,
            EffortDuration other) {
        if (other == null) {
            return total;
        }
        return total.minus(other);
    }

    private BigDecimal addIfNotNull(BigDecimal total, BigDecimal other) {
        if (other == null) {
            return total;
        }
        return total.add(other);
    }

    private BigDecimal subtractIfNotNull(BigDecimal total, BigDecimal other) {
        if (other == null) {
            return total;
        }
        return total.subtract(other);
    }

    @Override
    @Transactional(readOnly = true)
    public BigDecimal getHoursCost(Order order) {
        return moneyCostCalculator.getHoursMoneyCost(order);
    }

    @Override
    @Transactional(readOnly = true)
    public BigDecimal getExpensesCost(Order order) {
        return moneyCostCalculator.getExpensesMoneyCost(order);
    }

    @Override
    @Transactional(readOnly = true)
    public BigDecimal getTotalCost(Order order) {
        return moneyCostCalculator.getTotalMoneyCost(order);
    }

    @Override
    @Transactional(readOnly = true)
    public List<Label> getAllLabels() {
        List<Label> labels = labelDAO.findAll();
        for (Label label : labels) {
            forceLoadLabelType(label);
        }
        return labels;
    }

    private void forceLoadLabelType(Label label) {
        label.getType().getName();
    }

    @Override
    public void addSelectedLabel(Label label) {
        selectedLabels.add(label);
    }

    @Override
    public void removeSelectedLabel(Label label) {
        selectedLabels.remove(label);
    }

    @Override
    public Set<Label> getSelectedLabels() {
        return Collections.unmodifiableSet(selectedLabels);
    }

    @Override
    public ProjectStatusReportDTO getTotalDTO() {
        return totalDTO;
    }

    @Override
    @Transactional(readOnly = true)
    public List<Criterion> getAllCriteria() {
        List<Criterion> criteria = criterionDAO.findAll();
        for (Criterion criterion : criteria) {
            forceLoadCriterionType(criterion);
        }
        return criteria;
    }

    private void forceLoadCriterionType(Criterion criterion) {
        criterion.getType().getName();
    }

    @Override
    public void addSelectedCriterion(Criterion criterion) {
        selectedCriteria.add(criterion);
    }

    @Override
    public void removeSelectedCriterion(Criterion criterion) {
        selectedCriteria.remove(criterion);
    }

    @Override
    public Set<Criterion> getSelectedCriteria() {
        return Collections.unmodifiableSet(selectedCriteria);
    }

}
TOP

Related Classes of org.libreplan.web.reports.ProjectStatusReportModel

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.