Replies: 15 comments
-
I figure out there is 'hack' way like:
seems bpmn-server won't override data with |
Beta Was this translation helpful? Give feedback.
-
Please send your Bpmn file will investigate Sent from my iPhoneOn Mar 21, 2024, at 6:26 AM, Ks Tan ***@***.***> wrote:
I figure out there is 'hack' way like: @Techer[data.teacher._id]
Then at bpmn won't override it, I'm manually apply string replace or regex outside. However it seems not a long term solution
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
I'm not file a bug report, just wish to ask any "official" way to resolve user from the bpmn user task and that updated information can save into database permanently. Base on above sample, i created my own way methods to convert teacher (@teacher[$data.teacher._id]). it willl run custom code to find user who have same email with the teacher, then I wish to save the teacher's userid into items. this.bpmnServer.listener.on(
'all',
async (event) => await this.applyEventListener(event),
);
async applyEventListener(event){
.. ... many codes
//if is user task event under wait status
const assignee = await this.userResolver(appuser, event.context.item.assignee,data,);
const candidateUsers = await this.userResolver( appuser, event.context.item.candidateUsers, data,);
const candidateGroups = await this.userResolver( appuser,vent.context.item.candidateGroups,data,);
//i cant override this 3 properties and let bpmnserver save into database
event.context.item.assignee = assignee
event.context.item.candidateUsers = candidateUsers
event.context.item.candidateGroups =candidateGroups
//send email notification
//run others codes
}
// sample userids = ['@teacher[$data.teacher._id]','@user[$data.createdBy], ]
async userResolver( appuser: UserContext, userids: string | string[] | undefined, data: any,) {
if (!userids) return undefined;
if (typeof userids == 'string') userids = [userids];
if (!Array.isArray(userids)) return undefined;
const newids: string[] = [];
for (let i = 0; i < userids.length; i++) {
let uid = userids[i].trim();
// require convert teacher/student to real user
if (uid.substring(0, 1) == '@' && uid.includes('[') && uid.includes(']')) {
const regextype = /(?<=\@)(.*?)(?=\[)/;
const regexvalue = /(?<=\[)(.*?)(?=\])/;
const usertype = uid.match(regextype)[0].trim(); //obtain teacher/user
const typevalue = uid.match(regexvalue)[0].trim(); // obtain $data.teacher._id , $data.createdBy
let idvalue = '';
// read $data.teacher._id , $data.createdBy from "data"
if (typevalue.substring(0, 6) == '$data.') {
const fieldpath = typevalue.replace('$data.', '');
idvalue = this.readFieldFromData(fieldpath, data);
}
//convert become real uid using external resolver (such as teacher/student execute different resolver)
uid = await this.userResolverService.resolve(
appuser,
usertype,
idvalue,
data,
);
}
//either convert become user's uuid, or remove it when the teacher cannot resolve
if (uid) newids.push(uid);
}
return newids; //after return, wish to save into mongodb instance's usertask item
}
readFieldFromData(path: string, data: any) {
return path.split('.').reduce((o, i) => o[i], data);
} here is the xml <?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
<bpmn:process id="errohandle" name="errors handler" isExecutable="false">
<bpmn:startEvent id="StartEvent_1" name="update schedule">
<bpmn:outgoing>Flow_1pg0fnn</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_1pg0fnn" sourceRef="StartEvent_1" targetRef="tryerror" />
<bpmn:endEvent id="Event_1o6o4k2">
<bpmn:incoming>Flow_170a071</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_170a071" sourceRef="teacheracknowledge" targetRef="Event_1o6o4k2" />
<bpmn:userTask id="teacheracknowledge" name="teacher acknowledge" camunda:assignee="@teacher[$data.teacher._id]">
<bpmn:incoming>Flow_0i8h61u</bpmn:incoming>
<bpmn:outgoing>Flow_170a071</bpmn:outgoing>
</bpmn:userTask>
<bpmn:sequenceFlow id="Flow_0i8h61u" sourceRef="tryerror" targetRef="teacheracknowledge" />
<bpmn:serviceTask id="tryerror" name="try error">
<bpmn:incoming>Flow_1pg0fnn</bpmn:incoming>
<bpmn:outgoing>Flow_0i8h61u</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:boundaryEvent id="Event_1x43azn" attachedToRef="tryerror">
<bpmn:outgoing>Flow_0ujgdj5</bpmn:outgoing>
<bpmn:errorEventDefinition id="ErrorEventDefinition_1jljctq" />
</bpmn:boundaryEvent>
<bpmn:sequenceFlow id="Flow_0ujgdj5" sourceRef="Event_1x43azn" targetRef="errorhandler" />
<bpmn:serviceTask id="errorhandler" name="error handler">
<bpmn:incoming>Flow_0ujgdj5</bpmn:incoming>
<bpmn:outgoing>Flow_0xn22s3</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:endEvent id="Event_1lr7684">
<bpmn:incoming>Flow_0xn22s3</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0xn22s3" sourceRef="errorhandler" targetRef="Event_1lr7684" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="errohandle">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="122" y="102" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="100" y="145" width="81" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1o6o4k2_di" bpmnElement="Event_1o6o4k2">
<dc:Bounds x="632" y="102" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1vu7axv_di" bpmnElement="teacheracknowledge">
<dc:Bounds x="400" y="80" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0vrmgin_di" bpmnElement="tryerror">
<dc:Bounds x="200" y="80" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_12q3140_di" bpmnElement="errorhandler">
<dc:Bounds x="320" y="200" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1lr7684_di" bpmnElement="Event_1lr7684">
<dc:Bounds x="472" y="222" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0nov24y_di" bpmnElement="Event_1x43azn">
<dc:Bounds x="232" y="142" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1pg0fnn_di" bpmnElement="Flow_1pg0fnn">
<di:waypoint x="158" y="120" />
<di:waypoint x="200" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_170a071_di" bpmnElement="Flow_170a071">
<di:waypoint x="500" y="120" />
<di:waypoint x="632" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0i8h61u_di" bpmnElement="Flow_0i8h61u">
<di:waypoint x="300" y="120" />
<di:waypoint x="400" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0ujgdj5_di" bpmnElement="Flow_0ujgdj5">
<di:waypoint x="250" y="178" />
<di:waypoint x="250" y="240" />
<di:waypoint x="320" y="240" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0xn22s3_di" bpmnElement="Flow_0xn22s3">
<di:waypoint x="420" y="240" />
<di:waypoint x="472" y="240" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
|
Beta Was this translation helpful? Give feedback.
-
cause above code happen during doEvent start (or others which before save), so |
Beta Was this translation helpful? Give feedback.
-
I don't understand why is your item.assignee='user1'; call api from inside the event does not work |
Beta Was this translation helpful? Give feedback.
-
[samples]
[workflow]
I saw example |
Beta Was this translation helpful? Give feedback.
-
I think i can conclude my observation as this:
"$" working fine, and "#" doesn't. since we need async call to read database, thats the reason i keep failing. |
Beta Was this translation helpful? Give feedback.
-
sorry, you are having problems with this:
I am on the road right now, but will investigate this further in couple of days |
Beta Was this translation helpful? Give feedback.
-
seems during evaluate at
result = Function(js).bind(scope)(); have issue with |
Beta Was this translation helpful? Give feedback.
-
ok, seems it is bugs during process Just, I have a few comment:
Hope above comment helpful |
Beta Was this translation helpful? Give feedback.
-
Thanks for this feedback.
|
Beta Was this translation helpful? Give feedback.
-
I have to point out that bpmn-server is not using eval but using |
Beta Was this translation helpful? Give feedback.
-
Thanks of clarification. I don't have computer to prove now but I would like to say don't create room for execute script at every places. Just allow it on script task. I worry user task able to execute some of below code $(throw 'error') The field of bpmn like user task assigned shall only allow access to specific data, or method similar like "getter", give them room to insert js freely maybe harmful |
Beta Was this translation helpful? Give feedback.
-
But keep in mind that is code must be in either the bpmn model or appServices and both cases is protected. In other words the end-user has no access to this code nor can modify it |
Beta Was this translation helpful? Give feedback.
-
In latest release 2.2.4, you can now do this:
Where in appServices.ts: /**
* Sample Code for Leave Application
* to demonstrate how to access DB and return results into scripts
* This is called as such:
* assignee #(appServices.getSupervisorUser(this.data.requester))
*
* @param userName
* @param context
* @returns
*/
async getSupervisorUser(userName, context) {
console.log('getSupervisorUser for:',userName);
let ds=this.appDelegate.server.dataStore;
const dburl=ds.dbConfiguration.db; // process.env.MONGO_DB_URL;
const db=ds.dataStore.db;
// collection structure: {employee,manager}
let list=await db.find(dburl,'usersManager',{employee:userName});
let manager;
if (list.length>0)
manager=list[0]['manager'];
return manager;
} |
Beta Was this translation helpful? Give feedback.
-
I have plenty of scenario look common in real world but quite challenging to implement viauser task, wish to find solution.
1 example as below:
assume I have multiple group of users such as:
I have multiple mongodb collection such as
users (real user database who can login the application, cashers, teachers, and branch managers store in this collection)
teachers (master list of teachers)
student (master list of students)
schedules (class schedule, it store student name list, the teacherid)
Assume when class date/time change we wish to notify teachers and students.
refer to above bpmn and image, you can see that
schedule
record consist ofteacher
. However theteacher
is master data, not real user. The only thing can match user and teacher is email, but we won't save email into schedule. So, during prepare bpmn we can't define correct user identity.There is many scenario have similar case such as
students
parents
salesagent
they stored in different collection but consder
human
, play role in business processes. It is impossible to obtain suitable user info fromdata
cause it too dynamic. Seems I need special user resolver as below strategy:then I can create suitable methods outside to resolve the real user for that teacher, and send the notification/pusher message.
Any advise to implement this?
Beta Was this translation helpful? Give feedback.
All reactions