cancel
Showing results for 
Search instead for 
Did you mean: 

Activiti is ineffective in China, and hopes to attract official attention.

hubiao
Champ in-the-making
Champ in-the-making

1: how to refuse approval, back to the last node processing? Do you offer API?
Start A I B I C I D I E I End I
For example, when I'm in the C link, I may refuse to approve or go back to a certain link (A, B, C) at C.
The official only provided the completed task API, and did not provide the refusal of the approval of the API.

2: how do you jump to any node?
Suggestion: if the official want to do the world's first class activiti open source, it should be examined in all aspects. On the two above, Chinese developers are very embarrassed. It is hoped that the official will increase the function above. Thank you very much!


The author uses the environment: activiti 6

1 ACCEPTED ANSWER

ryandawson
Elite Collaborator
Elite Collaborator

I guess you saw Stone Yuan‌'s reply on How can activiti 6 be rejected? This kind of situation can be handled using gateways. So every outgoing flow goes into a gateway and the gateway makes the decision about which task to move back depending upon the value of the outcome of the previous task (which will presumably be set in a variable). So each gateway will link back to every previous task. You will end up with a quite large diagram that will take a while to draw like:

But if you actually have more tasks than just A,B,C,D and E then that will make the diagram even bigger and a certain point it will become impractical.

View answer in original post

11 REPLIES 11

ryandawson
Elite Collaborator
Elite Collaborator

I guess you saw Stone Yuan‌'s reply on How can activiti 6 be rejected? This kind of situation can be handled using gateways. So every outgoing flow goes into a gateway and the gateway makes the decision about which task to move back depending upon the value of the outcome of the previous task (which will presumably be set in a variable). So each gateway will link back to every previous task. You will end up with a quite large diagram that will take a while to draw like:

But if you actually have more tasks than just A,B,C,D and E then that will make the diagram even bigger and a certain point it will become impractical.

An alternative model which could handle more tasks better might be

First, please forgive me for my poor English. I am trying to improve my English....haha

I think that the fisrt bpmn diagram is the most common and principled approach, the second bpmn diagram is a smart way to solve this problem, but some Chinese activiti user and developer think that there are too much gateways and sequence flows.

They design bpmn diagram like below

With this bpmn diagram, we can solve this problem with BpmnModel.

Step 1

Find the SequcenceFlow which is the outgoing flow of the current usertask

Step 2

Change the targetRefElement of the SequcenceFlow to the node which you want to jump

Step 3

Complete the current usertask

I wish I had successfully expressed what I meant. ...haha

Thank you Activiti, thank you the guys who working for Activiti.

Activiti is a great project, it is most Chinese developer's first choice of workflow framework.

I think it's not only helping us write less code, it's also a good solution of workflow.

So maybe the questioner is not familiar with it. It does not mean that Activiti is ineffective in China.

I'm very sorry that my countrymen said this.

The day after tomorrow is our Spring Festival.  Happy  Spring Festival to you~

After Spring Festival, I plan to rebuild activiti-ui in springboot. ~~~

That makes sense - so instead of the 'Decide which task to go to' step you just build that logic into each service task and that code within the service task must also modify the BpmnModel. I guess you look it up through the RepositoryService and modify it so that the outgoing flow points where you want it to. (I guess you are not using DynamicBpmnService like mentioned at https://community.alfresco.com/community/bpm/blog/2017/06/01/activiti-6-is-here ). If you have a code snippet that could help  and other members. 

You're right, here is my code.

private FlowElement findElement(String procDefId, String elementId) {
    BpmnModel model = repositoryService.getBpmnModel(procDefId);
    Collection<FlowElement> list = model.getMainProcess().getFlowElements();
    for (FlowElement element : list) {
        if (elementId.equals(element.getId())) {
            return element;
        }
    }
    return null;
}

@Test
public void jump() {
    String currentUserTaskId = "usertask3";
    String targetUserTaskId = "usertask1";
    String procDefId = "changeDept:1:2504";
    String procInstId = "5013";
    FlowElement targetElement = findElement(procDefId, targetUserTaskId);

    BpmnModel model = repositoryService.getBpmnModel(procDefId);
    Collection<FlowElement> list = model.getMainProcess().getFlowElements();
    for (FlowElement element : list) {
        if (element instanceof SequenceFlow) {
            SequenceFlow flow = (SequenceFlow) element;
            if (currentUserTaskId.equals(flow.getSourceRef())) {
                flow.setTargetFlowElement(targetElement);
                System.out.println(taskService.createTaskQuery()
                        .processInstanceId(procInstId).singleResult().getName());
                taskService.complete(taskService.createTaskQuery()
                        .processInstanceId(procInstId).singleResult().getId());
                System.out.println(taskService.createTaskQuery()
                        .processInstanceId(procInstId).singleResult().getName());
            }
        }
    }
}

Stone Yuan Thanks very much for sharing this, it really helps the community. The approach is conceptually similar to Activiti User Guide I had a thought about how the approach sets the target element. Do you save the change to the BpmnModel when you update the target element for the sequence flow? If you did call repositoryService.saveModel then potentially every process instance might try to update the model when it hits the decision/jump point. If you had a lot of process instances and they were all jumping then they would all be trying to update the same database record. If the number of concurrent process instances were high this could maybe be a bit slow. It seems you are not having any problem with this. I am just asking out of curiosity. Feel free to chat on Activiti/Activiti7 - Gitter  if that is easier for you.

Thank you for your questions.

1.I think the approach is against the principle of Activiti, but I have to do like this with the bpmn diagram (no gateway to front node). 

2.I haven't saving the change to BpmnModel (I didn't call repositorySercie.saveModel), so it only affects the current process instance. Specific for, it depends on the scope of SequenceFlow. In my code, the SequenceFlow is a block variable of first if. In other words, I didn't persisting the BpmnModel to db, so other ongoing and new process instance still follow the rule of process definition (bpmn diagram).

3. I really didn't think about the number of concurrent process instances, I will test it. Thank you for your reminder.

hubiao
Champ in-the-making
Champ in-the-making

I tested in the project, this code is invalid ah!

Is your code finished?

hubiao
Champ in-the-making
Champ in-the-making

What did you draw with this? Can you share the tools you use and the XML?