alfrescoactivitialfresco-webscriptsalfresco-enterprise

How to delete a task?


Or more precisely - is there a way to remove a participant from subsequent iterations if it was "deleted" at the first iteration?

What I mean...

For example, there is a some parallel workflow. I choose 10 participants and initiated this business process. Thus, 10 tasks were created, one for each participant. But then I decided to delete a few participants.

As far as I know, I can't remove the task. But I can to complete these tasks by using WebScript. For example, as follows. I know the workflowId and taskId:

...
Map<String, String> templateArgs = req.getServiceMatch().getTemplateVars();

// String workflowId = templateArgs.get("workflowId");
String taskId = templateArgs.get("taskId");

Map<QName, Serializable> updatedProperties = new HashMap<>();
updatedProperties.put(TaskRemoverModel.REVIEW_OUTCOME_PROPERTY, "Approve"); 
updatedProperties.put(TaskRemoverModel.COMMENT_PROPERTY, 
    "The user was excluded from the list of participants.");

workflowService.updateTask(taskId, updatedProperties, null, null);
workflowService.endTask(taskId, null);
...

But the problem is that at the stage of revise, the initiator can send for approval again. Then tasks for excluded participants will be created again.

Is there a way to "mark" these participants, so that no tasks were created for them in the future?

I would be very grateful for the information. Thanks to all.


Solution

  • The solution can be represented as follows.

    In the WebScript it's needed to update the task properties and complete that task. To the task properties add the new property with the reference to the excluded participant (who was the owner):

    ...
    Map<String, String> templateArgs = req.getServiceMatch().getTemplateVars();
    
    String taskId = templateArgs.get("taskId");
    
    Map<QName, Serializable> updatedProperties = new HashMap<>();
    updatedProperties.put(TaskRemoverModel.WORKFLOW_CONFIRM_MODEL_CONFIRMOUTCOME_PROPERTY, 
        "Approve"); 
    updatedProperties.put(TaskRemoverModel.WORKFLOW_MODEL_LASTCOMMENT_PROPERTY, 
        I18NUtil.getMessage("task.comment.excluded"));
    
    WorkflowTask workflowTask = workflowService.getTaskById(taskId);
    Iterator taskProperties = workflowTask.getProperties().entrySet().iterator();
    while(taskProperties.hasNext()) {
        Map.Entry taskProperty = (Map.Entry)taskProperties.next();
        if(TaskRemoverModel.CONTENT_MODEL_OWNER_PROPERTY.toString().equals(
          taskProperty.getKey().toString())) {
            updatedProperties.put(TaskRemoverModel.TASK_WAS_EXCLUDED_SIGN, 
                    personService.getPerson(taskProperty.getValue().toString()));
        }
    
    }
    
    workflowService.updateTask(taskId, updatedProperties, null, null);
    workflowService.endTask(taskId, null);
    ...
    

    For the complete event of the task add the listener. This listener will work after this call in the WebScript:

    ...
    workflowService.endTask(taskId, null);
    ...
    

    In the listener, find this new property, in which the reference to the excluded participant. Then get the list of bpm_assignees and delete the reference for this participant from that list and set variable bpm_assignees again:

    public class TaskCompleteListener implements TaskListener {
        private Map<Object, Object> registeredBeans = 
            Context.getProcessEngineConfiguration().getBeans(); 
        private ServiceRegistry registry = 
            (ServiceRegistry) registeredBeans.get(
                ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY);
        private WorkflowService workflowService = registry.getWorkflowService();  
    
        @Override
        public void notify(DelegateTask delegateTask) {
            WorkflowTask workflowTask = 
                workflowService.getTaskById("activiti$" + delegateTask.getId());
            Map<QName, Serializable> taskProperties = workflowTask.getProperties();
    
            Iterator iterator = taskProperties.entrySet().iterator();
            while(iterator.hasNext()) {
                Map.Entry taskProperty = (Map.Entry)iterator.next();            
                if(taskProperty.getKey().toString().equals(
                 ContractsApprovalModel.TASK_WAS_EXCLUDED_SIGN)) {
                    ActivitiScriptNodeList assignees = 
                        (ActivitiScriptNodeList) delegateTask.getVariable("bpm_assignees");
                    for(ActivitiScriptNode personNode : assignees) {
                        if(personNode.getNodeRef().toString().equals(
                          taskProperty.getValue().toString())) {
                            assignees.remove(personNode);
                        }
                    }
                    delegateTask.setVariable("bpm_assignees", assignees);
                }            
            }
        }
    }
    

    After that it becomes possible to delete the tasks of the participants in runtime and after the resubmit for these participants tasks are not generated.