UNPKG

@tachybase/plugin-workflow-approval

Version:

Approval base in Workflow

267 lines (266 loc) 9.39 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; 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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var approvals_exports = {}; __export(approvals_exports, { approvals: () => approvals }); module.exports = __toCommonJS(approvals_exports); var import_module_workflow = require("@tachybase/module-workflow"); var import_server = require("@tego/server"); var import_constants = require("../../common/constants"); var import_status = require("../constants/status"); var import_tools = require("../tools"); const approvals = { async create(context, next) { const { status, collectionName, data, workflowId, workflowKey } = context.action.params.values ?? {}; const [dataSourceName, cName] = (0, import_server.parseCollectionName)(collectionName); const dataSource = context.app.dataSourceManager.dataSources.get(dataSourceName); if (!dataSource) { return context.throw(400, `Data source "${dataSourceName}" not found`); } const collection = dataSource.collectionManager.getCollection(cName); if (!collection) { return context.throw(400, `Collection "${cName}" not found`); } let workflow; if (workflowKey) { workflow = await context.db.getRepository("workflows").findOne({ filter: { key: workflowKey, enabled: true } }); } else { workflow = await context.db.getRepository("workflows").findOne({ filterByTk: workflowId }); } if (!workflow) { return context.throw(400, "Current workflow not found or disabled, please refresh and try again"); } if (status !== import_status.APPROVAL_STATUS.DRAFT) { context.action.mergeParams({ values: { status: import_status.APPROVAL_STATUS.SUBMITTED } }); } const { repository, model } = collection; const values = await repository.create({ values: { ...(0, import_server.traverseJSON)(data, { collection }), createdBy: context.state.currentUser.id, updatedBy: context.state.currentUser.id }, context }); const instance = values.get(); const summary = (0, import_tools.getSummary)({ summaryConfig: workflow.config.summary, data: { ...instance, ...data } }); Object.keys(model.associations).forEach((key) => { delete instance[key]; }); context.action.mergeParams({ values: { collectionName, data: instance, dataKey: values[collection.filterTargetKey], workflowKey: workflow.key, workflowId: workflow.id, applicantRoleName: context.state.currentRole, summary } }); return import_server.actions.create(context, next); }, async update(context, next) { const { collectionName, data, status, updateAssociationValues, summaryConfig } = context.action.params.values ?? {}; const [dataSourceName, cName] = (0, import_server.parseCollectionName)(collectionName); const dataSource = context.app.dataSourceManager.dataSources.get(dataSourceName); const collection = dataSource.collectionManager.getCollection(cName); const [target] = await collection.repository.update({ filterByTk: data[collection.filterTargetKey], values: data, updateAssociationValues }); const summary = (0, import_tools.getSummary)({ summaryConfig, data }); context.action.mergeParams({ values: { status: status ?? import_status.APPROVAL_STATUS.SUBMITTED, data, applicantRoleName: context.state.currentRole, summary } }); return import_server.actions.update(context, next); }, async destroy(context, next) { const { filterByTk, values: { status } } = context.action.params ?? {}; if (status !== import_status.APPROVAL_STATUS.DRAFT) { return context.throw(400); } const repository = import_server.utils.getRepositoryFromParams(context); const approval = await repository.findOne({ filterByTk, filter: { createdById: context.state.currentUser.id } }); if (!approval) { return context.throw(404); } return import_server.actions.destroy(context, next); }, async withdraw(context, next) { var _a; const { filterByTk } = context.action.params; const repository = import_server.utils.getRepositoryFromParams(context); const approval = await repository.findOne({ filterByTk, appends: ["workflow"], except: ["workflow.options"] }); if (!approval) { return context.throw(404); } if (approval.createdById !== ((_a = context.state.currentUser) == null ? void 0 : _a.id)) { return context.throw(403); } if (approval.status !== import_status.APPROVAL_STATUS.SUBMITTED || !approval.workflow.config.withdrawable) { return context.throw(400); } const [execution] = await approval.getExecutions({ where: { status: import_module_workflow.EXECUTION_STATUS.STARTED }, limit: 1 }); execution.workflow = approval.workflow; await context.db.sequelize.transaction(async (transaction) => { const records = await approval.getRecords({ where: { executionId: execution.id }, include: [ { association: "job", where: { status: import_module_workflow.JOB_STATUS.PENDING }, required: true } ], transaction }); await context.db.getRepository("approvalRecords").destroy({ filter: { id: records.map((record) => record.id) }, transaction }); const jobsMap = records.reduce((map, record) => { if (!map.has(record.job.id)) { record.job.execution = execution; record.job.latestUserJob = record.get(); record.job.latestUserJob.approval = approval; map.set(record.job.id, record.job); } return map; }, /* @__PURE__ */ new Map()); return Array.from(jobsMap.values()); }); context.body = approval; context.status = 202; await next(); await execution.update({ status: import_module_workflow.EXECUTION_STATUS.CANCELED }); }, async listCentralized(context, next) { const centralizedApprovalFlow = await context.db.getRepository("workflows").find({ filter: { type: "approval", "config.centralized": true }, fields: ["id"] }); context.action.mergeParams({ filter: { workflowId: centralizedApprovalFlow.map((item) => item.id) } }); return await import_server.actions.list(context, next); }, async reminder(context, next) { var _a, _b, _c; const { filterByTk } = context.action.params; const repository = import_server.utils.getRepositoryFromParams(context); const approval = await repository.findOne({ filterByTk, appends: ["records", "workflow", "createdBy.nickname"] }); if (!approval) { return context.throw(404); } if (approval.createdById !== ((_a = context.state.currentUser) == null ? void 0 : _a.id)) { return context.throw(403); } if ([import_status.APPROVAL_STATUS.APPROVED, import_status.APPROVAL_STATUS.REJECTED, import_status.APPROVAL_STATUS.ERROR].includes(approval.status)) { return context.throw(400); } if (((_b = approval.records) == null ? void 0 : _b.length) === 0) { return context.throw(400); } const assignees = approval.records.map((record) => record.userId); 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: '${import_constants.NAMESPACE}' })}}`, content: `{{t("{{user}} reminder", { ns: "${import_constants.NAMESPACE}", user: "${approval.createdBy.nickname}" })}}`, collectionName: approval.collectionName, jsonContent: approval.summary, schemaName: (_c = approval.workflow) == null ? void 0 : _c.config.applyDetail, dataKey: approval.data[collection.filterTargetKey] }; context.app.messageManager.sendMessage(+userId, message); } await next(); context.status = 200; context.body = { message: "reminder sent", success: true }; } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { approvals });