cancel
Showing results for 
Search instead for 
Did you mean: 

Workflow: auto-assign task to an user

benabou
Champ in-the-making
Champ in-the-making
Hi everyone,

I'm new in Alfresco and I have to develop a custom workflow with Activiti.

One of the requirement of it is the usertasks auto-assignement.

In fact, I have an Alfresco group called "Workers".

What I need is to assign my first usertask to the worker with the minimum number of assigned tasks.

I already try to lauch this script before the first usertask in order to get the username of my worker.

But it always returns me the first worker.



var members = people.getMembers(people.getGroup("GROUP_Workers"));
var assignedTasks = workflow.getAssignedTasks();
var arrayCount = [];

for(var i = 0 ; i < members.length ; i++) {
   var name = members.properties["cm:userName"];
   arrayCount.push(0);
   for(var j = 0 ; j < assignedTasks.length ; j++) {
      var name2 = assignedTasks[j].properties["bpm:assignee"];

      if (name2 == name) {
         arrayCount++;
      }
   }
}

var minValue = 999999999999999999999;
var minValueIndex ;

for(var i = 0 ; i < arrayCount.length ; i++) {
   if (arrayCount < minValue) {
      minValue = arrayCount;
      minValueIndex  = i;
   }
}

execution.setVariable("userName",members[minValueIndex].properties["cm:userName"]);



In order to debug my code, I already try to put some "logger.log()" after setting this:

log4j.logger.org.alfresco.repo.workflow=debug
log4j.logger.org.alfresco.repo.jscript.ScriptLogger=debug


But it doesn't write anything.

Please, can someone help me?

Thank you for your help.
4 REPLIES 4

kaynezhang
World-Class Innovator
World-Class Innovator
1.Please remember workflow.getAssignedTasks() will return <strong>all tasks that are assigned to the current user and that are currently in-progress </strong>
2.And if you want to change the assignment of a task you should use execution.setVariable("bpm_assignee", "assignee");
3.Which log4j.properties have you modified ,you should modify classpath:log4j.properties or classpath :alfresco/extension/***-log4j.properties. Or you can just use
logger.getSystem().out("***");
to print log information in console.

benabou
Champ in-the-making
Champ in-the-making
Hi,

Thank you for reply


Now, I can log what I want.

About the change of the assignment, I found something else but thank you for your solution.

Now, I have this:



var members = people.getMembers(people.getGroup("GROUP_Workers"));
var assignedTasks = workflow.getAssignedTasks();
var arrayCount = [];
   
for(var i = 0 ; i < members.length ; i++) {
   var name = members.properties["cm:userName"];   
   arrayCount.push(0);
   
        for(var j = 0 ; j < assignedTasks.length ; j++) {
      var name2 = assignedTasks[j].properties["owner"];
   
      if (name2 == name) {
         arrayCount++;
      }
   }   
}

var minValue = 999999999999999999999;
var minValueIndex ;

for(var i = 0 ; i < arrayCount.length ; i++) {
   if (arrayCount < minValue) {
      minValue = arrayCount;
      minValueIndex = i;
   }
}
task.assignee =  members[minValueIndex].properties["cm:userName"];



When I execute this, it always assigns the task to my first worker.
I tried some logs and I discovered that "assignedTasks.length" value was always 0 (even if i have many workflows tasks launched).
And I'm not sure to understand what you wanted to mean by "workflow.getAssignedTasks() will return all tasks that are assigned to the current user and that are currently in-progress"

Could you give me more informations about it and my problem, please?

Thank you

theoryoflinkin
Champ on-the-rise
Champ on-the-rise
Hi,

I try to do the same thing. But I have some problems with the getAssignedTasks() method too.

It seems that it doesn't return what we want.

Maybe kaynezhang could explain better than me what doesn't work in you code?

Regards

theoryoflinkin
Champ on-the-rise
Champ on-the-rise
Here is a solution I made.

I use a serviceTask which calls this java class:


import helpers.ServiceHelper;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.namespace.QName;
import org.apache.log4j.Logger;

public class FindAgentWithMinimumTasks implements JavaDelegate {
   public static FileServerImplServiceStub webService;
   public static Logger logger = Logger.getLogger(FindAgentWithMinimumTasks.class);

   @Override
   public void execute(DelegateExecution execution) throws Exception {
      execution.setVariable("defaultAgent", AuthenticationUtil.runAsSystem(new MyRunAsWork()));
   }

   private static class MyRunAsWork implements RunAsWork<String> {

      public String doWork() {
         // We get all the agents
         List<String> listAgents = getAllAgents(ServiceHelper.personService.getAllPeople());

         // We init an array in order to count the number of tasks assigned to each agent
         int nbTasksAssigned[] = new int[listAgents.size()];
         
         // We get all the active tasks
         List<WorkflowTask> listTasks = getAllActiveTasks();

         // For each tasks
         for (WorkflowTask task : listTasks) {
            // We get the owner of the task
            String assignee = (String) task.getProperties().get(QName.createQName("{http://www.alfresco.org/model/content/1.0}owner"));

            // assignee == null => pooled task /!\
            if (assignee != null) {
               // For each agent
               for (int i = 0; i < listAgents.size(); i++) {
                  if (assignee.equals(listAgents.get(i))) {
                     nbTasksAssigned++;
                  }
               }
            }
         }

         // Initializations
         long minValue = Long.MAX_VALUE;
         String usernameToReturn = "";
         
         // For each agents
         for (int i = 0; i < listAgents.size(); i++) {
            // We want the min value
            if (nbTasksAssigned < minValue) {
               minValue = nbTasksAssigned;
               usernameToReturn = listAgents.get(i);
            }
            logger.info(listAgents.get(i) + " - " + nbTasksAssigned + " tâches");
         }
         
         return usernameToReturn;
      }

      private static List<String> getAllAgents(Set<NodeRef> setUsers) {
         ArrayList<String> listUsers = new ArrayList<String>();
         
         // For each active user
         for (NodeRef users : setUsers) {
            // We get the username
            String userName = DefaultTypeConverter.INSTANCE.convert(String.class, ServiceHelper.nodeService.getProperty(users, ContentModel.PROP_USERNAME));
            
            // We add the user to the list if he belongs to the group "Agents"
            if (isAgent(userName)) {
               listUsers.add(userName);
            }
         }
         
         return listUsers;
      }
      
      private static boolean isAgent(String userName) {
         // We get all the groups of the user
         Set<String> groupsUser = ServiceHelper.authorityService.getAuthoritiesForUser(userName);

         // For each group
         for (String groupName : groupsUser) {
            if (groupName.equals("GROUP_Agents")) {
               return true;
            }
         }

         return false;
      }
      
      private static List<WorkflowTask> getAllActiveTasks() {
         WorkflowTaskQuery workflowTaskQuery = new WorkflowTaskQuery();
         
         // We want all the "IN PROGRESS" tasks
         workflowTaskQuery.setTaskState(WorkflowTaskState.IN_PROGRESS);
         
         return ServiceHelper.workflowService.queryTasks(workflowTaskQuery, true);
      }
   }
}


The "defaultAgent" variable is used as the assignee of my first userTask.

And this is the code of my ServiceHelper class that is used inside the FindAgentWithMinimumTasks class


import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.version.VersionService;
import org.alfresco.service.cmr.workflow.WorkflowService;

public class ServiceHelper {
   //public static ServiceRegistry serviceRegistry; = org.alfresco.web.bean.repository.Repository.getServiceRegistry(FacesContext.getCurrentInstance());
   public static ServiceRegistry serviceRegistry;
   public static WorkflowService workflowService;
   public static FileFolderService fileFolderService;
   public static VersionService versionService;
   public static SearchService searchService;
   public static ContentService contentService;
   public static NodeService nodeService;
   public static PersonService personService;
   public static AuthorityService authorityService;

   public void setServiceRegistry(ServiceRegistry serviceRegistry){
      ServiceHelper.serviceRegistry = serviceRegistry;
   }
   
   public void init(){
      workflowService = serviceRegistry.getWorkflowService();
      fileFolderService = serviceRegistry.getFileFolderService();
      versionService = serviceRegistry.getVersionService();
      searchService = serviceRegistry.getSearchService();
      contentService = serviceRegistry.getContentService();
      nodeService = serviceRegistry.getNodeService();
      personService = serviceRegistry.getPersonService();
      authorityService = serviceRegistry.getAuthorityService();
   }
}


And don't forget to define a bean file in order to call the init method of ServiceHelper

Hope this help