/*
* 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-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.resources.worker;
import static org.libreplan.web.I18nHelper._;
import java.util.ConcurrentModificationException;
import java.util.Date;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.LocalDate;
import org.libreplan.business.calendars.entities.BaseCalendar;
import org.libreplan.business.calendars.entities.ResourceCalendar;
import org.libreplan.business.common.entities.Limits;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.common.exceptions.ValidationException;
import org.libreplan.business.resources.daos.IResourceDAO;
import org.libreplan.business.resources.entities.ResourceType;
import org.libreplan.business.resources.entities.VirtualWorker;
import org.libreplan.business.resources.entities.Worker;
import org.libreplan.business.users.entities.User;
import org.libreplan.business.users.entities.UserRole;
import org.libreplan.web.calendars.BaseCalendarEditionController;
import org.libreplan.web.calendars.IBaseCalendarModel;
import org.libreplan.web.common.ConstraintChecker;
import org.libreplan.web.common.IMessagesForUser;
import org.libreplan.web.common.Level;
import org.libreplan.web.common.MessagesForUser;
import org.libreplan.web.common.OnlyOneVisible;
import org.libreplan.web.common.Util;
import org.libreplan.web.common.ILimitsModel;
import org.libreplan.web.common.BaseCRUDController.CRUDControllerState;
import org.libreplan.web.common.components.bandboxsearch.BandboxMultipleSearch;
import org.libreplan.web.common.components.bandboxsearch.BandboxSearch;
import org.libreplan.web.common.entrypoints.EntryPointsHandler;
import org.libreplan.web.common.entrypoints.IURLHandlerRegistry;
import org.libreplan.web.costcategories.ResourcesCostCategoryAssignmentController;
import org.libreplan.web.resources.search.ResourcePredicate;
import org.libreplan.web.security.SecurityUtils;
import org.libreplan.web.users.IUserCRUDController;
import org.libreplan.web.users.services.IDBPasswordEncoderService;
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.Events;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zkplus.spring.SpringUtil;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.ComboitemRenderer;
import org.zkoss.zul.Constraint;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Label;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Radio;
import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.Tab;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Caption;
import org.zkoss.zul.Groupbox;
import org.zkoss.zul.Radiogroup;
import org.zkoss.zul.Window;
import org.zkoss.zul.Bandbox;
/**
* Controller for {@link Worker} resource.
* <br />
*
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/
public class WorkerCRUDController extends GenericForwardComposer implements IWorkerCRUDControllerEntryPoints {
private IDBPasswordEncoderService dbPasswordEncoderService;
private ILimitsModel limitsModel;
private IWorkerModel workerModel;
private IResourceDAO resourceDAO;
private IUserCRUDController userCRUD;
private Window listWindow;
private Window editWindow;
private IURLHandlerRegistry URLHandlerRegistry;
private OnlyOneVisible visibility;
private IMessagesForUser messages;
private Component messagesContainer;
private CriterionsController criterionsController;
private LocalizationsController localizationsForEditionController;
private LocalizationsController localizationsForCreationController;
private ResourcesCostCategoryAssignmentController resourcesCostCategoryAssignmentController;
private IWorkerCRUDControllerEntryPoints workerCRUD;
private Window editCalendarWindow;
private BaseCalendarEditionController baseCalendarEditionController;
private IBaseCalendarModel resourceCalendarModel;
private Window createNewVersionWindow;
private BaseCalendarsComboitemRenderer baseCalendarsComboitemRenderer = new BaseCalendarsComboitemRenderer();
private Grid listing;
private Datebox filterStartDate;
private Datebox filterFinishDate;
private Listbox filterLimitingResource;
private BandboxMultipleSearch bdFilters;
private Textbox txtfilter;
private Tab personalDataTab;
private Tab assignedCriteriaTab;
private Tab costCategoryAssignmentTab;
private CRUDControllerState state = CRUDControllerState.LIST;
private Groupbox userBindingGroupbox;
private Radiogroup userBindingRadiogroup;
private BandboxSearch userBandbox;
private Textbox loginNameTextbox;
private Textbox emailTextbox;
private Textbox passwordTextbox;
private Textbox passwordConfirmationTextbox;
private enum UserBindingOption {
NOT_BOUND(_("Not bound")),
EXISTING_USER(_("Existing user")),
CREATE_NEW_USER(_("Create new user"));
private String label;
UserBindingOption(String label) {
this.label = label;
}
/**
* Helper function to mark text to be translated.
*/
private static String _(String text) {
return text;
}
}
public WorkerCRUDController() {
workerCRUD = (IWorkerCRUDControllerEntryPoints) SpringUtil.getBean("workerCRUD");
userCRUD = (IUserCRUDController) SpringUtil.getBean("userCRUD");
}
public WorkerCRUDController(Window listWindow,
Window editWindow,
Window editCalendarWindow,
IWorkerModel workerModel,
IMessagesForUser messages,
IWorkerCRUDControllerEntryPoints workerCRUD) {
this.listWindow = listWindow;
this.editWindow = editWindow;
this.workerModel = workerModel;
this.messages = messages;
this.workerCRUD = workerCRUD;
this.editCalendarWindow = editCalendarWindow;
}
public Worker getWorker() {
return workerModel.getWorker();
}
public List<Worker> getWorkers() {
return workerModel.getWorkers();
}
public List<Worker> getRealWorkers() {
return workerModel.getRealWorkers();
}
public List<Worker> getVirtualWorkers() {
return workerModel.getVirtualWorkers();
}
public LocalizationsController getLocalizations() {
if (workerModel.isCreating()) {
return localizationsForCreationController;
}
return localizationsForEditionController;
}
public void saveAndExit() {
if (save()) {
goToList();
}
}
public void saveAndContinue() {
if (save()) {
if (!getWorker().isVirtual()) {
goToEditForm(getWorker());
} else {
this.goToEditVirtualWorkerForm(getWorker());
}
}
}
public boolean save() {
validateConstraints();
setUserBindingInfo();
// Validate 'Cost category assignment' tab is correct
if (resourcesCostCategoryAssignmentController != null) {
if (!resourcesCostCategoryAssignmentController.validate()) {
return false;
}
}
try {
if (baseCalendarEditionController != null) {
baseCalendarEditionController.save();
}
if ( criterionsController != null && !criterionsController.validate() ) {
return false;
}
if (workerModel.getCalendar() == null) {
createCalendar();
}
workerModel.save();
messages.showMessage(Level.INFO, _("Worker saved"));
return true;
} catch (ValidationException e) {
messages.showInvalidValues(e);
}
return false;
}
private void setUserBindingInfo() {
int option = userBindingRadiogroup.getSelectedIndex();
if (UserBindingOption.NOT_BOUND.ordinal() == option) {
getWorker().setUser(null);
}
if (UserBindingOption.EXISTING_USER.ordinal() == option) {
if (getWorker().getUser() == null) {
throw new WrongValueException(userBandbox, _("please select a user to bound"));
}
getWorker().updateUserData();
}
if (UserBindingOption.CREATE_NEW_USER.ordinal() == option) {
getWorker().setUser(createNewUserForBinding());
}
}
private User createNewUserForBinding() {
String loginName = loginNameTextbox.getValue();
if (StringUtils.isBlank(loginName)) {
throw new WrongValueException(loginNameTextbox, _("cannot be empty"));
}
String password = passwordTextbox.getValue();
if (StringUtils.isBlank(loginName)) {
throw new WrongValueException(passwordTextbox, _("cannot be empty"));
}
String passwordConfirmation = passwordConfirmationTextbox.getValue();
if (!password.equals(passwordConfirmation)) {
throw new WrongValueException(passwordConfirmationTextbox, _("passwords do not match"));
}
String encodedPassword = dbPasswordEncoderService.encodePassword(password, loginName);
User newUser = User.create(loginName, encodedPassword, emailTextbox.getValue());
Worker worker = getWorker();
newUser.setFirstName(worker.getFirstName());
newUser.setLastName(worker.getSurname());
return newUser;
}
private void validateConstraints() {
Tab selectedTab = personalDataTab;
try {
validatePersonalDataTab();
selectedTab = assignedCriteriaTab;
validateAssignedCriteriaTab();
selectedTab = costCategoryAssignmentTab;
validateCostCategoryAssignmentTab();
} catch (WrongValueException e) {
selectedTab.setSelected(true);
throw e;
}
}
private void validatePersonalDataTab() {
ConstraintChecker.isValid(editWindow.getFellowIfAny("personalDataTabpanel"));
}
private void validateAssignedCriteriaTab() {
criterionsController.validateConstraints();
}
private void validateCostCategoryAssignmentTab() {
resourcesCostCategoryAssignmentController.validateConstraints();
}
public void cancel() {
goToList();
}
@Override
public void goToList() {
state = CRUDControllerState.LIST;
getVisibility().showOnly(listWindow);
Util.reloadBindings(listWindow);
}
@Override
public void goToEditForm(Worker worker) {
state = CRUDControllerState.EDIT;
getBookmarker().goToEditForm(worker);
workerModel.prepareEditFor(worker);
resourcesCostCategoryAssignmentController.setResource(workerModel.getWorker());
if (isCalendarNotNull()) {
editCalendar();
}
editAssignedCriterions();
updateUserBindingComponents();
showEditWindow(_("Edit Worker: {0}", worker.getHumanId()));
Textbox workerFirstname = (Textbox) editWindow.getFellow("workerFirstname");
workerFirstname.focus();
}
private void updateUserBindingComponents() {
User user = getBoundUser();
if (user == null) {
userBindingRadiogroup.setSelectedIndex(UserBindingOption.NOT_BOUND.ordinal());
} else {
userBindingRadiogroup.setSelectedIndex(UserBindingOption.EXISTING_USER.ordinal());
}
// Reset new user fields
loginNameTextbox.setValue("");
emailTextbox.setValue("");
passwordTextbox.setValue("");
passwordConfirmationTextbox.setValue("");
Util.reloadBindings(userBindingGroupbox);
}
public void goToEditVirtualWorkerForm(Worker worker) {
state = CRUDControllerState.EDIT;
workerModel.prepareEditFor(worker);
resourcesCostCategoryAssignmentController.setResource(workerModel.getWorker());
if (isCalendarNotNull()) {
editCalendar();
}
editAssignedCriterions();
showEditWindow(_("Edit Virtual Workers Group: {0}", worker.getHumanId()));
}
public void goToEditForm() {
state = CRUDControllerState.EDIT;
if (isCalendarNotNull()) {
editCalendar();
}
showEditWindow(_("Edit Worker: {0}", getWorker().getHumanId()));
}
@Override
public void goToCreateForm() {
state = CRUDControllerState.CREATE;
getBookmarker().goToCreateForm();
workerModel.prepareForCreate();
createAssignedCriterions();
resourcesCostCategoryAssignmentController.setResource(workerModel.getWorker());
updateUserBindingComponents();
showEditWindow(_("Create Worker"));
resourceCalendarModel.cancel();
Textbox workerFirstname = (Textbox) editWindow.getFellow("workerFirstname");
workerFirstname.focus();
}
private void showEditWindow(String title) {
personalDataTab.setSelected(true);
((Caption) editWindow.getFellow("caption")).setLabel(title);
getVisibility().showOnly(editWindow);
Util.reloadBindings(editWindow);
}
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
workerModel = (IWorkerModel) SpringUtil.getBean("workerModel");
dbPasswordEncoderService = (IDBPasswordEncoderService) SpringUtil.getBean("dbPasswordEncoderService");
limitsModel = (ILimitsModel) SpringUtil.getBean("limitsModel");
resourceDAO = (IResourceDAO) SpringUtil.getBean("resourceDAO");
URLHandlerRegistry = (IURLHandlerRegistry) SpringUtil.getBean("URLHandlerRegistry");
resourceCalendarModel = (IBaseCalendarModel) SpringUtil.getBean("resourceCalendarModel");
localizationsForEditionController = createLocalizationsController(comp, "editWindow");
localizationsForCreationController = createLocalizationsController(comp, "editWindow");
comp.setAttribute("controller", this, true);
if (messagesContainer == null) {
throw new RuntimeException(_("MessagesContainer is needed"));
}
messages = new MessagesForUser(messagesContainer);
setupResourcesCostCategoryAssignmentController();
getVisibility().showOnly(listWindow);
initFilterComponent();
setupFilterLimitingResourceListbox();
initializeTabs();
initUserBindingComponents();
setWidthOfUserBandBoxSearch();
final EntryPointsHandler<IWorkerCRUDControllerEntryPoints> handler =
URLHandlerRegistry.getRedirectorFor(IWorkerCRUDControllerEntryPoints.class);
handler.register(this, page);
}
private void initUserBindingComponents() {
userBindingGroupbox = (Groupbox) editWindow.getFellowIfAny("userBindingGroupbox");
userBindingRadiogroup = (Radiogroup) editWindow.getFellowIfAny("userBindingRadiogroup");
initUserBindingOptions();
userBandbox = (BandboxSearch) editWindow.getFellowIfAny("userBandbox");
loginNameTextbox = (Textbox) editWindow.getFellowIfAny("loginName");
passwordTextbox = (Textbox) editWindow.getFellowIfAny("password");
passwordConfirmationTextbox = (Textbox) editWindow.getFellowIfAny("passwordConfirmation");
emailTextbox = (Textbox) editWindow.getFellowIfAny("email");
}
private void initUserBindingOptions() {
UserBindingOption[] values = UserBindingOption.values();
for (UserBindingOption option : values) {
Radio radio = new Radio(_(option.label));
if ( option.equals(UserBindingOption.CREATE_NEW_USER) &&
!SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_USER_ACCOUNTS) ) {
radio.setDisabled(true);
radio.setTooltiptext(_("You do not have permissions to create new users"));
}
userBindingRadiogroup.appendChild(radio);
}
}
private void setWidthOfUserBandBoxSearch() {
Bandbox userBandboxComponent = (Bandbox) this.userBandbox.getChildren().get(1);
userBandboxComponent.setWidth("300px");
Listbox userListbox = (Listbox)
userBandbox.getChildren().get(1).getChildren().get(0).getChildren().get(0).getChildren().get(0);
userListbox.setWidth("300px");
}
private void initializeTabs() {
personalDataTab = (Tab) editWindow.getFellow("personalDataTab");
assignedCriteriaTab = (Tab) editWindow.getFellow("assignedCriteriaTab");
costCategoryAssignmentTab = (Tab) editWindow.getFellow("costCategoryAssignmentTab");
}
private void initFilterComponent() {
this.filterFinishDate = (Datebox) listWindow.getFellowIfAny("filterFinishDate");
this.filterStartDate = (Datebox) listWindow.getFellowIfAny("filterStartDate");
this.filterLimitingResource = (Listbox) listWindow.getFellowIfAny("filterLimitingResource");
this.bdFilters = (BandboxMultipleSearch) listWindow.getFellowIfAny("bdFilters");
this.txtfilter = (Textbox) listWindow.getFellowIfAny("txtfilter");
this.listing = (Grid) listWindow.getFellowIfAny("listing");
clearFilterDates();
}
private void setupResourcesCostCategoryAssignmentController() {
Component costCategoryAssignmentContainer = editWindow.getFellowIfAny("costCategoryAssignmentContainer");
resourcesCostCategoryAssignmentController = (ResourcesCostCategoryAssignmentController)
costCategoryAssignmentContainer.getAttribute("assignmentController", true);
}
private void editAssignedCriterions() {
try {
setupCriterionsController();
criterionsController.prepareForEdit(workerModel.getWorker());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void createAssignedCriterions() {
try {
setupCriterionsController();
criterionsController.prepareForCreate(workerModel.getWorker());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void setupCriterionsController() throws Exception {
criterionsController = new CriterionsController(workerModel);
criterionsController.doAfterCompose(getCurrentWindow().getFellow("criterionsContainer"));
}
public BaseCalendarEditionController getEditionController() {
return baseCalendarEditionController;
}
private LocalizationsController createLocalizationsController(Component comp,
String localizationsContainerName) throws Exception {
LocalizationsController localizationsController = new LocalizationsController(workerModel);
localizationsController
.doAfterCompose(comp.getFellow(localizationsContainerName).getFellow("localizationsContainer"));
return localizationsController;
}
private OnlyOneVisible getVisibility() {
if (visibility == null) {
visibility = new OnlyOneVisible(listWindow, editWindow);
}
return visibility;
}
private IWorkerCRUDControllerEntryPoints getBookmarker() {
return workerCRUD;
}
public List<BaseCalendar> getBaseCalendars() {
return workerModel.getBaseCalendars();
}
public boolean isCalendarNull() {
return workerModel.getCalendar() == null;
}
public boolean isCalendarNotNull() {
return !isCalendarNull();
}
private void createCalendar() {
Combobox combobox = (Combobox) getCurrentWindow().getFellow("createDerivedCalendar");
Comboitem selectedItem = combobox.getSelectedItem();
if (selectedItem == null) {
throw new WrongValueException(combobox, "You should select one calendar");
}
BaseCalendar parentCalendar = combobox.getSelectedItem().getValue();
if (parentCalendar == null) {
parentCalendar = workerModel.getDefaultCalendar();
}
resourceCalendarModel.initCreateDerived(parentCalendar);
resourceCalendarModel.generateCalendarCodes();
workerModel.setCalendar((ResourceCalendar) resourceCalendarModel.getBaseCalendar());
}
private void editCalendar() {
updateCalendarController();
resourceCalendarModel.initEdit(workerModel.getCalendar());
try {
baseCalendarEditionController.doAfterCompose(editCalendarWindow);
} catch (Exception e) {
throw new RuntimeException(e);
}
baseCalendarEditionController.setSelectedDay(new LocalDate());
Util.reloadBindings(editCalendarWindow);
Util.reloadBindings(createNewVersionWindow);
}
public BaseCalendarEditionController getBaseCalendarEditionController() {
return baseCalendarEditionController;
}
private void reloadCurrentWindow() {
Util.reloadBindings(getCurrentWindow());
}
private Window getCurrentWindow() {
return editWindow;
}
private void updateCalendarController() {
editCalendarWindow = (Window) getCurrentWindow().getFellow("editCalendarWindow");
createNewVersionWindow = (Window) getCurrentWindow().getFellow("createNewVersion");
createNewVersionWindow.setVisible(true);
createNewVersionWindow.setVisible(false);
baseCalendarEditionController = new BaseCalendarEditionController(
resourceCalendarModel,
editCalendarWindow,
createNewVersionWindow,
messages) {
@Override
public void goToList() {
workerModel.setCalendar((ResourceCalendar) resourceCalendarModel.getBaseCalendar());
reloadCurrentWindow();
}
@Override
public void cancel() {
workerModel.removeCalendar();
resourceCalendarModel.cancel();
reloadCurrentWindow();
}
@Override
public void save() {
validateCalendarExceptionCodes();
ResourceCalendar calendar = (ResourceCalendar) resourceCalendarModel.getBaseCalendar();
if (calendar != null) {
resourceCalendarModel.generateCalendarCodes();
workerModel.setCalendar(calendar);
}
reloadCurrentWindow();
}
@Override
public void saveAndContinue() {
save();
}
};
editCalendarWindow.setAttribute("calendarController", this, true);
createNewVersionWindow.setAttribute("calendarController", this, true);
}
public BaseCalendarsComboitemRenderer getBaseCalendarsComboitemRenderer() {
return baseCalendarsComboitemRenderer;
}
private class BaseCalendarsComboitemRenderer implements ComboitemRenderer {
@Override
public void render(Comboitem comboitem, Object o, int i) throws Exception {
BaseCalendar calendar = (BaseCalendar) o;
comboitem.setLabel(calendar.getName());
comboitem.setValue(calendar);
if (isDefaultCalendar(calendar)) {
Combobox combobox = (Combobox) comboitem.getParent();
combobox.setSelectedItem(comboitem);
}
}
private boolean isDefaultCalendar(BaseCalendar calendar) {
BaseCalendar defaultCalendar = workerModel.getDefaultCalendar();
return defaultCalendar.getId().equals(calendar.getId());
}
}
public void goToCreateVirtualWorkerForm() {
state = CRUDControllerState.CREATE;
workerModel.prepareForCreate(true);
createAssignedCriterions();
resourcesCostCategoryAssignmentController.setResource(workerModel.getWorker());
showEditWindow(_("Create Virtual Workers Group"));
resourceCalendarModel.cancel();
}
public boolean isVirtualWorker() {
boolean isVirtual = false;
if ( this.workerModel != null && this.workerModel.getWorker() != null ) {
if (this.workerModel.getWorker() != null) {
isVirtual = this.workerModel.getWorker().isVirtual();
}
}
return isVirtual;
}
public boolean isRealWorker() {
return !isVirtualWorker();
}
public String getVirtualWorkerObservations() {
if (isVirtualWorker()) {
return ((VirtualWorker) this.workerModel.getWorker()).getObservations();
} else {
return "";
}
}
public void setVirtualWorkerObservations(String observations) {
if (isVirtualWorker()) {
((VirtualWorker) this.workerModel.getWorker()).setObservations(observations);
}
}
/**
* Operations to filter the machines by multiple filters
*/
public Constraint checkConstraintFinishDate() {
return (comp, value) -> {
Date finishDate = (Date) value;
if ( (finishDate != null) && (filterStartDate.getValue() != null) &&
(finishDate.compareTo(filterStartDate.getValue()) < 0) ) {
filterFinishDate.setValue(null);
throw new WrongValueException(comp, _("must be after start date"));
}
};
}
public Constraint checkConstraintStartDate() {
return (comp, value) -> {
Date startDate = (Date) value;
if ( (startDate != null) && (filterFinishDate.getValue() != null) && (
startDate.compareTo(filterFinishDate.getValue()) > 0) ) {
filterStartDate.setValue(null);
throw new WrongValueException(comp, _("must be lower than end date"));
}
};
}
public void onApplyFilter() {
ResourcePredicate predicate = createPredicate();
if (predicate != null) {
filterByPredicate(predicate);
} else {
showAllWorkers();
}
}
private ResourcePredicate createPredicate() {
List listFilters = bdFilters.getSelectedElements();
String personalFilter = txtfilter.getValue();
// Get the dates filter
LocalDate startDate = null;
LocalDate finishDate = null;
if (filterStartDate.getValue() != null) {
startDate = LocalDate.fromDateFields(filterStartDate.getValue());
}
if (filterFinishDate.getValue() != null) {
finishDate = LocalDate.fromDateFields(filterFinishDate.getValue());
}
final Listitem item = filterLimitingResource.getSelectedItem();
Boolean isLimitingResource = (item != null)
? LimitingResourceEnum.valueOf((LimitingResourceEnum) item.getValue()) : null;
if ( listFilters.isEmpty() && (personalFilter == null || personalFilter.isEmpty()) &&
startDate == null && finishDate == null && isLimitingResource == null ) {
return null;
}
return new ResourcePredicate(listFilters, personalFilter, startDate, finishDate, isLimitingResource);
}
private void filterByPredicate(ResourcePredicate predicate) {
List<Worker> filteredResources = workerModel.getFilteredWorker(predicate);
listing.setModel(new SimpleListModel<>(filteredResources.toArray()));
listing.invalidate();
}
private void clearFilterDates() {
filterStartDate.setValue(null);
filterFinishDate.setValue(null);
}
public void showAllWorkers() {
listing.setModel(new SimpleListModel<>(workerModel.getAllCurrentWorkers().toArray()));
listing.invalidate();
}
public enum LimitingResourceEnum {
ALL(_("All")),
LIMITING_RESOURCE(_("Queue-based resource")),
NON_LIMITING_RESOURCE(_("Normal resource"));
private String option;
LimitingResourceEnum(String option) {
this.option = option;
}
@Override
public String toString() {
return _(option);
}
public static LimitingResourceEnum valueOf(Boolean isLimitingResource) {
return Boolean.TRUE.equals(isLimitingResource) ? LIMITING_RESOURCE : NON_LIMITING_RESOURCE;
}
public static Boolean valueOf(LimitingResourceEnum option) {
if (LIMITING_RESOURCE.equals(option))
return true;
else if (NON_LIMITING_RESOURCE.equals(option))
return false;
else return null;
}
public static Set<LimitingResourceEnum> getLimitingResourceOptionList() {
return EnumSet.of(LimitingResourceEnum.LIMITING_RESOURCE, LimitingResourceEnum.NON_LIMITING_RESOURCE);
}
public static Set<LimitingResourceEnum> getLimitingResourceFilterOptionList() {
return EnumSet.of(LimitingResourceEnum.ALL, LimitingResourceEnum.LIMITING_RESOURCE, LimitingResourceEnum.NON_LIMITING_RESOURCE);
}
public static ResourceType toResourceType(LimitingResourceEnum limitingResource) {
if (LIMITING_RESOURCE.equals(limitingResource)) {
return ResourceType.LIMITING_RESOURCE;
}
return ResourceType.NON_LIMITING_RESOURCE;
}
}
private void setupFilterLimitingResourceListbox() {
for (LimitingResourceEnum resourceEnum : LimitingResourceEnum.getLimitingResourceFilterOptionList()) {
Listitem item = new Listitem();
item.setParent(filterLimitingResource);
item.setValue(resourceEnum);
item.appendChild(new Listcell(resourceEnum.toString()));
filterLimitingResource.appendChild(item);
}
filterLimitingResource.setSelectedIndex(0);
}
public Set<LimitingResourceEnum> getLimitingResourceOptionList() {
return LimitingResourceEnum.getLimitingResourceOptionList();
}
public LimitingResourceEnum getLimitingResource() {
final Worker worker = getWorker();
return (worker != null)
? LimitingResourceEnum.valueOf(worker.isLimitingResource())
: LimitingResourceEnum.NON_LIMITING_RESOURCE; // Default option
}
public void setLimitingResource(LimitingResourceEnum option) {
Worker worker = getWorker();
if (worker != null) {
worker.setResourceType(LimitingResourceEnum.toResourceType(option));
if (worker.isLimitingResource()) {
worker.setUser(null);
}
Util.reloadBindings(userBindingGroupbox);
}
}
public boolean isEditing() {
return (getWorker() != null && !getWorker().isNewObject());
}
public void onCheckGenerateCode(Event e) {
CheckEvent ce = (CheckEvent) e;
if (ce.isChecked()) {
// We have to auto-generate the code if it is unsaved
try {
workerModel.setCodeAutogenerated(ce.isChecked());
} catch (ConcurrentModificationException err) {
messages.showMessage(Level.ERROR, err.getMessage());
}
}
Util.reloadBindings(editWindow);
}
public void confirmRemove(Worker worker) {
try {
if (!workerModel.canRemove(worker)) {
messages.showMessage(
Level.WARNING,
_("This worker cannot be deleted because it has assignments to projects or imputed hours"));
return;
}
int status = Messagebox.show(
_("Confirm deleting this worker. Are you sure?"),
_("Delete"), Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION);
if (Messagebox.OK != status) {
return;
}
boolean removeBoundUser = false;
User user = workerModel.getBoundUserFromDB(worker);
if (user != null && !user.isSuperuser()) {
removeBoundUser = Messagebox.show(
_("Do you want to remove bound user \"{0}\" too?", user.getLoginName()),
_("Delete bound user"),
Messagebox.YES | Messagebox.NO, Messagebox.QUESTION) == Messagebox.YES;
}
workerModel.confirmRemove(worker, removeBoundUser);
messages.showMessage(Level.INFO,
removeBoundUser ? _("Worker and bound user deleted") : _("Worker deleted"));
goToList();
} catch (InstanceNotFoundException e) {
messages.showMessage(Level.INFO, _("This worker was already removed by other user"));
}
}
public RowRenderer getWorkersRenderer() {
return (row, data, i) -> {
final Worker worker = (Worker) data;
row.setValue(worker);
row.addEventListener(Events.ON_CLICK, event -> goToEditForm(worker));
row.appendChild(new Label(worker.getSurname()));
row.appendChild(new Label(worker.getFirstName()));
row.appendChild(new Label(worker.getNif()));
row.appendChild(new Label(worker.getCode()));
row.appendChild(new Label(Boolean.TRUE.equals(worker.isLimitingResource()) ? _("yes") : _("no")));
Hbox hbox = new Hbox();
hbox.appendChild(Util.createEditButton(event -> goToEditForm(worker)));
hbox.appendChild(Util.createRemoveButton(event -> confirmRemove(worker)));
row.appendChild(hbox);
};
}
public void updateWindowTitle() {
if (editWindow != null && state != CRUDControllerState.LIST) {
Worker worker = getWorker();
String entityType = _("Worker");
if (worker.isVirtual()) {
entityType = _("Virtual Workers Group");
}
String humanId = worker.getHumanId();
String title;
switch (state) {
case CREATE:
if (StringUtils.isEmpty(humanId))
title = _("Create {0}", entityType);
else
title = _("Create {0}: {1}", entityType, humanId);
break;
case EDIT:
title = _("Edit {0}: {1}", entityType, humanId);
break;
default:
throw new IllegalStateException("You should be in creation or edition mode to use this method");
}
((Caption) editWindow.getFellow("caption")).setLabel(title);
}
}
public List<User> getPossibleUsersToBound() {
return workerModel.getPossibleUsersToBound();
}
public User getBoundUser() {
return workerModel.getBoundUser();
}
public void setBoundUser(User user) {
workerModel.setBoundUser(user);
Util.reloadBindings(userBindingGroupbox.getFellow("existingUserPanel"));
}
public boolean isUserSelected() {
return userBandbox.getSelectedElement() != null;
}
public String getLoginName() {
User user = getBoundUser();
if (user != null) {
return user.getLoginName();
}
return "";
}
public String getEmail() {
User user = getBoundUser();
if (user != null) {
return user.getEmail();
}
return "";
}
public boolean isExistingUser() {
int option = userBindingRadiogroup.getSelectedIndex();
return UserBindingOption.EXISTING_USER.ordinal() == option;
}
public boolean isCreateNewUser() {
int option = userBindingRadiogroup.getSelectedIndex();
return UserBindingOption.CREATE_NEW_USER.ordinal() == option;
}
public void updateUserBindingView() {
Util.reloadBindings(userBindingGroupbox);
}
public boolean isNotLimitingOrVirtualResource() {
Worker worker = getWorker();
return worker != null && !(worker.isLimitingResource() || worker.isVirtual());
}
public void goToUserEdition() {
User user = getWorker().getUser();
if (user != null && showConfirmUserEditionDialog() == Messagebox.OK) {
userCRUD.goToEditForm(user);
}
}
private int showConfirmUserEditionDialog() {
return Messagebox.show(
_("Unsaved changes will be lost. Would you like to continue?"),
_("Confirm editing user"), Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION);
}
public boolean isNoRoleUserAccounts() {
return !SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_USER_ACCOUNTS);
}
public String getUserEditionButtonTooltip() {
return isNoRoleUserAccounts()
? _("You do not have permissions to go to edit user window")
: "";
}
/**
* Should be public!
* Used in resources/worker/_list.zul
*/
public boolean isCreateButtonDisabled() {
Limits resourcesTypeLimit = limitsModel.getResourcesType();
if (isNullOrZeroValue(resourcesTypeLimit)) {
return false;
} else {
Integer resources = resourceDAO.getRowCount().intValue();
return resources >= resourcesTypeLimit.getValue();
}
}
/**
* Should be public!
* Used in resources/worker/_list.zul
*/
public String getShowCreateFormLabel() {
Limits resourcesTypeLimit = limitsModel.getResourcesType();
if (isNullOrZeroValue(resourcesTypeLimit)) {
return _("Create");
}
Integer resources = resourceDAO.getRowCount().intValue();
int resourcesLeft = resourcesTypeLimit.getValue() - resources;
return resources >= resourcesTypeLimit.getValue()
? _("Workers limit reached")
: _("Create") + " ( " + resourcesLeft + " " + _("left") + " )";
}
private boolean isNullOrZeroValue (Limits resourcesTypeLimit) {
return resourcesTypeLimit == null ||
resourcesTypeLimit.getValue() == null ||
resourcesTypeLimit.getValue().equals(0);
}
}