UNPKG

@tachybase/plugin-workflow-approval

Version:

Approval base in Workflow

223 lines (222 loc) 9.17 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var Approval_exports = {}; __export(Approval_exports, { default: () => ApprovalInstruction }); module.exports = __toCommonJS(Approval_exports); var import_module_workflow = require("@tachybase/module-workflow"); var import_server = require("@tego/server"); var import_status = require("../constants/status"); var import_Approval = __toESM(require("../triggers/Approval")); var import_tools = require("./tools"); class ApprovalInstruction extends import_module_workflow.Instruction { async run(node, prevJob, processor) { const job = await processor.saveJob({ status: import_module_workflow.JOB_STATUS.PENDING, nodeId: node.id, nodeKey: node.key, upstreamId: (prevJob == null ? void 0 : prevJob.id) ?? null }); const assignees = await (0, import_tools.parseAssignees)(node, processor); const { db } = processor.options.plugin; const ApprovalRepo = db.getRepository("approvals"); const approval = await ApprovalRepo.findOne({ filter: { "executions.id": processor.execution.id }, fields: ["id", "status", "data", "summary", "collectionName"], appends: ["approvalExecutions", "createdBy"], except: ["data"] }); const approvalExecution = approval.approvalExecutions.find((item) => item.executionId === processor.execution.id); if ([import_status.APPROVAL_STATUS.RESUBMIT, import_status.APPROVAL_STATUS.DRAFT].includes(approval.status)) { return job; } const RecordModel = db.getModel("approvalRecords"); await RecordModel.bulkCreate( assignees.map((userId, index) => { var _a; return { approvalId: approval.id, approvalExecutionId: approvalExecution.id, createdById: (_a = approval.createdBy) == null ? void 0 : _a.id, userId, jobId: job.id, nodeId: node.id, executionId: job.executionId, workflowId: node.workflowId, index, status: node.config.order && index ? import_status.APPROVAL_ACTION_STATUS.ASSIGNED : import_status.APPROVAL_ACTION_STATUS.PENDING, snapshot: approvalExecution.snapshot, summary: approval.summary, collectionName: approval.collectionName }; }), { transaction: processor.transaction } ); for (const userId of assignees) { const [dataSourceName] = (0, import_server.parseCollectionName)(approval.collectionName); const collection = this.workflow.app.dataSourceManager.dataSources.get(dataSourceName).collectionManager.getCollection(approval.collectionName); const message = { userId, title: '{{t("Approval", { ns: "workflow-approval" })}}', content: "", collectionName: approval.collectionName, jsonContent: approval.summary, schemaName: node.config.applyDetail, dataKey: approval.data[collection.filterTargetKey] }; this.workflow.app.messageManager.sendMessage(+userId, message); } return job; } async resume(node, job, processor) { if (job.nodeId !== node.id) { const nodeJob = processor.findBranchParentJob(job, node); if (job.status === import_module_workflow.JOB_STATUS.RESOLVED) { const jobNode = processor.nodesMap.get(job.nodeId); const branchStart = processor.findBranchStartNode(jobNode); if (branchStart.branchIndex === import_status.APPROVAL_ACTION_STATUS.RETURNED) { nodeJob.set("status", import_module_workflow.JOB_STATUS.RETRY_NEEDED); } else if (branchStart.branchIndex === import_status.APPROVAL_ACTION_STATUS.REJECTED && node.config.endOnReject) { nodeJob.set("status", import_module_workflow.JOB_STATUS.REJECTED); } return nodeJob; } return processor.exit(job.status); } const { branchMode, negotiation, order } = node.config; const assignees = await (0, import_tools.parseAssignees)(node, processor); const RecordRepo = this.workflow.app.db.getRepository("approvalRecords"); const records = await RecordRepo.find({ filter: { jobId: job.id }, appends: ["approval"], except: ["snapshot"], sort: ["index"], transaction: processor.transaction }); const distribution = records.reduce((prev, record) => { const item = prev.find((item2) => item2.status === record.status); if (item) { item.count += 1; } else { prev.push({ status: record.status, count: 1 }); } return prev; }, []); const processing = Boolean(distribution.find((item) => item.status !== import_status.APPROVAL_ACTION_STATUS.PENDING)); const status = (0, import_tools.getNegotiationMode)(+negotiation).getStatus(distribution, assignees, negotiation) ?? import_module_workflow.JOB_STATUS.PENDING; const result = import_tools.ApprovalJobStatusMap[status]; processor.logger.debug(`approval resume job and next status: ${status}`); job.set({ status: status && status !== import_module_workflow.JOB_STATUS.CANCELED ? branchMode ? import_module_workflow.JOB_STATUS.RESOLVED : status : status, result }); if (status && status !== import_module_workflow.JOB_STATUS.CANCELED || negotiation && processing) { await job.latestUserJob.approval.update( { status: import_status.APPROVAL_STATUS.PROCESSING }, { transaction: processor.transaction } ); } const nextAssignee = assignees[assignees.indexOf(job.latestUserJob.userId) + 1]; if (!status && negotiation && order && nextAssignee) { await RecordRepo.update({ values: { status: import_status.APPROVAL_ACTION_STATUS.PENDING }, filter: { jobId: job.id, userId: nextAssignee }, transaction: processor.transaction }); } if (branchMode) { const branchNode = processor.nodes.find((item) => item.upstream === node && item.branchIndex === result); if (branchNode) { await processor.saveJob(job); await processor.run(branchNode, job); return null; } } try { const approval = records[0].approval; const [dataSourceName, collectionName] = (0, import_server.parseCollectionName)(approval.collectionName); const { repository } = this.workflow.app.dataSourceManager.dataSources.get(dataSourceName).collectionManager.getCollection(collectionName); const workflow = await approval.getWorkflow({ where: { id: approval.get("workflowId"), type: import_Approval.default.TYPE, enabled: true, "config.collection": approval.collectionName }, transaction: processor.transaction }); const data = await repository.findOne({ filterByTk: approval.get("dataKey"), appends: workflow.config.appends, transaction: this.workflow.useDataSourceTransaction(dataSourceName, processor.transaction) }); await RecordRepo.update({ values: { snapshot: (0, import_module_workflow.toJSON)(data) }, filter: { jobId: job.id }, transaction: processor.transaction }); } catch (error) { console.log("%c Line:269 \u{1F95B} error", error); } return job; } async duplicateConfig(node, { transaction }) { const uiSchemaRepo = this.workflow.app.db.getRepository("uiSchemas"); if (!node.config.applyDetail) { return node.config; } const result = await uiSchemaRepo.duplicate(node.config.applyDetail, { transaction }); return { ...node.config, applyDetail: (result == null ? void 0 : result["x-uid"]) ?? (0, import_server.uid)() }; } }