package com.constellio.app.modules.tasks.services; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.collections.CollectionUtils; import org.joda.time.LocalDate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.constellio.app.modules.tasks.model.wrappers.Task; import com.constellio.app.modules.tasks.model.wrappers.structures.TaskFollower; import com.constellio.app.modules.tasks.model.wrappers.structures.TaskReminder; import com.constellio.app.modules.tasks.model.wrappers.types.TaskStatus; import com.constellio.app.modules.tasks.ui.builders.TaskFollowerFromVOBuilder; import com.constellio.app.modules.tasks.ui.builders.TaskReminderFromVOBuilder; import com.constellio.app.modules.tasks.ui.entities.TaskFollowerVO; import com.constellio.app.modules.tasks.ui.entities.TaskReminderVO; import com.constellio.app.modules.tasks.ui.entities.TaskVO; import com.constellio.data.dao.dto.records.OptimisticLockingResolution; import com.constellio.data.utils.TimeProvider; import com.constellio.model.entities.batchprocess.BatchProcess; import com.constellio.model.entities.records.Record; import com.constellio.model.entities.records.Transaction; import com.constellio.model.entities.records.wrappers.User; import com.constellio.model.frameworks.validation.ValidationException; import com.constellio.model.services.logging.LoggingServices; import com.constellio.model.services.records.RecordServices; import com.constellio.model.services.records.RecordServicesException; public class TaskPresenterServices { private static Logger LOGGER = LoggerFactory.getLogger(TaskPresenterServices.class); final private TasksSchemasRecordsServices tasksSchemas; private final RecordServices recordServices; private final TasksSearchServices tasksSearchServices; private LoggingServices loggingServices; public TaskPresenterServices(TasksSchemasRecordsServices tasksSchemas, RecordServices recordServices, TasksSearchServices tasksSearchServices, LoggingServices loggingServices) { this.tasksSchemas = tasksSchemas; this.recordServices = recordServices; this.tasksSearchServices = tasksSearchServices; this.loggingServices = loggingServices; } public Task toTask(TaskVO taskVO, Record record) { Task task = tasksSchemas.wrapTask(record); List<TaskReminderVO> remindersVOs = taskVO.getReminders(); if (remindersVOs != null) { List<TaskReminder> reminders = new ArrayList<>(); TaskReminderFromVOBuilder reminderBuilder = new TaskReminderFromVOBuilder(); for (Object reminderVO : remindersVOs) { //FIXME should be VO! if (reminderVO instanceof TaskReminderVO) { reminders.add(reminderBuilder.build((TaskReminderVO) reminderVO)); } else { reminders.add((TaskReminder) reminderVO); } } task.setReminders(reminders); } List<TaskFollowerVO> followersVOs = taskVO.getTaskFollowers(); if (taskVO.getTaskFollowers() != null) { TaskFollowerFromVOBuilder followerBuilder = new TaskFollowerFromVOBuilder(); Map<String, TaskFollower> taskFollowersMap = new HashMap<>(); for (Object follower : followersVOs) { TaskFollowerVO followerVO; //FIXME should always be VO if (follower instanceof TaskFollowerVO) { followerVO = (TaskFollowerVO) follower; } else { followerVO = toTaskFollowerVO((TaskFollower) follower); } TaskFollower currentTaskFollower = taskFollowersMap.get(followerVO.getFollowerId()); if (currentTaskFollower == null) { currentTaskFollower = followerBuilder.build(followerVO); } if (followerVO.isFollowSubTasksModified()) { currentTaskFollower.setFollowSubTasksModified(true); } if (followerVO.isFollowTaskAssigneeModified()) { currentTaskFollower.setFollowTaskAssigneeModified(true); } if (followerVO.isFollowTaskCompleted()) { currentTaskFollower.setFollowTaskCompleted(true); } if (followerVO.isFollowTaskDeleted()) { currentTaskFollower.setFollowTaskDeleted(true); } if (followerVO.isFollowTaskStatusModified()) { currentTaskFollower.setFollowTaskStatusModified(true); } taskFollowersMap.put(currentTaskFollower.getFollowerId(), currentTaskFollower); } task.setTaskFollowers(new ArrayList<>(taskFollowersMap.values())); } return task; } private TaskFollowerVO toTaskFollowerVO(TaskFollower taskFollower) { return new TaskFollowerVO(taskFollower.getFollowerId(), taskFollower.getFollowTaskAssigneeModified(), taskFollower.getFollowSubTasksModified(), taskFollower.getFollowTaskStatusModified(), taskFollower.getFollowTaskCompleted(), taskFollower.getFollowTaskDeleted()); } public boolean isTaskOverdue(TaskVO task) { LocalDate dueDate = task.getDueDate(); if (dueDate == null) { return false; } if (dueDate.isBefore(TimeProvider.getLocalDate())) { LocalDate endDate = task.getEndDate(); if (endDate == null || endDate.isAfter(dueDate)) { return true; } } return false; } public boolean isEditTaskButtonVisible(Record record, User currentUser) { return currentUser.hasWriteAccess().on(record); } public boolean isCompleteTaskButtonVisible(Record record, User user) { if (!user.hasWriteAccess().on(record)) { return false; } if (!isAssignedToUser(record, user)) { return false; } Object statusId = record.get(tasksSchemas.userTask.status()); if (statusId == null) { return true; } TaskStatus taskStatus = tasksSchemas.getTaskStatus((String) statusId); return taskStatus.isBeforeFinished(); } public void closeTask(Record record, User user) { TaskStatus closeStatus = tasksSearchServices.getClosedStatus(); addOrUpdate(record.set(tasksSchemas.userTask.status(), closeStatus), user); } public boolean isCloseTaskButtonVisible(Record record, User user) { if (!user.hasWriteAccess().on(record)) { return false; } if (!isAssignedToUser(record, user) && !wasCreatedByUser(record, user)) { return false; } Object statusId = record.get(tasksSchemas.userTask.status()); if (statusId == null) { return false; } TaskStatus taskStatus = tasksSchemas.getTaskStatus((String) statusId); return taskStatus.isFinished(); } boolean isAssignedToUser(Record record, User user) { Task task = tasksSchemas.wrapTask(record); if (task.getAssignee() != null && task.getAssignee().equals(user.getId())) { return true; } if (task.getAssigneeUsersCandidates() != null && task.getAssigneeUsersCandidates().contains(user.getId())) { return true; } return CollectionUtils.containsAny(task.getAssigneeGroupsCandidates(), user.getUserGroups()); } boolean wasCreatedByUser(Record record, User user) { Task task = tasksSchemas.wrapTask(record); return task.getCreatedBy() != null && task.getCreatedBy().equals(user.getId()); } public void sendReminder(Record record, User user) { Task task = tasksSchemas.wrapTask(record); List<TaskReminder> newReminders = new ArrayList<>(task.getReminders()); newReminders.add(new TaskReminder().setFixedDate(TimeProvider.getLocalDate())); addOrUpdate(task.setReminders(newReminders).getWrappedRecord(), user); } public boolean isSendReminderButtonVisible(Record record, User user) { return user.hasWriteAccess().on(record); } public void deleteTask(Record record, User currentUser) { recordServices.logicallyDelete(record, currentUser); loggingServices.logDeleteRecordWithJustification(record, currentUser, ""); //recordServices.physicallyDelete(record, currentUser); } public boolean isDeleteTaskButtonVisible(Record record, User user) { return user.hasDeleteAccess().on(record); } public final List<BatchProcess> addOrUpdate(Record record, User user) { Transaction createTransaction = new Transaction(); createTransaction.setUser(user); createTransaction.setOptimisticLockingResolution(OptimisticLockingResolution.EXCEPTION); createTransaction.addUpdate(record); try { return recordServices.executeHandlingImpactsAsync(createTransaction); } catch (RecordServicesException e) { Exception nestedException; if (e instanceof RecordServicesException.ValidationException) { LOGGER.error(e.getMessage(), e); nestedException = new ValidationException(((RecordServicesException.ValidationException) e).getErrors()); } else { nestedException = e; } throw new RuntimeException(nestedException); } } public boolean isFinished(TaskVO taskVO) { TaskStatus status = tasksSchemas.getTaskStatus(taskVO.getStatus()); return status.isFinished(); } public void autoAssignTask(Record record, User user) { if (record == null) { return; } record.set(tasksSchemas.userTask.assignee(), user.getId()); record.set(tasksSchemas.userTask.assigner(), user.getId()); record.set(tasksSchemas.userTask.assignedOn(), TimeProvider.getLocalDate()); addOrUpdate(record, user); } public boolean isAutoAssignButtonEnabled(Record record, User user) { if (!user.hasWriteAccess().on(record)) { return false; } if (record == null) { return false; } Task task = tasksSchemas.getTask(record.getId()); return task.getAssignee() == null && (task.getAssigneeUsersCandidates() == null || task.getAssigneeUsersCandidates() .isEmpty()) && (task.getAssigneeGroupsCandidates() == null || task.getAssigneeGroupsCandidates().isEmpty()); } }