/* * 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.util.Date; import java.util.List; import org.joda.time.LocalDate; import org.libreplan.business.common.exceptions.ValidationException; import org.libreplan.business.costcategories.entities.CostCategory; import org.libreplan.business.costcategories.entities.ResourcesCostCategoryAssignment; import org.libreplan.business.resources.entities.Resource; import org.libreplan.web.common.ConstraintChecker; import org.libreplan.web.common.Util; import org.libreplan.web.common.components.Autocomplete; import org.libreplan.web.util.ValidationExceptionPrinter; import org.zkoss.zk.ui.Component; 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.zkplus.spring.SpringUtil; import org.zkoss.zul.Button; import org.zkoss.zul.Comboitem; import org.zkoss.zul.Datebox; import org.zkoss.zul.Grid; import org.zkoss.zul.Messagebox; import org.zkoss.zul.Row; import org.zkoss.zul.RowRenderer; /** * Controller for CRUD actions over a {@link ResourcesCostCategoryAssignment}. * * @author Jacobo Aragunde Perez <jaragunde@igalia.com> */ @SuppressWarnings("serial") public class ResourcesCostCategoryAssignmentController extends GenericForwardComposer { private IResourcesCostCategoryAssignmentModel resourcesCostCategoryAssignmentModel; private CostCategoryAssignmentRenderer costCategoryAssignmentRenderer = new CostCategoryAssignmentRenderer(); private Grid listResourcesCostCategoryAssignments; @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); if ( resourcesCostCategoryAssignmentModel == null ) { resourcesCostCategoryAssignmentModel = (IResourcesCostCategoryAssignmentModel) SpringUtil.getBean("resourcesCostCategoryAssignmentModel"); } comp.setAttribute("assignmentController", this, true); this.listResourcesCostCategoryAssignments = (Grid) comp.getFellowIfAny("listResourcesCostCategoryAssignments"); } public void addCostCategory() { resourcesCostCategoryAssignmentModel.addCostCategory(); Util.reloadBindings(listResourcesCostCategoryAssignments); } public List<ResourcesCostCategoryAssignment> getCostCategoryAssignments() { return resourcesCostCategoryAssignmentModel.getCostCategoryAssignments(); } private void removeCostCategoryAssignment(ResourcesCostCategoryAssignment assignment) { resourcesCostCategoryAssignmentModel.removeCostCategoryAssignment(assignment); Util.reloadBindings(listResourcesCostCategoryAssignments); } private CostCategory getCostCategory(Row listitem) { ResourcesCostCategoryAssignment assignment = listitem.getValue(); return assignment.getCostCategory(); } /** * Append a Autocomplete @{link CostCategory} to row. * * @param row */ private void appendAutocompleteType(final Row row) { final Autocomplete autocomplete = new Autocomplete(); autocomplete.setAutodrop(true); autocomplete.applyProperties(); autocomplete.setFinder("CostCategoryFinder"); autocomplete.setConstraint("no empty:" + _("A category must be selected")); // Getter, show type selected if (getCostCategory(row) != null) { autocomplete.setSelectedItem(getCostCategory(row)); } // Setter, set type selected to HourCost.type autocomplete.addEventListener("onSelect", new EventListener() { @Override public void onEvent(Event event) { final Comboitem comboitem = autocomplete.getSelectedItem(); if (comboitem != null) { // Update resourcesCostCategoryAssignment ResourcesCostCategoryAssignment assignment = row.getValue(); assignment.setCostCategory(comboitem.getValue()); row.setValue(assignment); } } }); row.appendChild(autocomplete); } public void confirmRemove(ResourcesCostCategoryAssignment assignment) { int status = Messagebox.show( _("Confirm deleting this hour cost. Are you sure?"), _("Delete"), Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION); if (Messagebox.OK == status) { removeCostCategoryAssignment(assignment); } } /** * 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(row.getValue()); } }); row.appendChild(delete); } /** * Append a Datebox "init date" to row. * * @param row */ private void appendDateboxInitDate(final Row row) { Datebox initDateBox = new Datebox(); bindDateboxInitDate(initDateBox, 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 = ((ResourcesCostCategoryAssignment)row.getValue()).getInitDate(); Datebox endDateBox = (Datebox) row.getChildren().get(2); 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 ResourcesCostCategoryAssignment}. * * @param dateBoxInitDate * @param assignment */ private void bindDateboxInitDate(final Datebox dateBoxInitDate, final ResourcesCostCategoryAssignment assignment) { Util.bind( dateBoxInitDate, new Util.Getter<Date>() { @Override public Date get() { LocalDate dateTime = assignment.getInitDate(); /* TODO resolve deprecated */ return dateTime != null ? new Date(dateTime.getYear() - 1900, dateTime.getMonthOfYear() - 1, dateTime.getDayOfMonth()) : null; } }, new Util.Setter<Date>() { @Override public void set(Date value) { if (value != null) { /* TODO resolve deprecated */ assignment.setInitDate(new LocalDate(value.getYear() + 1900, value.getMonth() + 1,value.getDate())); } else { assignment.setInitDate(null); } } }); } /** * Append a Datebox "end date" to row. * * @param row */ private void appendDateboxEndDate(Row row) { Datebox endDateBox = new Datebox(); bindDateboxEndDate(endDateBox, row.getValue()); LocalDate initDate = ((ResourcesCostCategoryAssignment)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 ResourcesCostCategoryAssignment}. * * @param dateBoxEndDate * @param assignment */ private void bindDateboxEndDate(final Datebox dateBoxEndDate, final ResourcesCostCategoryAssignment assignment) { Util.bind( dateBoxEndDate, new Util.Getter<Date>() { @Override public Date get() { LocalDate dateTime = assignment.getEndDate(); /* TODO resolve deprecated */ return dateTime != null ? new Date(dateTime.getYear() - 1900, dateTime.getMonthOfYear() - 1,dateTime.getDayOfMonth()) : null; } }, new Util.Setter<Date>() { @Override public void set(Date value) { if (value != null) { /* TODO resolve deprecated */ assignment.setEndDate(new LocalDate(value.getYear() + 1900, value.getMonth() + 1, value.getDate())); } else { assignment.setEndDate(null); } } }); } public CostCategoryAssignmentRenderer getCostCategoryAssignmentsRenderer() { return costCategoryAssignmentRenderer; } /** * RowRenderer for a @{HourCost} element. * * @author Jacobo Aragunde Perez <jaragunde@igalia.com> * */ private class CostCategoryAssignmentRenderer implements RowRenderer { @Override public void render(Row row, Object data, int i) { ResourcesCostCategoryAssignment assignment = (ResourcesCostCategoryAssignment) data; row.setValue(assignment); // Create boxes appendAutocompleteType(row); appendDateboxInitDate(row); appendDateboxEndDate(row); appendDeleteButton(row); } } public void setResource(Resource resource) { resourcesCostCategoryAssignmentModel.setResource(resource); Util.reloadBindings(listResourcesCostCategoryAssignments); } public void validateConstraints() { ConstraintChecker.isValid(self); } /** * Check there are not category assignment overlaps. * * @return boolean */ public boolean validate() { List<ResourcesCostCategoryAssignment> costCategoryAssignments = resourcesCostCategoryAssignmentModel.getCostCategoryAssignments(); try { CostCategory.validateCostCategoryOverlapping(costCategoryAssignments); } catch (ValidationException e) { ValidationExceptionPrinter.showAt(listResourcesCostCategoryAssignments, e); } return true; } }