@tachybase/plugin-workflow-approval
Version:
Approval base in Workflow
223 lines (222 loc) • 9.17 kB
JavaScript
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)()
};
}
}