org.libreplan.web.planner.order.OrderPlanningController.java Source code

Java tutorial

Introduction

Here is the source code for org.libreplan.web.planner.order.OrderPlanningController.java

Source

/*
 * This file is part of LibrePlan
 *
 * Copyright (C) 2009-2010 Fundacin para o Fomento da Calidade Industrial e
 *                         Desenvolvemento Tecnolxico de Galicia
 * Copyright (C) 2010-2013 Igalia, S.L.
 * Copyright (C) 2010-2011 WirelessGalicia 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.order;

import static org.libreplan.web.I18nHelper._;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.Validate;
import org.apache.commons.logging.Log;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.planner.entities.TaskElement;
import org.libreplan.web.common.FilterUtils;
import org.libreplan.web.common.ViewSwitcher;
import org.libreplan.web.common.components.bandboxsearch.BandboxMultipleSearch;
import org.libreplan.web.common.components.finders.FilterPair;
import org.libreplan.web.orders.OrderCRUDController;
import org.libreplan.web.planner.TaskElementPredicate;
import org.libreplan.web.planner.advances.AdvanceAssignmentPlanningController;
import org.libreplan.web.planner.calendar.CalendarAllocationController;
import org.libreplan.web.planner.consolidations.AdvanceConsolidationController;
import org.libreplan.web.planner.taskedition.AdvancedAllocationTaskController;
import org.libreplan.web.planner.taskedition.EditTaskController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.zkoss.ganttz.FilterAndParentExpandedPredicates;
import org.zkoss.ganttz.Planner;
import org.zkoss.ganttz.data.Task;
import org.zkoss.ganttz.extensions.ContextWithPlannerTask;
import org.zkoss.ganttz.extensions.ICommand;
import org.zkoss.ganttz.extensions.IContext;
import org.zkoss.ganttz.extensions.IContextWithPlannerTask;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.ganttz.util.LongOperationFeedback;
import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation;
import org.zkoss.ganttz.util.ProfilingLogFactory;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.util.Composer;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Constraint;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Popup;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Vbox;

/**
 * @author scar Gonzlez Fernndez <ogonzalez@igalia.com>
 * @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
 * @author Lorenzo Tilve ?lvaro <ltilve@igalia.com>
 */
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class OrderPlanningController implements Composer {

    private static final Log PROFILING_LOG = ProfilingLogFactory.getLog(OrderPlanningController.class);

    @Autowired
    private ViewSwitcher viewSwitcher;

    private Map<String, String[]> parameters;

    @Autowired
    private IOrderPlanningModel model;

    private Planner planner;

    @Autowired
    private CalendarAllocationController calendarAllocationController;

    @Autowired
    private EditTaskController editTaskController;

    @Autowired
    private AdvancedAllocationTaskController advancedAllocationTaskController;

    @Autowired
    private AdvanceConsolidationController advanceConsolidationController;

    @Autowired
    private AdvanceAssignmentPlanningController advanceAssignmentPlanningController;

    @Autowired
    private OrderCRUDController orderCRUDController;

    private GenericForwardComposer currentControllerToShow;

    private Order order;

    private TaskElement task;

    private List<ICommand<TaskElement>> additional = new ArrayList<>();

    private Vbox orderElementFilter;

    private Datebox filterStartDateOrderElement;

    private Datebox filterFinishDateOrderElement;

    private Checkbox labelsWithoutInheritance;

    private BandboxMultipleSearch bdFiltersOrderElement;

    private Textbox filterNameOrderElement;

    private Popup filterOptionsPopup;

    public OrderPlanningController() {

    }

    public List getCriticalPath() {
        return planner != null ? planner.getCriticalPath() : null;
    }

    @SafeVarargs
    public final void setOrder(Order order, ICommand<TaskElement>... additionalCommands) {
        Validate.notNull(additionalCommands);
        Validate.noNullElements(additionalCommands);
        this.order = order;
        this.additional = Arrays.asList(additionalCommands);
        if (planner != null) {
            ensureIsInPlanningOrderView();
            updateConfiguration();
            planner.setTaskListPredicate(getFilterAndParentExpanedPredicates(createPredicate()));
        }
    }

    public void setShowedTask(TaskElement task) {
        this.task = task;
    }

    public CalendarAllocationController getCalendarAllocationController() {
        return calendarAllocationController;
    }

    private void ensureIsInPlanningOrderView() {
        viewSwitcher.goToPlanningOrderView();
    }

    public ViewSwitcher getViewSwitcher() {
        return viewSwitcher;
    }

    @Override
    public void doAfterCompose(org.zkoss.zk.ui.Component comp) {
        this.planner = (Planner) comp;
        String zoomLevelParameter = null;
        if ((parameters != null) && (parameters.get("zoom") != null) && !(parameters.isEmpty())) {
            zoomLevelParameter = parameters.get("zoom")[0];
        }
        if (zoomLevelParameter != null) {
            planner.setInitialZoomLevel(ZoomLevel.getFromString(zoomLevelParameter));
        }
        planner.setAreContainersExpandedByDefault(Planner.guessContainersExpandedByDefault(parameters));

        planner.setAreShownAdvancesByDefault(Planner.guessShowAdvancesByDefault(parameters));

        planner.setAreShownReportedHoursByDefault(Planner.guessShowReportedHoursByDefault(parameters));
        planner.setAreShownMoneyCostBarByDefault(Planner.guessShowMoneyCostBarByDefault(parameters));

        orderElementFilter = (Vbox) planner.getFellow("orderElementFilter");
        // Configuration of the order filter
        org.zkoss.zk.ui.Component filterComponent = Executions.createComponents(
                "/orders/_orderElementTreeFilter.zul", orderElementFilter, new HashMap<String, String>());
        filterComponent.setAttribute("treeController", this, true);
        filterOptionsPopup = (Popup) filterComponent.getFellow("filterOptionsPopup");
        filterStartDateOrderElement = (Datebox) filterOptionsPopup.getFellow("filterStartDateOrderElement");
        filterFinishDateOrderElement = (Datebox) filterOptionsPopup.getFellow("filterFinishDateOrderElement");
        labelsWithoutInheritance = (Checkbox) filterOptionsPopup.getFellow("labelsWithoutInheritance");
        bdFiltersOrderElement = (BandboxMultipleSearch) filterComponent.getFellow("bdFiltersOrderElement");
        bdFiltersOrderElement.setFinder("taskElementsMultipleFiltersFinder");
        filterNameOrderElement = (Textbox) filterComponent.getFellow("filterNameOrderElement");
        filterComponent.setVisible(true);
        updateConfiguration();
    }

    private void updateConfiguration() {
        if (order != null) {
            importOrderFiltersFromSession();

            long time = System.currentTimeMillis();
            model.setConfigurationToPlanner(planner, order, viewSwitcher, editTaskController,
                    advancedAllocationTaskController, advanceAssignmentPlanningController,
                    advanceConsolidationController, calendarAllocationController, additional);
            PROFILING_LOG.debug("setConfigurationToPlanner took: " + (System.currentTimeMillis() - time) + " ms");
            planner.updateSelectedZoomLevel();
            showResorceAllocationIfIsNeeded();

        }
    }

    private void importOrderFiltersFromSession() {
        importOrderFiltersFromSession(false);
    }

    private void importOrderFiltersFromSession(boolean forceReload) {
        filterNameOrderElement.setValue(FilterUtils.readOrderTaskName(order));
        filterStartDateOrderElement.setValue(FilterUtils.readOrderStartDate(order));
        filterFinishDateOrderElement.setValue(FilterUtils.readOrderEndDate(order));
        List<FilterPair> sessionFilterPairs = FilterUtils.readOrderParameters(order);
        if ((sessionFilterPairs != null)
                && (bdFiltersOrderElement.getSelectedElements().isEmpty() || forceReload)) {
            bdFiltersOrderElement.addSelectedElements(sessionFilterPairs);
        }
        if (FilterUtils.readOrderInheritance(order) != null) {
            labelsWithoutInheritance.setChecked(FilterUtils.readOrderInheritance(order));
        }
    }

    public EditTaskController getEditTaskController() {
        return editTaskController;
    }

    public AdvancedAllocationTaskController getAdvancedAllocationTaskController() {
        return advancedAllocationTaskController;
    }

    public OrderCRUDController getOrderCRUDController() {
        return orderCRUDController;
    }

    public void setURLParameters(Map<String, String[]> parameters) {
        this.parameters = parameters;
    }

    public Order getOrder() {
        return model.getOrder();
    }

    public void onApplyFilter() {
        filterByPredicate(createPredicate());
        List<FilterPair> listFilters = (List<FilterPair>) bdFiltersOrderElement.getSelectedElements();
        FilterUtils.writeOrderParameters(order, listFilters);
    }

    private TaskElementPredicate createPredicate() {

        if (FilterUtils.hasOrderWBSFiltersChanged(order)) {
            importOrderFiltersFromSession(true);
            FilterUtils.writeOrderWBSFiltersChanged(order, false);
        }

        List<FilterPair> listFilters = (List<FilterPair>) bdFiltersOrderElement.getSelectedElements();
        Date startDate = filterStartDateOrderElement.getValue();
        Date finishDate = filterFinishDateOrderElement.getValue();
        boolean ignoreLabelsInheritance = labelsWithoutInheritance.isChecked();
        String name = filterNameOrderElement.getValue();

        if (listFilters.isEmpty() && startDate == null && finishDate == null && name == null) {
            return null;
        }
        FilterUtils.writeOrderTaskName(order, name);
        FilterUtils.writeOrderStartDate(order, startDate);
        FilterUtils.writeOrderEndDate(order, finishDate);
        FilterUtils.writeOrderInheritance(order, ignoreLabelsInheritance);
        return new TaskElementPredicate(listFilters, startDate, finishDate, name, ignoreLabelsInheritance);
    }

    public Checkbox getLabelsWithoutInheritance() {
        return labelsWithoutInheritance;
    }

    public void setLabelsWithoutInheritance(Checkbox labelsWithoutInheritance) {
        this.labelsWithoutInheritance = labelsWithoutInheritance;
    }

    private void filterByPredicate(final TaskElementPredicate predicate) {
        LongOperationFeedback.execute(orderElementFilter, new ILongOperation() {

            @Override
            public void doAction() {
                // FIXME remove or change
                model.forceLoadLabelsAndCriterionRequirements();
                planner.setTaskListPredicate(getFilterAndParentExpanedPredicates(predicate));
            }

            @Override
            public String getName() {
                return _("filtering");
            }

        });
    }

    private FilterAndParentExpandedPredicates getFilterAndParentExpanedPredicates(
            final TaskElementPredicate predicate) {
        final IContext<?> context = planner.getContext();
        FilterAndParentExpandedPredicates newPredicate = new FilterAndParentExpandedPredicates(context) {
            @Override
            public boolean accpetsFilterPredicate(Task task) {
                if (predicate == null) {
                    return true;
                }
                TaskElement taskElement = (TaskElement) context.getMapper().findAssociatedDomainObject(task);
                return predicate.accepts(taskElement);
            }

        };
        newPredicate.setFilterContainers(planner.getPredicate().isFilterContainers());

        return newPredicate;
    }

    public Constraint checkConstraintFinishDate() {
        return new Constraint() {
            @Override
            public void validate(org.zkoss.zk.ui.Component comp, Object value) throws WrongValueException {
                Date finishDate = (Date) value;
                if ((finishDate != null) && (filterStartDateOrderElement.getValue() != null)
                        && (finishDate.compareTo(filterStartDateOrderElement.getValue()) < 0)) {

                    filterFinishDateOrderElement.setRawValue(null);
                    throw new WrongValueException(comp, _("must be after start date"));
                }
            }

        };
    }

    public Constraint checkConstraintStartDate() {
        return new Constraint() {
            @Override
            public void validate(org.zkoss.zk.ui.Component comp, Object value) throws WrongValueException {
                Date startDate = (Date) value;
                if ((startDate != null) && (filterFinishDateOrderElement.getValue() != null)
                        && (startDate.compareTo(filterFinishDateOrderElement.getValue()) > 0)) {

                    filterStartDateOrderElement.setRawValue(null);
                    throw new WrongValueException(comp, _("must be lower than end date"));
                }
            }
        };
    }

    private void showResorceAllocationIfIsNeeded() {
        if ((task != null) && (planner != null)) {

            planner.expandAllAlways();

            Task foundTask = null;
            TaskElement foundTaskElement = null;
            IContext<TaskElement> context = (IContext<TaskElement>) planner.getContext();
            Map<TaskElement, Task> map = context.getMapper().getMapDomainToTask();

            for (Entry<TaskElement, Task> entry : map.entrySet()) {
                if (task.getId().equals(entry.getKey().getId())) {
                    foundTaskElement = entry.getKey();
                    foundTask = entry.getValue();
                }
            }

            if ((foundTask != null) && (foundTaskElement != null)) {
                IContextWithPlannerTask<TaskElement> contextTask = ContextWithPlannerTask.create(context,
                        foundTask);

                if (this.getCurrentControllerToShow().equals(getEditTaskController())) {

                    this.editTaskController.showEditFormResourceAllocation(contextTask, foundTaskElement,
                            model.getPlanningState());

                } else if (this.getCurrentControllerToShow()
                        .equals(this.getAdvanceAssignmentPlanningController())) {

                    getAdvanceAssignmentPlanningController().showWindow(contextTask, foundTaskElement,
                            model.getPlanningState());
                }
            }
        }
    }

    public AdvanceConsolidationController getAdvanceConsolidationController() {
        return advanceConsolidationController;
    }

    public AdvanceAssignmentPlanningController getAdvanceAssignmentPlanningController() {
        return advanceAssignmentPlanningController;
    }

    public void setCurrentControllerToShow(GenericForwardComposer currentControllerToShow) {
        this.currentControllerToShow = currentControllerToShow;
    }

    private GenericForwardComposer getCurrentControllerToShow() {
        return currentControllerToShow;
    }

}