/*
* This file is part of LibrePlan
*
* Copyright (C) 2010-2011 Wireless Galicia, S.L.
* Copyright (C) 2011-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.orders;
import static org.libreplan.web.I18nHelper._;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.joda.time.LocalDate;
import org.libreplan.business.calendars.entities.BaseCalendar;
import org.libreplan.business.externalcompanies.entities.ExternalCompany;
import org.libreplan.business.orders.daos.IOrderDAO;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.templates.entities.OrderTemplate;
import org.libreplan.web.common.ConstraintChecker;
import org.libreplan.web.common.Util;
import org.libreplan.web.common.components.bandboxsearch.BandboxSearch;
import org.libreplan.web.planner.tabs.MultipleTabsPlannerController;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.SuspendNotAllowedException;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zkplus.spring.SpringUtil;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.ComboitemRenderer;
import org.zkoss.zul.Constraint;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;
/**
* Controller for the creation of an {@link Order} with its principal properties.
*
* @author Susana Montes Pedreira <smontes@wirelessgailicia.com>
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
* @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/
public class ProjectDetailsController extends GenericForwardComposer<Component> {
private OrderCRUDController orderController;
private Grid gridProjectDetails;
private BaseCalendar defaultCalendar;
private boolean isCodeAutogeneratedInit;
private MultipleTabsPlannerController tabs;
private Window window;
private Datebox initDate;
private BandboxSearch bdProjectTemplate;
private Textbox txtName;
private Datebox deadline;
private Checkbox generateCode;
private IOrderDAO orderDAO;
private OrderTemplate template;
public ProjectDetailsController() {
Window window = (Window)
Executions.createComponents("/orders/_projectDetails.zul", null, new HashMap<String, String>());
try {
doAfterCompose(window);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
orderDAO = (IOrderDAO) SpringUtil.getBean("orderDAO");
window = (Window) comp;
window.setAttribute("projectController", this, true);
}
public void showWindow(OrderCRUDController orderController, MultipleTabsPlannerController tabs) {
this.tabs = tabs;
this.orderController = orderController;
this.defaultCalendar = orderController.getOrder().getCalendar();
this.isCodeAutogeneratedInit = orderController.getOrder().isCodeAutogenerated();
try {
Util.reloadBindings(window);
Util.createBindingsFor(gridProjectDetails);
Util.reloadBindings(gridProjectDetails);
window.doModal();
} catch (SuspendNotAllowedException e) {
throw new RuntimeException(e);
}
}
public void cancel() {
clearProperties();
close();
}
public void accept() {
if ( validate() ) {
Desktop desktop = window.getDesktop();
IOrderModel orderModel = orderController.getOrderModel();
if ( bdProjectTemplate.getSelectedElement() != null ) {
OrderTemplate template = (OrderTemplate) bdProjectTemplate.getSelectedElement();
orderModel.prepareCreationFrom(template, desktop);
} else {
orderModel.initEdit(orderController.getOrder(), desktop);
}
if ( tabs != null ) {
tabs.goToOrderDetails(orderController.getOrder());
}
orderModel.save();
orderController.editNewCreatedOrder(window);
}
}
private boolean validate() {
ConstraintChecker.isValid(window);
if ( initDate.getValue() == null ) {
showWrongValue();
return false;
}
if ( orderDAO.existsByNameAnotherTransaction(txtName.getValue()) ) {
showWrongName();
return false;
}
return true;
}
private void showWrongValue() {
throw new WrongValueException(initDate, _("cannot be empty"));
}
private void showWrongName() {
throw new WrongValueException(txtName, _("project name already being used"));
}
private void close() {
window.setVisible(false);
}
public Order getOrder() {
return orderController.getOrder();
}
public String getTest(){
return orderController.getOrder().getCode();
}
public boolean isCodeAutogenerated() {
return orderController.isCodeAutogenerated();
}
public void setCodeAutogenerated(boolean codeAutogenerated) {
orderController.setCodeAutogeneratedInModel(codeAutogenerated);
Util.reloadBindings(gridProjectDetails);
}
public List<ExternalCompany> getExternalCompaniesAreClient() {
return orderController.getExternalCompaniesAreClient();
}
public List<BaseCalendar> getBaseCalendars() {
return orderController.getBaseCalendars();
}
public ComboitemRenderer getBaseCalendarsComboitemRenderer() {
return orderController.getBaseCalendarsComboitemRenderer();
}
public void setBaseCalendar(BaseCalendar calendar) {
orderController.setBaseCalendar(calendar);
}
private void clearProperties() {
Order order = orderController.getOrder();
order.setName(null);
// Reset the code autogenerated property
if (isCodeAutogeneratedInit) {
order.setCodeAutogenerated(true);
} else {
order.setCodeAutogenerated(false);
order.setCode("");
}
order.setCustomer(null);
order.setDeadline(null);
order.setInitDate(new Date());
order.setCalendar(defaultCalendar);
}
public Constraint getCheckConstraintFinishDate() {
return (comp, value) -> {
Date finishDate = (Date) value;
boolean deadlineBeforeStart = (finishDate != null) &&
(initDate.getValue() != null) &&
(finishDate.compareTo(initDate.getValue()) < 0);
if ( deadlineBeforeStart ) {
deadline.setValue(null);
getOrder().setDeadline(null);
throw new WrongValueException(comp, _("must be after start date"));
}
};
}
public Constraint checkConstraintStartDate() {
return (comp, value) -> {
Date startDate = (Date) value;
boolean startAfterDeadline = (startDate != null) &&
(deadline.getValue() != null) &&
(startDate.compareTo(deadline.getValue()) > 0);
if ( startAfterDeadline ) {
initDate.setValue(null);
getOrder().setInitDate(null);
throw new WrongValueException(comp, _("must be lower than end date"));
}
Date year2010 = new Date(1262296800000L);
boolean startBefore2010 = (startDate != null) && startDate.before(year2010);
if ( startBefore2010 ) {
initDate.setValue(null);
getOrder().setInitDate(null);
throw new WrongValueException(comp, _("Must be after 2010!"));
}
};
}
private void calculateProjectDates(OrderTemplate template) {
LocalDate initLocalDate = new LocalDate().plusDays(template.getStartAsDaysFromBeginning());
Date initDate = initLocalDate.toDateTimeAtStartOfDay().toDate();
getOrder().setInitDate(initDate);
this.initDate.setValue(initDate);
if (template.getDeadlineAsDaysFromBeginning() != null ) {
LocalDate deadlineLocalDate = initLocalDate.plusDays(template.getDeadlineAsDaysFromBeginning());
Date deadline = deadlineLocalDate.toDateTimeAtStartOfDay().toDate();
getOrder().setDeadline(deadline);
this.deadline.setValue(deadline);
} else {
getOrder().setDeadline(null);
this.deadline.setValue(null);
}
}
public OrderTemplate getTemplate() {
return template;
}
public void setTemplate(OrderTemplate template) {
this.template = template;
if (template == null) {
generateCode.setDisabled(false);
generateCode.setTooltiptext("");
} else {
if (!isCodeAutogenerated()) {
setCodeAutogenerated(true);
}
generateCode.setDisabled(true);
generateCode.setTooltiptext(_("Set Code as autogenerated to create a new project from templates"));
generateCode.setChecked(true);
calculateProjectDates(template);
setCalendarFromTemplate(template);
}
}
private void setCalendarFromTemplate(OrderTemplate template) {
BaseCalendar calendar = template.getCalendar();
for (BaseCalendar each : getBaseCalendars()) {
if (calendar.getId().equals(each.getId())) {
setBaseCalendar(each);
return;
}
}
}
}