Package org.libreplan.web.costcategories

Source Code of org.libreplan.web.costcategories.CostCategoryCRUDController$HourCostListRenderer

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

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

import java.math.BigDecimal;
import java.util.ConcurrentModificationException;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.LogFactory;
import org.joda.time.LocalDate;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.common.exceptions.ValidationException;
import org.libreplan.business.costcategories.entities.CostCategory;
import org.libreplan.business.costcategories.entities.HourCost;
import org.libreplan.business.costcategories.entities.TypeOfWorkHours;
import org.libreplan.web.common.BaseCRUDController;
import org.libreplan.web.common.Level;
import org.libreplan.web.common.Util;
import org.libreplan.web.workreports.WorkReportCRUDController;
import org.zkoss.ganttz.util.ComponentsFinder;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.CheckEvent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Button;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Decimalbox;
import org.zkoss.zul.Grid;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Row;
import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.Rows;
import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.api.Hbox;

/**
* Controller for CRUD actions over a {@link CostCategory}
*
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
@SuppressWarnings("serial")
public class CostCategoryCRUDController extends BaseCRUDController<CostCategory> {

    private static final org.apache.commons.logging.Log LOG = LogFactory.getLog(WorkReportCRUDController.class);

    private ICostCategoryModel costCategoryModel;

    private Grid listHourCosts;

    private Grid listCostCategories;

    private ListModel allHoursType;

    private HourCostListRenderer hourCostListRenderer = new HourCostListRenderer();

    @Override
    public void doAfterCompose(Component comp) throws Exception {
        super.doAfterCompose(comp);
        listHourCosts = (Grid) editWindow.getFellowIfAny("listHourCosts");
        listCostCategories = (Grid) listWindow.getFellowIfAny("listing");

        // Renders grid and disables delete button in case it cannot be removed
        listCostCategories.addEventListener("onInitRender", new EventListener() {

            @Override
                    public void onEvent(Event event) {
                listCostCategories.renderAll();

                final Rows rows = listCostCategories.getRows();
                for (Iterator i = rows.getChildren().iterator(); i.hasNext(); ) {
                    final Row row = (Row) i.next();
                    final CostCategory category = (CostCategory) row.getValue();
                    Button btnDelete = (Button) ((Hbox)row.getChildren().get(2)).getChildren().get(1);
                    if (!canRemoveCostCategory(category)) {
                        btnDelete.setDisabled(true);
                        btnDelete.setImage("/common/img/ico_borrar_out.png");
                        btnDelete.setHoverImage("/common/img/ico_borrar_out.png");
                    }
                }
            }
        });
        initializeHoursType();
    }

    private void initializeHoursType() {
        allHoursType = new SimpleListModel(costCategoryModel.getAllHoursType());
    }

    @Override
    protected void save() throws ValidationException{
        costCategoryModel.confirmSave();
    }

    @Override
    protected void beforeSaving() throws ValidationException {
        costCategoryModel.validateHourCostsOverlap();
    }

    private void showInvalidValues(ValidationException e) {
        Object value = e.getInvalidValue().getRootBean();
        if (value instanceof HourCost) {
            showInvalidValue((HourCost) value);
        }
        messagesForUser.showInvalidValues(e);
    }

    private void showInvalidValue(HourCost hourCost) {
        Row row = ComponentsFinder.findRowByValue(listHourCosts, hourCost);
        if (row != null) {
            if (hourCost.getType() == null) {
                Listbox workHoursType = getWorkHoursType(row);
                String message = workHoursType.getItems().isEmpty() ? _("Hours types are empty. Please, create some hours types before proceeding")
                        : _("cannot be empty");
                throw new WrongValueException(getWorkHoursType(row), message);
            }
            if (hourCost.getPriceCost() == null) {
                throw new WrongValueException(getPricePerHour(row), _("cannot be empty"));
            }
        }
    }

    private Listbox getWorkHoursType(Row row) {
        return (Listbox) row.getChildren().get(1);
    }

    private Component getPricePerHour(Row row) {
        return (Component) row.getChildren().get(2);
    }

    public CostCategory getCostCategory() {
        return costCategoryModel.getCostCategory();
    }

    public List<CostCategory> getCostCategories() {
        return costCategoryModel.getCostCategories();
    }

    public Set<HourCost> getHourCosts() {
        return costCategoryModel.getHourCosts();
    }


    private TypeOfWorkHours getTypeOfWorkHours(Row listitem) {
        HourCost hourCost = (HourCost) listitem.getValue();
        return hourCost.getType();
    }

    /**
     * Append a textbox @{link code} to row
     * @param row
     */
    private void appendTextboxCode(final Row row) {
        final HourCost hourCost = ((HourCost) row.getValue());
        final Textbox txtCode = new Textbox();
        txtCode.setWidth("200px");
        if (hourCost != null) {
            CostCategory costCategory = hourCost.getCategory();
            txtCode.setDisabled(costCategory.isCodeAutogenerated());
            Util.bind(txtCode, new Util.Getter<String>() {
                @Override
                public String get() {
                    return hourCost.getCode();
                }
            }, new Util.Setter<String>() {

                @Override
                public void set(String value) {
                    hourCost.setCode(value);
                }
            });

            if (!hourCost.getCategory().isCodeAutogenerated()) {
                txtCode.setConstraint("no empty:"
                        + _("cannot be empty"));
            } else {
                txtCode.setConstraint("");
            }
        }
        row.appendChild(txtCode);
    }

    /**
     * Append Selectbox of @{link TypeOfWorkHours} to row
     *
     * @param row
     */
    private void appendHoursType(final Row row) {
        final HourCost hourCost = (HourCost) row.getValue();
        final Listbox lbHoursType = new Listbox();
        lbHoursType.setMold("select");
        lbHoursType.setModel(allHoursType);
        lbHoursType.renderAll();
        lbHoursType.applyProperties();

        if (lbHoursType.getItems().isEmpty()) {
            row.appendChild(lbHoursType);
            return;
        }

        // First time is rendered, select first item
        TypeOfWorkHours type = hourCost.getType();
        if (hourCost.isNewObject() && type == null) {
            Listitem item = lbHoursType.getItemAtIndex(0);
            item.setSelected(true);
            setHoursType(hourCost, item);
        } else {
            // If hoursCost has a type, select item with that type
            Listitem item = ComponentsFinder.findItemByValue(lbHoursType, type);
            if (item != null) {
                lbHoursType.selectItem(item);
            }
        }

        lbHoursType.addEventListener(Events.ON_SELECT, new EventListener() {

            @Override
            public void onEvent(Event event) {
                Listitem item = lbHoursType.getSelectedItem();
                if (item != null) {
                    setHoursType((HourCost) row.getValue(), item);
                }
            }

        });

        row.appendChild(lbHoursType);
    }

    private void setHoursType(HourCost hourCost, Listitem item) {
        TypeOfWorkHours value = item != null ? (TypeOfWorkHours) item
                .getValue() : null;
        hourCost.setType(value);
        if (value != null) {
            final BigDecimal defaultPrice = value.getDefaultPrice();
            final Decimalbox dbPricePerHour = (Decimalbox) item.getParent().getNextSibling();
            hourCost.setPriceCost(defaultPrice);
            if (dbPricePerHour != null) {
                dbPricePerHour.setValue(defaultPrice);
            }
        } else if (item != null) {
            hourCost.setPriceCost(BigDecimal.ZERO);
            throw new WrongValueException(item.getParent(),
                    _("Please, select an item"));
        }
    }

    /**
     * Append a delete {@link Button} to {@link Row}
     *
     * @param row
     */
    private void appendDeleteButton(final Row row) {
        Button delete = new Button("", "/common/img/ico_borrar1.png");
        delete.setHoverImage("/common/img/ico_borrar.png");
        delete.setSclass("icono");
        delete.setTooltiptext(_("Delete"));
        delete.addEventListener(Events.ON_CLICK, new EventListener() {
            @Override
            public void onEvent(Event event) {
                confirmRemove((HourCost) row.getValue());
            }
        });
        row.appendChild(delete);
    }

    /**
     * Append a Textbox "hour cost" to row
     *
     * @param row
     */
    private void appendDecimalboxCost(Row row) {
        Decimalbox boxCost = new Decimalbox();
        bindDecimalboxCost(boxCost, (HourCost) row.getValue());
        boxCost.setConstraint("no empty:" + _("cannot be empty"));
        boxCost.setFormat(Util.getMoneyFormat());
        row.appendChild(boxCost);
    }

    /**
     * Binds Decimalbox "hour cost" to the corresponding attribute of a {@link HourCost}
     *
     * @param boxCost
     * @param hourCost
     */
    private void bindDecimalboxCost(final Decimalbox boxCost,
            final HourCost hourCost) {
        Util.bind(boxCost, new Util.Getter<BigDecimal>() {

            @Override
            public BigDecimal get() {
                if (hourCost.getPriceCost() != null) {
                    return hourCost.getPriceCost();
                }
                return new BigDecimal(0);
            }

        }, new Util.Setter<BigDecimal>() {

            @Override
            public void set(BigDecimal value) {
                hourCost.setPriceCost(value);
            }
        });
    }

    /**
     * Append a Datebox "init date" to row
     *
     * @param row
     */
    private void appendDateboxInitDate(final Row row) {
        Datebox initDateBox = new Datebox();
        bindDateboxInitDate(initDateBox, (HourCost) row.getValue());
        initDateBox.setConstraint("no empty:" + _("Start date cannot be empty"));
        row.appendChild(initDateBox);

        initDateBox.addEventListener("onChange", new EventListener() {

            @Override
            public void onEvent(Event event) {
                // Updates the constraint of the endDate box with the new date
                LocalDate initDate = ((HourCost)row.getValue()).getInitDate();
                Datebox endDateBox = (Datebox) row.getChildren().get(4);
                endDateBox.setConstraint("after " +
                        String.format("%04d", initDate.getYear()) +
                        String.format("%02d", initDate.getMonthOfYear()) +
                        String.format("%02d", initDate.getDayOfMonth()));
            }
        });
    }

    /**
     * Binds Datebox "init date" to the corresponding attribute of a {@link HourCost}
     *
     * @param dateBoxInitDate
     * @param hourCost
     */
    private void bindDateboxInitDate(final Datebox dateBoxInitDate,
            final HourCost hourCost) {
        Util.bind(dateBoxInitDate, new Util.Getter<Date>() {

            @Override
            public Date get() {
                LocalDate dateTime = hourCost.getInitDate();
                if (dateTime != null) {
                    return new Date(dateTime.getYear()-1900,
                            dateTime.getMonthOfYear()-1,dateTime.getDayOfMonth());
                } else {
                    Date now = new Date();
                    hourCost.setInitDate(new LocalDate(now));
                    return now;
                }
            }

        }, new Util.Setter<Date>() {

            @Override
            public void set(Date value) {
                if (value != null) {
                    hourCost.setInitDate(new LocalDate(value.getYear()+1900,
                            value.getMonth()+1,value.getDate()));
                }
                else {
                    hourCost.setInitDate(null);
                }
            }
        });
    }

    /**
     * Append a Datebox "end date" to row
     *
     * @param row
     */
    private void appendDateboxEndDate(Row row) {
        Datebox endDateBox = new Datebox();
        bindDateboxEndDate(endDateBox, (HourCost) row.getValue());
        LocalDate initDate = ((HourCost)row.getValue()).getInitDate();
        if (initDate != null) {
            endDateBox.setConstraint("after " +
                    String.format("%04d", initDate.getYear()) +
                    String.format("%02d", initDate.getMonthOfYear()) +
                    String.format("%02d", initDate.getDayOfMonth()));
        }
        row.appendChild(endDateBox);
    }

    /**
     * Binds Datebox "init date" to the corresponding attribute of a {@link HourCost}
     *
     * @param dateBoxInitDate
     * @param hourCost
     */
    private void bindDateboxEndDate(final Datebox dateBoxEndDate,
            final HourCost hourCost) {
        Util.bind(dateBoxEndDate, new Util.Getter<Date>() {

            @Override
            public Date get() {
                LocalDate dateTime = hourCost.getEndDate();
                if (dateTime != null) {
                    return new Date(dateTime.getYear()-1900,
                            dateTime.getMonthOfYear()-1,dateTime.getDayOfMonth());
                }
                return null;
            }

        }, new Util.Setter<Date>() {

            @Override
            public void set(Date value) {
                if (value != null) {
                    hourCost.setEndDate(new LocalDate(value.getYear()+1900,
                            value.getMonth()+1,value.getDate()));
                }
                else {
                    hourCost.setEndDate(null);
                }
            }
        });
    }

    public void confirmRemove(HourCost hourCost) {
        try {
            int status = Messagebox.show(_("Confirm deleting this hour cost. Are you sure?"), _("Delete"),
                    Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION);
            if (Messagebox.OK == status) {
                removeHourCost(hourCost);
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public HourCostListRenderer getRenderer() {
        return hourCostListRenderer;
    }

    /**
     * Adds a new {@link HourCost} to the list of rows
     *
     * @param rows
     */
    public void addHourCost() {
        costCategoryModel.addHourCost();
        Util.reloadBindings(listHourCosts);
    }

    public void removeHourCost(HourCost hourCost) {
        costCategoryModel.removeHourCost(hourCost);
        Util.reloadBindings(listHourCosts);
    }

    /**
     * RowRenderer for a @{HourCost} element
     *
     * @author Jacobo Aragunde Perez <jaragunde@igalia.com>
     *
     */
    public class HourCostListRenderer implements RowRenderer {

        @Override
        public void render(Row row, Object data) {
            HourCost hourCost = (HourCost) data;

            row.setValue(hourCost);

            // Create boxes
            appendTextboxCode(row);
            appendHoursType(row);
            appendDecimalboxCost(row);
            appendDateboxInitDate(row);
            appendDateboxEndDate(row);

            appendDeleteButton(row);
        }
    }

    public void onCheckGenerateCode(Event e) {
        CheckEvent ce = (CheckEvent) e;
        if (ce.isChecked()) {
            // we have to auto-generate the code for new objects
            try {
                costCategoryModel.setCodeAutogenerated(ce.isChecked());
            } catch (ConcurrentModificationException err) {
                messagesForUser.showMessage(Level.ERROR, err.getMessage());
            }
        }
        Util.reloadBindings(listCostCategories);
        Util.reloadBindings(listHourCosts);
    }

    @Override
    protected String getEntityType() {
        return _("Cost Category");
    }

    @Override
    protected String getPluralEntityType() {
        return _("Cost Categories");
    }

    @Override
    protected void initCreate() {
        costCategoryModel.initCreate();
    }

    @Override
    protected void initEdit(CostCategory costCategory) {
        costCategoryModel.initEdit(costCategory);
    }

    @Override
    protected CostCategory getEntityBeingEdited() {
        return costCategoryModel.getCostCategory();
    }

    @Override
    protected void delete(CostCategory category) throws InstanceNotFoundException{
        costCategoryModel.confirmRemoveCostCategory(category);
        Util.reloadBindings(listCostCategories);
    }

    protected boolean beforeDeleting(CostCategory category) {
        return costCategoryModel.canRemoveCostCategory(category);
    }

    public boolean canRemoveCostCategory(CostCategory category) {
        return costCategoryModel.canRemoveCostCategory(category);
    }

}
TOP

Related Classes of org.libreplan.web.costcategories.CostCategoryCRUDController$HourCostListRenderer

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.