/* * Copyright (c) 2016 Haulmont * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.haulmont.timesheets.gui.project; import com.google.common.collect.ImmutableMap; import com.haulmont.bali.util.ParamsMap; import com.haulmont.cuba.core.entity.Entity; import com.haulmont.cuba.core.global.CommitContext; import com.haulmont.cuba.core.global.LoadContext; import com.haulmont.cuba.core.global.Metadata; import com.haulmont.cuba.core.global.View; import com.haulmont.cuba.gui.WindowManager; import com.haulmont.cuba.gui.components.*; import com.haulmont.cuba.gui.components.actions.CreateAction; import com.haulmont.cuba.gui.components.actions.EditAction; import com.haulmont.cuba.gui.components.actions.ItemTrackingAction; import com.haulmont.cuba.gui.data.HierarchicalDatasource; import com.haulmont.cuba.security.entity.User; import com.haulmont.timesheets.entity.*; import com.haulmont.timesheets.gui.util.ComponentsHelper; import com.haulmont.timesheets.gui.util.SecurityAssistant; import com.haulmont.timesheets.service.ProjectsService; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Named; import java.util.*; /** * @author gorelov */ @SuppressWarnings("WeakerAccess") public class ProjectBrowse extends AbstractLookup { @Inject protected TreeTable<Project> projectsTable; @Inject protected Table<Task> tasksTable; @Inject protected Table<ProjectParticipant> participantsTable; @Inject protected PopupButton assignBtn; @Inject protected SecurityAssistant securityAssistant; @Inject protected ProjectsService projectsService; @Inject protected HierarchicalDatasource<Project, UUID> projectsDs; @Named("participantsTable.create") protected CreateAction participantsTableCreate; @Named("participantsTable.edit") protected EditAction participantsTableEdit; @Inject protected Metadata metadata; @Override public void init(Map<String, Object> params) { if (securityAssistant.isSuperUser()) { projectsDs.setQuery("select e from ts$Project e"); } initProjectsTable(); initTasksTable(); initParticipantsTable(); } private void initParticipantsTable() { participantsTable.addAction(new CreateAction(participantsTable) { @Override public String getCaption() { return getMessage("caption.createParticipant"); } @Override public WindowManager.OpenType getOpenType() { return WindowManager.OpenType.DIALOG; } @Override public Map<String, Object> getInitialValues() { return ParamsMap.of("project", projectsTable.getSingleSelected()); } @Override public void actionPerform(Component component) { if (projectsTable.getSingleSelected() != null) { super.actionPerform(component); } else { showNotification(getMessage("notification.pleaseSelectProject"), NotificationType.HUMANIZED); } } }); participantsTable.addAction(new ItemTrackingAction("copy") { @Override public String getCaption() { return getMessage("caption.copy"); } @Override public void actionPerform(Component component) { copyParticipants(); } @Override protected boolean isApplicable() { return projectsTable != null && !projectsTable.getSelected().isEmpty(); } }); participantsTableCreate.setOpenType(WindowManager.OpenType.DIALOG); participantsTableEdit.setOpenType(WindowManager.OpenType.DIALOG); } private void initTasksTable() { tasksTable.addAction(new CreateAction(tasksTable) { @Override public Map<String, Object> getInitialValues() { return ParamsMap.of("project", projectsTable.getSingleSelected()); } @Override public void actionPerform(Component component) { if (projectsTable.getSingleSelected() != null) { super.actionPerform(component); } else { showNotification(getMessage("notification.pleaseSelectProject"), NotificationType.HUMANIZED); } } }); tasksTable.addAction(new ComponentsHelper.TaskStatusTrackingAction(tasksTable, "switchStatus")); tasksTable.setStyleProvider(new Table.StyleProvider<Task>() { @Nullable @Override public String getStyleName(Task entity, @Nullable String property) { if ("status".equals(property)) { return ComponentsHelper.getTaskStatusStyle(entity); } return null; } }); } private void initProjectsTable() { projectsTable.addAction(new CreateAction(projectsTable) { @Override public WindowManager.OpenType getOpenType() { return WindowManager.OpenType.DIALOG; } }); projectsTable.addAction(new EditAction(tasksTable) { @Override public WindowManager.OpenType getOpenType() { return WindowManager.OpenType.DIALOG; } @Override protected void afterCommit(Entity entity) { projectsTable.refresh(); } }); LoadContext<ProjectRole> loadContext = new LoadContext<>(ProjectRole.class); loadContext.setQueryString("select pr from ts$ProjectRole pr order by pr.name"); List<ProjectRole> projectRoles = getDsContext().getDataSupplier().loadList(loadContext); projectRoles = new ArrayList<>(projectRoles); sortProjectRoles(projectRoles); for (final ProjectRole projectRole : projectRoles) { assignBtn.addAction(new AbstractAction("assign" + projectRole.getCode()) { @Override public String getCaption() { return (getMessage("caption.assign" + StringUtils.capitalize(projectRole.getCode().getId().toLowerCase()))); } @SuppressWarnings("unchecked") @Override public void actionPerform(Component component) { if (CollectionUtils.isNotEmpty(projectsTable.getSelected())) { openLookup("sec$User.lookup", items -> { if (CollectionUtils.isNotEmpty(items)) { Collection<Project> selectedProjects = projectsTable.getSelected(); Collection<User> selectedUsers = (Collection) items; boolean needToRefresh = projectsService.assignUsersToProjects(selectedUsers, selectedProjects, projectRole); if (needToRefresh) { participantsTable.refresh(); } } }, WindowManager.OpenType.DIALOG); } else { showNotification(getMessage("notification.pleaseSelectProject"), NotificationType.HUMANIZED); } } }); } projectsTable.setStyleProvider(new Table.StyleProvider<Project>() { @Nullable @Override public String getStyleName(Project entity, @Nullable String property) { if ("status".equals(property)) { return ComponentsHelper.getProjectStatusStyle(entity); } return null; } }); } protected void sortProjectRoles(List<ProjectRole> projectRoles) { Collections.sort(projectRoles, new Comparator<ProjectRole>() { private Map<ProjectRoleCode, Integer> order = ImmutableMap.<ProjectRoleCode, Integer>builder() .put(ProjectRoleCode.WORKER, 1) .put(ProjectRoleCode.MANAGER, 2) .put(ProjectRoleCode.APPROVER, 3) .put(ProjectRoleCode.OBSERVER, 4).build(); @Override public int compare(ProjectRole o1, ProjectRole o2) { ProjectRoleCode code1 = o1.getCode(); ProjectRoleCode code2 = o2.getCode(); Integer order1 = order.get(code1); Integer order2 = order.get(code2); return ObjectUtils.compare(order1, order2); } }); } @SuppressWarnings("unchecked") public void copyParticipants() { final Project project = projectsTable.getSingleSelected(); if (project != null) { openLookup("ts$Project.lookup", items -> { if (CollectionUtils.isNotEmpty(items)) { CommitContext commitContext = new CommitContext(); for (Project selected : (Collection<Project>) items) { commitContext.getCommitInstances().addAll(updateParticipants( projectsService.getProjectParticipants(selected, "projectParticipant-full"), project)); } getDsContext().getDataSupplier().commit(commitContext); participantsTable.refresh(); } }, WindowManager.OpenType.DIALOG, ParamsMap.of("exclude", project)); } else { showNotification(getMessage("notification.pleaseSelectProject"), NotificationType.HUMANIZED); } } protected Collection<? extends Entity> updateParticipants(List<ProjectParticipant> participants, Project project) { if (participants.isEmpty()) { return Collections.emptyList(); } List<ProjectParticipant> copies = new ArrayList<>(participants.size()); List<User> assignedUsers = projectsService.getProjectUsers(project, View.MINIMAL); for (ProjectParticipant existParticipant : participants) { if (!assignedUsers.contains(existParticipant.getUser())) { ProjectParticipant participant = metadata.create(ProjectParticipant.class); participant.setUser(existParticipant.getUser()); participant.setRole(existParticipant.getRole()); participant.setProject(project); copies.add(participant); } } return copies; } @Override public void ready() { projectsTable.expandAll(); } }