Package org.libreplan.web.limitingresources

Source Code of org.libreplan.web.limitingresources.LimitingResourcesController$LimitingResourceQueueElementsRenderer

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

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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
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.Order;
import org.libreplan.business.planner.entities.GenericResourceAllocation;
import org.libreplan.business.planner.entities.ResourceAllocation;
import org.libreplan.business.planner.entities.SpecificResourceAllocation;
import org.libreplan.business.planner.entities.Task;
import org.libreplan.business.planner.limiting.entities.LimitingResourceQueueDependency;
import org.libreplan.business.planner.limiting.entities.LimitingResourceQueueElement;
import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.resources.entities.LimitingResourceQueue;
import org.libreplan.business.resources.entities.Resource;
import org.libreplan.web.common.Util;
import org.libreplan.web.limitingresources.LimitingResourcesPanel.IToolbarCommand;
import org.libreplan.web.planner.order.BankHolidaysMarker;
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.timetracker.TimeTracker;
import org.zkoss.ganttz.timetracker.zoom.SeveralModificators;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.zk.ui.SuspendNotAllowedException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Button;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Column;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Label;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Row;
import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.Window;
import org.zkoss.zul.api.Rows;

/**
* Controller for limiting resources view
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class LimitingResourcesController extends GenericForwardComposer {

    @Autowired
    private ILimitingResourceQueueModel limitingResourceQueueModel;

    @Autowired
    private IConfigurationDAO configurationDAO;

    @Autowired
    private IAdHocTransactionService transactionService;

    private List<IToolbarCommand> commands = new ArrayList<IToolbarCommand>();

    private LimitingResourcesPanel limitingResourcesPanel;

    private TimeTracker timeTracker;

    private Grid gridUnassignedLimitingResourceQueueElements;

    private Checkbox cbSelectAll;

    private Window manualAllocationWindow;

    private Window editTaskWindow;

    private final LimitingResourceQueueElementsRenderer limitingResourceQueueElementsRenderer =
        new LimitingResourceQueueElementsRenderer();

    public LimitingResourcesController() {
    }

    public void add(IToolbarCommand... commands) {
        Validate.noNullElements(commands);
        this.commands.addAll(Arrays.asList(commands));
    }

    @Override
    public void doAfterCompose(org.zkoss.zk.ui.Component comp) throws Exception {
        super.doAfterCompose(comp);
    }

    public void reload() {
        transactionService.runOnReadOnlyTransaction(new IOnTransaction<Void>() {

            @Override
            public Void execute() {
                reloadInTransaction();
                return null;
            }

            private void reloadInTransaction() {
                // FIXME: Temporary fix, it seems the page was already rendered,
                // so
                // clear it all as it's going to be rendered again
                self.getChildren().clear();

                limitingResourceQueueModel.initGlobalView();

                // Initialize interval
                timeTracker = buildTimeTracker();
                limitingResourcesPanel = buildLimitingResourcesPanel();

                self.appendChild(limitingResourcesPanel);
                limitingResourcesPanel.afterCompose();

                cbSelectAll = (Checkbox) limitingResourcesPanel
                        .getFellowIfAny("cbSelectAll");

                initGridUnassignedLimitingResourceQueueElements();
                initManualAllocationWindow();
                initEditTaskWindow();

                addCommands(limitingResourcesPanel);
            }
        });
    }

    private void initGridUnassignedLimitingResourceQueueElements() {
        gridUnassignedLimitingResourceQueueElements = (Grid) limitingResourcesPanel
                .getFellowIfAny("gridUnassignedLimitingResourceQueueElements");
        gridUnassignedLimitingResourceQueueElements
                .setModel(new SimpleListModel(
                        getUnassignedLimitingResourceQueueElements()));
        gridUnassignedLimitingResourceQueueElements
                .setRowRenderer(getLimitingResourceQueueElementsRenderer());
        getEarlierStartingDateColumn().sort(true, true);
    }

    private Column getEarlierStartingDateColumn() {
        return (Column) gridUnassignedLimitingResourceQueueElements
                .getColumns().getChildren().get(4);
    }

    private void initManualAllocationWindow() {
        manualAllocationWindow = (Window) limitingResourcesPanel.getFellowIfAny("manualAllocationWindow");
        ManualAllocationController manualAllocationController = getManualAllocationController();
        manualAllocationController.setLimitingResourcesController(this);
        manualAllocationController.setLimitingResourcesPanel(limitingResourcesPanel);
    }

    private ManualAllocationController getManualAllocationController() {
        return (ManualAllocationController) manualAllocationWindow.getVariable(
                "manualAllocationController", true);
    }

    private void initEditTaskWindow() {
        editTaskWindow = (Window) limitingResourcesPanel.getFellowIfAny("editTaskWindow");
    }

    public ILimitingResourceQueueModel getLimitingResourceQueueModel() {
        return limitingResourceQueueModel;
    }

    private void addCommands(LimitingResourcesPanel limitingResourcesPanel) {
        limitingResourcesPanel.add(commands
                .toArray(new IToolbarCommand[commands.size()]));
    }

    private TimeTracker buildTimeTracker() {
        return timeTracker = new TimeTracker(limitingResourceQueueModel
                .getViewInterval(), ZoomLevel.DETAIL_THREE,
                SeveralModificators.create(),
                SeveralModificators.create(BankHolidaysMarker.create(getDefaultCalendar())),self);
    }

    private BaseCalendar getDefaultCalendar() {
        return configurationDAO.getConfiguration().getDefaultCalendar();
    }

    private LimitingResourcesPanel buildLimitingResourcesPanel() {
        return new LimitingResourcesPanel(this, timeTracker);
    }

    /**
     * Returns unassigned {@link LimitingResourceQueueElement}
     *
     * It's necessary to convert elements to a DTO that encapsulates properties
     * such as task name or order name, since the only way of sorting by these
     * fields is by having properties getTaskName or getOrderName on the
     * elements returned
     *
     * @return
     */
    public List<LimitingResourceQueueElementDTO> getUnassignedLimitingResourceQueueElements() {
        List<LimitingResourceQueueElementDTO> result = new ArrayList<LimitingResourceQueueElementDTO>();
        for (LimitingResourceQueueElement each : limitingResourceQueueModel
                .getUnassignedLimitingResourceQueueElements()) {
            result.add(toLimitingResourceQueueElementDTO(each));
        }
        return result;
    }

    private LimitingResourceQueueElementDTO toLimitingResourceQueueElementDTO(
            LimitingResourceQueueElement element) {
        final Task task = element.getResourceAllocation().getTask();
        final Order order = limitingResourceQueueModel.getOrderByTask(task);
        return new LimitingResourceQueueElementDTO(element, order
                .getName(), task.getName(), element
                .getEarliestStartDateBecauseOfGantt());
    }

    public static String getResourceOrCriteria(
            ResourceAllocation<?> resourceAllocation) {
        if (resourceAllocation instanceof SpecificResourceAllocation) {
            final Resource resource = ((SpecificResourceAllocation) resourceAllocation)
                    .getResource();
            return (resource != null) ? resource.getName() : "";
        } else if (resourceAllocation instanceof GenericResourceAllocation) {
            GenericResourceAllocation genericAllocation = (GenericResourceAllocation) resourceAllocation;
            return Criterion.getCaptionFor(genericAllocation);
        }
        return StringUtils.EMPTY;
    }

    /**
     * DTO for list of unassigned {@link LimitingResourceQueueElement}
     *
     * Note: this class has a natural ordering that is inconsistent with equals.
     *
     * @author Diego Pino Garcia <dpino@igalia.com>
     *
     */
    public static class LimitingResourceQueueElementDTO implements
            Comparable<LimitingResourceQueueElementDTO> {

        private LimitingResourceQueueElement original;

        private String orderName;

        private String taskName;

        private String date;

        private Integer hoursToAllocate;

        private String resourceOrCriteria;

        public LimitingResourceQueueElementDTO(
                LimitingResourceQueueElement element, String orderName,
                String taskName, Date date) {
            this.original = element;
            this.orderName = orderName;
            this.taskName = taskName;
            this.date = Util.formatDate(date);
            this.hoursToAllocate = element.getIntentedTotalHours();
            this.resourceOrCriteria = LimitingResourcesController
                    .getResourceOrCriteria(element.getResourceAllocation());
        }

        public LimitingResourceQueueElement getOriginal() {
            return original;
        }

        public String getOrderName() {
            return orderName;
        }

        public String getTaskName() {
            return taskName;
        }

        public String getDate() {
            return date;
        }

        public Integer getHoursToAllocate() {
            return (hoursToAllocate != null) ? hoursToAllocate : 0;
        }

        public String getResourceOrCriteria() {
            return resourceOrCriteria;
        }

        @Override
        public int compareTo(LimitingResourceQueueElementDTO dto) {
            return getOriginal().getId().compareTo(dto.getOriginal().getId());
        }

    }

    public void saveQueues() {
        limitingResourceQueueModel.confirm();
        notifyUserThatSavingIsDone();
    }

    private void notifyUserThatSavingIsDone() {
        try {
            Messagebox.show(_("Scheduling saved"), _("Information"), Messagebox.OK,
                    Messagebox.INFORMATION);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public void editResourceAllocation(
            LimitingResourceQueueElement oldElement) {

        try {
            Task task = oldElement.getTask();

            EditTaskController editTaskController = getEditController(editTaskWindow);
            editTaskController.showEditFormResourceAllocationFromLimitingResources(task);

            // New resource allocation or resource allocation modified ?
            if (editTaskController.getStatus() == Messagebox.OK) {

                // Update resource allocation for element
                LimitingResourceQueueElement newElement = copyFrom(oldElement,
                        getQueueElementFrom(task));

                // Replace old limiting resource with new one
                LimitingResourceQueue oldQueue = oldElement.getLimitingResourceQueue();
                List<LimitingResourceQueueElement> modified = limitingResourceQueueModel
                        .replaceLimitingResourceQueueElement(oldElement,
                                newElement);

                // Refresh modified queues
                Set<LimitingResourceQueue> toRefreshQueues = new HashSet<LimitingResourceQueue>();
                toRefreshQueues.addAll(LimitingResourceQueue.queuesOf(modified));
                if (oldQueue != null) {
                    toRefreshQueues.add(oldQueue);
                }
                limitingResourcesPanel.refreshQueues(toRefreshQueues);
            }
        } catch (SuspendNotAllowedException e) {
            e.printStackTrace();
        }
    }

    private LimitingResourceQueueElement getQueueElementFrom(Task task) {
        return task.getResourceAllocation().getLimitingResourceQueueElement();
    }

    /**
     * Copies earliestStartDateBecauseOfGantt and dependencies from source to dest
     *
     * @param source
     * @param dest
     * @return
     */
    private LimitingResourceQueueElement copyFrom(
            LimitingResourceQueueElement source,
            LimitingResourceQueueElement dest) {

        dest.setEarlierStartDateBecauseOfGantt(source
                .getEarliestStartDateBecauseOfGantt());

        for (LimitingResourceQueueDependency each : source
                .getDependenciesAsOrigin()) {
            each.setOrigin(dest);
            dest.add(each);
        }
        for (LimitingResourceQueueDependency each : source
                .getDependenciesAsDestiny()) {
            each.setDestiny(dest);
            dest.add(each);
        }

        return dest;
    }

    private EditTaskController getEditController(Window window) {
        return (EditTaskController) editTaskWindow.getVariable("editController", true);
    }

    public LimitingResourceQueueElementsRenderer getLimitingResourceQueueElementsRenderer() {
        return limitingResourceQueueElementsRenderer;
    }

    private class LimitingResourceQueueElementsRenderer implements RowRenderer {

        @Override
        public void render(Row row, Object data) {
            LimitingResourceQueueElementDTO element = (LimitingResourceQueueElementDTO) data;

            row.setValue(data);

            row.appendChild(automaticQueueing(element));
            row.appendChild(label(element.getOrderName()));
            row.appendChild(label(element.getTaskName()));
            row.appendChild(label(element.getResourceOrCriteria()));
            row.appendChild(label(element.getDate()));
            row.appendChild(label(element.getHoursToAllocate().toString()));
            row.appendChild(operations(element));
        }

        private Hbox operations(LimitingResourceQueueElementDTO element) {
            Hbox hbox = new Hbox();
            hbox.appendChild(editResourceAllocationButton(element));
            hbox.appendChild(automaticButton(element));
            hbox.appendChild(manualButton(element));
            hbox.appendChild(removeButton(element));
            return hbox;
        }

        private Button editResourceAllocationButton(final LimitingResourceQueueElementDTO element) {
            Button result = new Button("", "/common/img/ico_editar1.png");
            result.setHoverImage("/common/img/ico_editar.png");
            result.setSclass("icono");
            result.setTooltiptext(_("Edit queue-based resource element"));
            result.addEventListener(Events.ON_CLICK, new EventListener() {

                @Override
                public void onEvent(Event event) {
                    LimitingResourceQueueElement queueElement = element.getOriginal();

                    editResourceAllocation(queueElement);
                    if (queueElement.getLimitingResourceQueue() == null) {
                        reloadUnassignedLimitingResourceQueueElements();
                    }
                }
            });
            return result;
        }

        private Button manualButton(final LimitingResourceQueueElementDTO element) {
            Button result = new Button();
            result.setLabel(_("Manual"));
            result.setTooltiptext(_("Assign element to queue manually"));
            result.addEventListener(Events.ON_CLICK, new EventListener() {

                @Override
                public void onEvent(Event event) {
                    showManualAllocationWindow(element.getOriginal());
                }
            });
            return result;
        }

        private Button removeButton(final LimitingResourceQueueElementDTO element) {
            Button result = new Button("", "/common/img/ico_borrar1.png");
            result.setHoverImage("/common/img/ico_borrar.png");
            result.setSclass("icono");
            result.setTooltiptext(_("Remove queue-based resource element"));
            result.addEventListener(Events.ON_CLICK, new EventListener() {

                @Override
                public void onEvent(Event event) {
                    removeUnassignedLimitingResourceQueueElement(element);
                }
            });
            return result;
        }

        private void removeUnassignedLimitingResourceQueueElement(
                LimitingResourceQueueElementDTO dto) {

            LimitingResourceQueueElement element = dto.getOriginal();
            limitingResourceQueueModel
                    .removeUnassignedLimitingResourceQueueElement(element);
            reloadUnassignedLimitingResourceQueueElements();
        }

        private Button automaticButton(
                final LimitingResourceQueueElementDTO element) {
            Button result = new Button();
            result.setLabel(_("Automatic"));
            result.setTooltiptext(_("Assign element to queue automatically"));
            result.addEventListener(Events.ON_CLICK, new EventListener() {

                @Override
                public void onEvent(Event event) {
                    assignLimitingResourceQueueElement(element);
                }
            });
            return result;
        }

        private void assignLimitingResourceQueueElement(
                LimitingResourceQueueElementDTO dto) {

            List<LimitingResourceQueueElement> inserted = limitingResourceQueueModel
                    .assignLimitingResourceQueueElement(dto.getOriginal());

            if (inserted.isEmpty()) {
                showErrorMessage(_("Cannot allocate selected element. There is not any queue "
                        + "that matches resource allocation criteria at any interval of time"));
                return;
            }
            limitingResourcesPanel.refreshQueues((LimitingResourceQueue.queuesOf(inserted)));
            reloadUnassignedLimitingResourceQueueElements();
        }

        private Checkbox automaticQueueing(
                final LimitingResourceQueueElementDTO element) {
            Checkbox result = new Checkbox();
            result.setTooltiptext(_("Select for automatic queuing"));
            return result;
        }

        private Label label(String value) {
            return new Label(value);
        }

    }

    public List<LimitingResourceQueue> getLimitingResourceQueues() {
        return limitingResourceQueueModel.getLimitingResourceQueues();
    }

    public void unschedule(QueueTask task) {
        LimitingResourceQueueElement queueElement = task.getLimitingResourceQueueElement();
        LimitingResourceQueue queue = queueElement.getLimitingResourceQueue();

        limitingResourceQueueModel.unschedule(queueElement);
        limitingResourcesPanel.refreshQueue(queue);
        reloadUnassignedLimitingResourceQueueElements();
    }

    public boolean moveTask(LimitingResourceQueueElement element) {
        showManualAllocationWindow(element);
        return getManualAllocationWindowStatus() == Messagebox.OK;
    }

    private void showManualAllocationWindow(LimitingResourceQueueElement element) {
        getManualAllocationController().show(element);
    }

    public int getManualAllocationWindowStatus() {
        Integer status = getManualAllocationController().getStatus();
        return (status != null) ? status.intValue() : -1;
    }

    public void reloadUnassignedLimitingResourceQueueElements() {
        gridUnassignedLimitingResourceQueueElements
                .setModel(new SimpleListModel(getUnassignedLimitingResourceQueueElements()));
    }

    public void selectedAllUnassignedQueueElements() {
        final boolean value = cbSelectAll.isChecked();

        final Rows rows = gridUnassignedLimitingResourceQueueElements.getRows();
        for (Object each: rows.getChildren()) {
            final Row row = (Row) each;
            Checkbox cbAutoQueueing = getAutoQueueing(row);
            cbAutoQueueing.setChecked(value);
        }
    }

    @SuppressWarnings("unchecked")
    private Checkbox getAutoQueueing(Row row) {
        List<Component> children = row.getChildren();
        return (Checkbox) children.get(0);
    }

    public void assignAllSelectedElements() {
        List<LimitingResourceQueueElement> elements = getAllSelectedQueueElements();
        if (!elements.isEmpty()) {
            Set<LimitingResourceQueueElement> inserted = limitingResourceQueueModel
                    .assignLimitingResourceQueueElements(elements);
            clearSelectAllCheckbox();

            if (inserted.isEmpty()) {
                showErrorMessage(_("Cannot allocate selected element. There is not any queue "
                        + "that matches resource allocation criteria at any interval of time"));
                return;
            }
            limitingResourcesPanel.refreshQueues(LimitingResourceQueue.queuesOf(inserted));
            reloadUnassignedLimitingResourceQueueElements();
        }
    }

    private void clearSelectAllCheckbox() {
        cbSelectAll.setChecked(false);
    }

    private List<LimitingResourceQueueElement> getAllSelectedQueueElements() {
        List<LimitingResourceQueueElement> result = new ArrayList<LimitingResourceQueueElement>();

        final Rows rows = gridUnassignedLimitingResourceQueueElements.getRows();
        for (Object each : rows.getChildren()) {
            final Row row = (Row) each;
            Checkbox cbAutoQueueing = getAutoQueueing(row);
            if (cbAutoQueueing.isChecked()) {
                LimitingResourceQueueElementDTO dto = (LimitingResourceQueueElementDTO) row
                        .getValue();
                result.add((LimitingResourceQueueElement) dto.getOriginal());
            }
        }
        return result;
    }

    private void showErrorMessage(String error) {
        try {
            Messagebox.show(error, _("Error"), Messagebox.OK, Messagebox.ERROR);
        } catch (InterruptedException e) {

        }
    }

}
TOP

Related Classes of org.libreplan.web.limitingresources.LimitingResourcesController$LimitingResourceQueueElementsRenderer

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.