CCM NG/ccm-core: Several improvments for Workflow Handling

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4816 8810af33-2d31-482b-a856-94f89814c4df
ccm-docs
jensp 2017-06-26 17:15:45 +00:00
parent 6759d1d2e1
commit 0a6c5ae636
7 changed files with 74 additions and 29 deletions

View File

@ -54,25 +54,24 @@ public class AssignedTaskController {
@Inject @Inject
private Shiro shiro; private Shiro shiro;
@Inject @Inject
private ConfigurationManager confManager; private ConfigurationManager confManager;
private Locale defaultLocale; private Locale defaultLocale;
@PostConstruct @PostConstruct
private void init() { private void init() {
final KernelConfig kernelConfig = confManager.findConfiguration( final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class); KernelConfig.class);
defaultLocale = kernelConfig.getDefaultLocale(); defaultLocale = kernelConfig.getDefaultLocale();
} }
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public List<RowData<Long>> getAssignedTasks(final Workflow workflow) { public List<RowData<Long>> getAssignedTasks(final Workflow workflow) {
final User user = shiro.getUser().get(); final User user = shiro.getUser().get();
final List<AssignableTask> tasks = userTaskRepo.getAssignedTasks(user, final List<AssignableTask> tasks = userTaskRepo.getAssignedTasks(user,
workflow); workflow);
return tasks return tasks
.stream() .stream()
@ -82,24 +81,22 @@ public class AssignedTaskController {
} }
private RowData<Long> createRowData(final AssignableTask task) { private RowData<Long> createRowData(final AssignableTask task) {
final RowData<Long> rowData = new RowData<>(3); final RowData<Long> rowData = new RowData<>(3);
rowData.setRowKey(task.getTaskId()); rowData.setRowKey(task.getTaskId());
// Change when Workflow forms provide fields to enter localised label. // Change when Workflow forms provide fields to enter localised label.
rowData.setColData(0, task.getLabel().getValue(defaultLocale)); rowData.setColData(0, task.getLabel().getValue(defaultLocale));
if (task.isLocked()) { if (task.isLocked()) {
rowData.setColData(1, task.getLockingUser().getName()); rowData.setColData(1, task.getLockingUser().getName());
} else { } else {
rowData.setColData(1,""); rowData.setColData(1, "");
} }
rowData.setColData(2, ""); rowData.setColData(2, "");
return rowData; return rowData;
} }

View File

@ -56,8 +56,6 @@ class AssignedTaskTableModelBuilder extends AbstractTableModelBuilder {
Assert.exists(workflow, Workflow.class); Assert.exists(workflow, Workflow.class);
final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final WorkflowManager workflowManager = cdiUtil.findBean(
WorkflowManager.class);
final WorkflowState workflowState = workflow.getState(); final WorkflowState workflowState = workflow.getState();
if (workflowState == WorkflowState.STARTED) { if (workflowState == WorkflowState.STARTED) {

View File

@ -70,12 +70,21 @@ import static org.libreccm.core.CoreConstants.DB_SCHEMA;
, ,
@NamedQuery( @NamedQuery(
name = "AssignableTask.findAssignedTasks", name = "AssignableTask.findAssignedTasks",
query = "SELECT t FROM AssignableTask t " query = "SELECT DISTINCT t FROM AssignableTask t "
+ "JOIN t.assignments a " + "JOIN t.assignments a "
+ "WHERE a.role IN :roles " + "WHERE a.role IN :roles "
+ "AND t.workflow = :workflow " + "AND t.workflow = :workflow "
+ "AND t.active = true") + "AND t.active = true")
, ,
@NamedQuery(
name = "AssignableTask.isAssignedTo",
query = "SELECT (CASE WHEN COUNT(t) > 0 THEN true ELSE false END) "
+ "FROM AssignableTask t "
+ "JOIN t.assignments a "
+ "WHERE a.role IN :roles "
+ "AND t = :task"
)
,
@NamedQuery( @NamedQuery(
name = "AssignableTask.findOverdueTasks", name = "AssignableTask.findOverdueTasks",
query = "SELECT t FROM AssignableTask t " query = "SELECT t FROM AssignableTask t "

View File

@ -22,6 +22,7 @@ import org.libreccm.core.CoreConstants;
import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.AuthorizationRequired;
import org.libreccm.security.RequiresPrivilege; import org.libreccm.security.RequiresPrivilege;
import org.libreccm.security.Role; import org.libreccm.security.Role;
import org.libreccm.security.RoleMembership;
import org.libreccm.security.RoleRepository; import org.libreccm.security.RoleRepository;
import org.libreccm.security.Shiro; import org.libreccm.security.Shiro;
import org.libreccm.security.User; import org.libreccm.security.User;
@ -125,6 +126,24 @@ public class AssignableTaskManager {
} }
} }
@Transactional(Transactional.TxType.REQUIRED)
public boolean isAssignedTo(final AssignableTask task,
final User user) {
final TypedQuery<Boolean> query = entityManager
.createNamedQuery("AssignableTask.isAssignedTo",
Boolean.class);
final List<Role> roles = user
.getRoleMemberships()
.stream()
.map(RoleMembership::getRole)
.collect(Collectors.toList());
query.setParameter("roles", roles);
query.setParameter("task", task);
return query.getSingleResult();
}
/** /**
* *
* @param task * @param task

View File

@ -20,18 +20,20 @@ package org.libreccm.workflow;
import org.libreccm.core.AbstractEntityRepository; import org.libreccm.core.AbstractEntityRepository;
import org.libreccm.security.Role; import org.libreccm.security.Role;
import org.libreccm.security.RoleMembership;
import org.libreccm.security.User; import org.libreccm.security.User;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.persistence.NoResultException; import javax.persistence.NoResultException;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* Repository for assignable tasks. * Repository for assignable tasks.
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
@RequestScoped @RequestScoped
@ -56,7 +58,8 @@ public class AssignableTaskRepository
* @return An optional either with the found item or empty * @return An optional either with the found item or empty
*/ */
public Optional<AssignableTask> findByUuid(final String uuid) { public Optional<AssignableTask> findByUuid(final String uuid) {
final TypedQuery<AssignableTask> query = getEntityManager().createNamedQuery( final TypedQuery<AssignableTask> query = getEntityManager()
.createNamedQuery(
"AssignableTask.findByUuid", AssignableTask.class); "AssignableTask.findByUuid", AssignableTask.class);
query.setParameter("uuid", uuid); query.setParameter("uuid", uuid);
@ -71,7 +74,8 @@ public class AssignableTaskRepository
final User user, final Workflow workflow) { final User user, final Workflow workflow) {
final TypedQuery<AssignableTask> query = getEntityManager() final TypedQuery<AssignableTask> query = getEntityManager()
.createNamedQuery( .createNamedQuery(
"AssignableTask.findEnabledTasksForWorkflow", AssignableTask.class); "AssignableTask.findEnabledTasksForWorkflow",
AssignableTask.class);
query.setParameter("user", user); query.setParameter("user", user);
query.setParameter("workflow", workflow); query.setParameter("workflow", workflow);
@ -81,11 +85,12 @@ public class AssignableTaskRepository
public List<AssignableTask> getAssignedTasks(final User user, public List<AssignableTask> getAssignedTasks(final User user,
final Workflow workflow) { final Workflow workflow) {
final TypedQuery<AssignableTask> query = getEntityManager() final TypedQuery<AssignableTask> query = getEntityManager()
.createNamedQuery( .createNamedQuery("AssignableTask.findAssignedTasks",
"AssignableTask.findAssignedTasks", AssignableTask.class); AssignableTask.class);
final List<Role> roles = user.getRoleMemberships() final List<Role> roles = user
.getRoleMemberships()
.stream() .stream()
.map(membership -> membership.getRole()) .map(RoleMembership::getRole)
.collect(Collectors.toList()); .collect(Collectors.toList());
query.setParameter("roles", roles); query.setParameter("roles", roles);

View File

@ -216,6 +216,7 @@ public class Task implements Identifiable, Serializable {
this.taskId = taskId; this.taskId = taskId;
} }
@Override
public String getUuid() { public String getUuid() {
return uuid; return uuid;
} }

View File

@ -51,7 +51,9 @@ import javax.persistence.TypedQuery;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.libreccm.security.Role; import org.libreccm.security.User;
import java.util.Optional;
/** /**
* Manager for {@link Workflow}s. The logic of some of these classes has been * Manager for {@link Workflow}s. The logic of some of these classes has been
@ -360,12 +362,26 @@ public class WorkflowManager {
workflow.setActive(true); workflow.setActive(true);
updateState(workflow); updateState(workflow);
for (final Task current : workflow.getTasks()) { // for (final Task current : workflow.getTasks()) {
current.setActive(true); // current.setActive(true);
taskManager.updateState(current); // taskManager.updateState(current);
// }
final List<Task> tasks = workflow.getTasks();
if (!tasks.isEmpty()) {
final Task firstTask = tasks.get(0);
firstTask.setActive(true);
taskManager.updateState(firstTask);
final Optional<User> currentUser = shiro.getUser();
if (!currentUser.isPresent()
&& assignableTaskManager
.isAssignedTo((AssignableTask) firstTask,
currentUser.get())) {
assignableTaskManager.lockTask((AssignableTask) firstTask);
}
} }
} }
workflowRepo.save(workflow); workflowRepo.save(workflow);
} }