const { convertStringToJson } = require("./util"); const getAllProcesses = async (workflow, query = {}) => { const processes = await bpmsDB.bpms_process.findAll({ where: { workflowId: workflow.id, ...query // type:{ // [Op.in]:[0,1] // } }, order: [ ['id', 'ASC'] ], attributes: [ "id", "pid", "link", "type", "name", "conditions", "subFlowPid", "subFlowId" ], raw: true }); return processes; } function getProcessPaths(data, workflow) { const invalidPathsWithoutEnding = []; const nodesMap = data.reduce((map, node) => { map[node.id.toString()] = node; return map; }, {}); const subFlowParentIds = []; // const childrenMap = data.reduce((map, node) => { // const pid = node.pid; // if (pid !== null && pid !== undefined) { // if (!map[pid]) map[pid] = []; // map[pid].push(node); // } // return map; // }, {}); const startNodes = data.filter(node => ((node.type === 0 || node.type === 1) && node.pid === null)); // console.log("startNodes", startNodes) if (startNodes?.length === 0 || !startNodes) { invalidPathsWithoutEnding.push({ path: null, data: null, workflow: workflow.id, error: "هیچ پروسسی برای استارت این ورک فلو وجود ندارد" }); return { allPaths: [], subFlowParentIds: [], invalidPathsWithoutEnding }; } let allPaths = []; const pathSet = new Set(); //for delete duplicated paths function isUniquePath(path) { const pathString = path.map(n => n.id).join(','); if (pathSet.has(pathString)) return false; pathSet.add(pathString); return true; } function traverse(currentNode, currentPath, visited) { // if (currentNode.type === 99) { // in bekhatere in ezaf shod ke mikhastim gozaresh ha ro nadide begirim felan // if(isUniquePath([...currentPath])){ // // allPaths.push({path:[...currentPath].map(n => n.id),data:mergedData}); // invalidPathsWithoutEnding.push({path:[...currentPath].map(n => n.id),data:mergedData}); // } // return; // } // const date = Date.now(); // console.time(date); const newPath = [...currentPath, currentNode]; const newVisited = { ...visited }; const nodeIdStr = currentNode.id.toString(); const visitCount = newVisited[nodeIdStr] || 0; if (visitCount >= 2) { // console.timeEnd(date); return; } newVisited[nodeIdStr] = visitCount + 1; // const newMergedData = [...mergedData] // newMergedData.push({ // processId: currentNode.id.toString(), // // condition: convertStringToJson(currentNode.conditions) // }); if (currentNode.type === 99 || currentNode.type === 100 || currentNode.subFlowPid) { if (currentNode.subFlowPid && !subFlowParentIds.includes(currentNode.subFlowPid)) subFlowParentIds.push(currentNode.subFlowPid) // allPaths.push(newPath.map(n => n.id)); if (isUniquePath(newPath)) { allPaths.push(newPath.map(n => n.id).join(",")); } // console.timeEnd(date); return; } const children = data.filter(node => node.pid == nodeIdStr); // console.log("3 data:",children,nodeIdStr,data) const linkNodes = []; if (currentNode.link) { currentNode.link.split(',').forEach(id => { const linkedNode = nodesMap[id]; if (linkedNode) { linkNodes.push(linkedNode); } }); } const nextNodes = [...children, ...linkNodes]; // console.timeEnd(date); if (nextNodes?.length === 0) { if (isUniquePath(newPath)) { // allPaths.push({path:newPath.map(n => n.id),data:newMergedData}); invalidPathsWithoutEnding.push({ path: newPath.map(n => n.id), // data: newMergedData, error: "ورک فلو در این مسیر به پایان نرسید" }); } return; } nextNodes.forEach(nextNode => { traverse(nextNode, newPath, newVisited); }); } for (let startNode of startNodes) { traverse(startNode, [], {}); } // console.log("allPaths:",allPaths.length); // allPaths = [...new Set( // allPaths.map((path,pindex)=>{ // return path.path.join(",") // }) // )].map((newPath,index)=>{ // return newPath.split(",") // }) // console.log("allPaths after:",allPaths.length); // return allPaths.map((a,aindex)=>{ // return a.map((b,bindex)=>{ // return nodesMap[b.toString()].name // }) // }); return { allPaths:[...new Set(allPaths)], subFlowParentIds, invalidPathsWithoutEnding }; } function getProcessPathsSubFlow(data, subFlowIdTemp, workflow) { const invalidSubPathsWithoutEnding = []; const nodesMap = data.reduce((map, node) => { map[node.id.toString()] = node; return map; }, {}); // const childrenMap = data.reduce((map, node) => { // const pid = node.pid; // if (pid !== null && pid !== undefined) { // if (!map[pid]) map[pid] = []; // map[pid].push(node); // } // return map; // }, {}); let subTreePath = []; const startNodes = data.filter(node => ((node.type === 0 || node.type === 1) && node.pid === null) || (node.subFlowPid == subFlowIdTemp)); // console.log("startNodes",startNodes) if (startNodes?.length === 0 || !startNodes) { // return []; invalidSubPathsWithoutEnding.push({ path: null, data: null, workflow: workflow.id, subworkflow: subFlowIdTemp, error: "هیچ پروسس استارتی برای این ورک فلو وجود ندارد" }); return { subTreePath: [], invalidSubPathsWithoutEnding }; } const pathSet = new Set(); //for delete duplicated paths function isUniquePath(path) { const pathString = path.map(n => n.id).join(','); if (pathSet.has(pathString)) return false; pathSet.add(pathString); return true; } function traverse(currentNode, currentPath, visited) { // if (currentNode.type === 99) { // in bekhatere in ezaf shod ke mikhastim gozaresh ha ro nadide begirim felan // if(isUniquePath([...currentPath])){ // // allPaths.push({path:[...currentPath].map(n => n.id),data:mergedData}); // invalidPathsWithoutEnding.push({path:[...currentPath].map(n => n.id),data:mergedData}); // } // return; // } // const date = `sub${subFlowIdTemp}-${Date.now()}`; // console.time(date); const newPath = [...currentPath, currentNode]; const newVisited = { ...visited }; const nodeIdStr = currentNode.id.toString(); const visitCount = newVisited[nodeIdStr] || 0; if (visitCount >= 2) { // console.timeEnd(date); return; } newVisited[nodeIdStr] = visitCount + 1; // const newMergedData = [...mergedData] // newMergedData.push({ // processId: currentNode.id.toString(), // // condition: convertStringToJson(currentNode.conditions) // }); if (currentNode.type === 99 || currentNode.type === 100 // || currentNode.subFlowPid it will be uncommented when we want go to final subflowPid ) { // allPaths.push(newPath.map(n => n.id)); if (isUniquePath(newPath)) { subTreePath.push( newPath.map(n => n.id).join(",")); } // console.timeEnd(date); return; } const children = data.filter(node => node.pid == nodeIdStr); // console.log("3 data:",children,nodeIdStr,data) const linkNodes = []; if (currentNode.link) { currentNode.link.split(',').forEach(id => { const linkedNode = nodesMap[id]; if (linkedNode) { linkNodes.push(linkedNode); } }); } const nextNodes = [...children, ...linkNodes]; // console.timeEnd(date); if (nextNodes?.length === 0) { if (isUniquePath(newPath)) { // allPaths.push({path:newPath.map(n => n.id),data:newMergedData}); invalidSubPathsWithoutEnding.push( { path: newPath.map(n => n.id), // data: newMergedData, error: "هیچ پروسس پایانی برای این ورک فلو وجود ندارد" } ); } return; } nextNodes.forEach(nextNode => { traverse(nextNode, newPath, newVisited); }); } for (let startNode of startNodes) { traverse(startNode, [], {}); } // console.log("allPaths:",allPaths.length); // console.log("allPaths:",allPaths.length); // allPaths = [...new Set( // allPaths.map((path,pindex)=>{ // return path.path.join(",") // }) // )].map((newPath,index)=>{ // return newPath.split(",") // }) // console.log("allPaths after:",allPaths.length); // return allPaths.map((a,aindex)=>{ // return a.map((b,bindex)=>{ // return nodesMap[b.toString()].name // }) // }); return { subTreePath:[...new Set(subTreePath)], invalidSubPathsWithoutEnding }; } module.exports = { getAllProcesses, getProcessPaths, getProcessPathsSubFlow }