import { ICommon_Model_Field_Solution_Workflow_Node_Field_Type } from "../../../common/model/field_solution_workflow_node_field_type"; import { ICommon_Model_Field_Type } from "../../../common/model/field_type"; import { ICommon_Model_Field_Type_Config_Value } from "../../../common/model/field_type_config_value"; import { ICommon_Model_Workflow, workflowModel } from "../../../common/model/workflow"; import { workflowActionModel } from "../../../common/model/workflow_action"; import { ICommon_Model_Workflow_Solution, workflowSolutionModel } from "../../../common/model/workflow_solution"; import { ICommon_Route_Res_Workflow_Info, ICommon_Route_Res_Workflow_Info_Action, ICommon_Route_Res_Workflow_Info_Node } from "../../../common/routes/response"; import { Err } from "../../../common/status/error"; import { Entity } from "../../common/entity/entity"; import { EServer_Common_Event_Types } from "../../common/event/types"; import { ECommon_Model_Workflow_Node_Status, ICommon_Model_Workflow_Node, workflowNodeModel } from './../../../common/model/workflow_node'; import { ICommon_Route_Res_WorkflowSolution_Info } from './../../../common/routes/response'; import { workflowActionMapper, workflowMapper, workflowNodeMapper, workflowSolutionMapper } from './../mapper/workflow'; import { FieldSolutionService } from './field'; export default class Workflow extends Entity { constructor(){ super(workflowMapper) } static async list(organizationId:string){ let ret=await workflowMapper.list(organizationId) return ret; } static async getReservedItem (organizationId:string) { let ret=await workflowMapper.getReservedItem(organizationId) let workflow=new Workflow workflow.setItem(ret); return workflow; } override async create(): Promise { let obj=await super.create() let workflowNode=new WorkflowNodeService workflowNode.assignItem({ name:"Open", workflow_id:obj.id, status:ECommon_Model_Workflow_Node_Status.NOTSTART }) await workflowNode.create() return obj; } async accessNodesAndActions(fieldsCallback:(nodeId:string)=>Promise<{ field:ICommon_Model_Field_Solution_Workflow_Node_Field_Type, fieldType:ICommon_Model_Field_Type, values?:ICommon_Model_Field_Type_Config_Value[] }[]>=null):Promise { let nodeList=await workflowMapper.nodeList(this.getId()); let actionList=await workflowMapper.actionList(this.getId()); let arrNodeId:string[]=[]; async function _exec(node:ICommon_Route_Res_Workflow_Info_Node):Promise { if(node==null) { let firstNode:ICommon_Model_Workflow_Node; for(let obj of nodeList) { if(obj.status==ECommon_Model_Workflow_Node_Status.NOTSTART) { firstNode=obj; break } } if(firstNode) { let objNode:ICommon_Route_Res_Workflow_Info_Node={ node:firstNode, actions:[] } if(fieldsCallback) { objNode.fields=await fieldsCallback(firstNode.id); } arrNodeId.push(firstNode.id) await _exec(objNode) return objNode; } } else { if(!node.actions) { node.actions=[] } for(let obj of actionList) { if(obj.source_node_id==node.node.id) { let objAction:ICommon_Route_Res_Workflow_Info_Action={ action:obj, destNode:null } for(let obj1 of nodeList) { if(obj1.id==obj.dest_node_id) { objAction.destNode={ node:obj1, actions:[] } if(fieldsCallback) { objAction.destNode.fields=await fieldsCallback(obj1.id); } if(!arrNodeId.includes(obj1.id)) { arrNodeId.push(obj1.id) await _exec(objAction.destNode) } } } node.actions.push(objAction) } } } } let ret=await _exec(null) return ret; } async info():Promise { let obj:ICommon_Route_Res_Workflow_Info={ ...this.getItem(), data: { nodes:[], actions:[] } }; obj.data.nodes=await workflowMapper.nodeList(this.getId()); obj.data.actions=await workflowMapper.actionList(this.getId()); return obj; } override async delete(eventPulish?: EServer_Common_Event_Types.Types): Promise { await super.delete() await workflowMapper.revoke(this.getId(),this.getItem().organization_id) await FieldSolutionService.clearItemsByWorkflowId(this.getId()) } override async copy(deletedFields?: (keyof ICommon_Model_Workflow)[]): Promise { let objNew=await super.copy() await workflowMapper.copyItem(this.getId(),objNew.getId()); return objNew } async checkNode(workflowNodeId:string) { let ret=await workflowMapper.checkNode(this.getId(),workflowNodeId) return ret; } async checkAction(workflowActionId:string) { let ret=await workflowMapper.checkAction(this.getId(),workflowActionId) return ret; } async getFirstNode(){ let ret=await workflowNodeMapper.getOpenNode(this.getId()) return ret; } static async init(organizationId:string) { let workflowId=await workflowMapper.init(organizationId); return workflowId; } } export class WorkflowSolutionService extends Entity { constructor(){ super(workflowSolutionMapper) } static async list(organizationId:string){ let ret=await workflowSolutionMapper.list(organizationId) return ret; } static async getItemByIssueTypeSolutionId(issueSolutionId:string) { let obj=await workflowSolutionMapper.getItemByIssueTypeSolutionId(issueSolutionId) if(obj) { let objService=new WorkflowSolutionService() objService.setItem(obj) return objService; } else { return null } } static async getItemListByWorkflowId(workflowId:string) { let ret=await workflowSolutionMapper.getItemsByWorkflowId(workflowId) return ret; } static async getReservedItem (organizationId:string) { let ret=await workflowSolutionMapper.getReservedItem(organizationId) let obj=new WorkflowSolutionService() obj.setItem(ret) return obj; } async bindIssueTypeSolutions(issueTypeSolutionIds:string[]) { let existIssueTypeSolutionIds=[]; for(let issueTypeSolutionId of issueTypeSolutionIds) { let arr=await workflowSolutionMapper.getItemsByIssueTypeSolutionId(issueTypeSolutionId) if(arr && arr.length>0) { existIssueTypeSolutionIds.push(issueTypeSolutionId) } } if(existIssueTypeSolutionIds.length>0) { await WorkflowSolutionService.clearIssueTypeSolutions(existIssueTypeSolutionIds) } await workflowSolutionMapper.bindIssueTypeSolutionList(this.getId(),issueTypeSolutionIds,this.getItem().organization_id) } async unbindIssueTypeSolutions(issueTypeSolutionIds:string[]=null) { await workflowSolutionMapper.unbindIssueTypeSolution(this.getId(),issueTypeSolutionIds) } static async clearIssueTypeSolutions(issueTypeSolutionIds:string[]) { await workflowSolutionMapper.clearIssueTypeSolution(issueTypeSolutionIds) } async resetIssueTypeSolutions(issueTypeSolutionIds:string[]=null) { if(this.getItem().reserved) { throw Err.Project.Workflow.unbindReservedWorkflowSolutionForbidden } await workflowSolutionMapper.unbindIssueTypeSolution(this.getId(),issueTypeSolutionIds) let objWorkflowReserved=await WorkflowSolutionService.getReservedItem(this.getItem().organization_id) objWorkflowReserved.bindIssueTypeSolutions(issueTypeSolutionIds) } async getIssueTypeAndWorkflowList() { let arr:ICommon_Route_Res_WorkflowSolution_Info["data"]=[] let objIssueTypeSolutionList=await workflowSolutionMapper.getIssueTypeSolutionList(this.getId()) for(let obj of objIssueTypeSolutionList) { arr.push({ issueTypeSolution:obj, data:await workflowSolutionMapper.workflowIssueTypeList(this.getId(),obj.id) }) } return arr; } async info():Promise { let info:ICommon_Route_Res_WorkflowSolution_Info={ ...this.getItem(), data:[] } let objIssueTypeSolutionList=await workflowSolutionMapper.getIssueTypeSolutionList(this.getId()) for(let obj of objIssueTypeSolutionList) { info.data.push({ issueTypeSolution:obj, data:await workflowSolutionMapper.workflowIssueTypeList(this.getId(),obj.id) }) } return info; } async assign(issueTypeId:string,workflowId:string,issueTypeSolutionId:string) { let workflow=await Workflow.getItemById(workflowId) if(!workflow) { throw Err.Project.Workflow.workflowNotFound } let isIn=await this.checkWorkflow(workflowId) if(!isIn) { throw Err.Project.Workflow.workflowNotInWorkflowSolution } await workflowSolutionMapper.assign(this.getId(),workflowId,issueTypeId,issueTypeSolutionId); } async getWorkflowByIssueTypeId(issueTypeId:string,issueTypeSolutionId:string) { let ret=await workflowSolutionMapper.getWorkflowByIssueTypeId(this.getId(),issueTypeId,issueTypeSolutionId); return ret; } override async create(): Promise { let ret=await super.create() let obj=await workflowMapper.getReservedItem(ret.organization_id) await workflowSolutionMapper.addWorkflow(this.getId(),obj.id) return ret } override async copy(): Promise { let workflowList=await this.listWorkflow() let obj=await super.copy() for(let o of workflowList) { await workflowSolutionMapper.addWorkflow(obj.getId(),o.id); } return obj; } async listWorkflow() { let ret=await workflowSolutionMapper.listWorkflow(this.getId()) return ret; } async checkWorkflow(workflowId:string) { let isIn=await workflowSolutionMapper.checkWorkflow(this.getId(),workflowId) return isIn } async addWorkflow(workflowId:string) { let isIn=await this.checkWorkflow(workflowId) if(isIn) { throw Err.Project.Workflow.workflowAlreadyInWorkflowSolution } await workflowSolutionMapper.addWorkflow(this.getId(),workflowId) } async removeWorkflow(workflowId:string) { await workflowSolutionMapper.removeWorkflow(this.getId(),workflowId) await FieldSolutionService.clearItemsByWorkflowIdAndWorkflowSolutionId(workflowId,this.getId()) } override async delete() { await super.delete(); await workflowSolutionMapper.deleteItemsByWorkflowSolutionId(this.getId()); await workflowSolutionMapper.unbindIssueTypeSolution(this.getId()) await FieldSolutionService.clearItemsByWorkflowSolutionId(this.getId()) } async deleteIssueType(issueTypeId:string,issueTypeSolutionId:string) { await workflowSolutionMapper.deleteIssueType(this.getId(),issueTypeId,issueTypeSolutionId) } static async clearIssueType(issueTypeId:string) { await workflowSolutionMapper.clearIssueType(issueTypeId); } async checkWorkFlowAndNodeRelation(workflowId:string,workflowNodeId:string) { if(!workflowNodeId) { throw Err.Project.Workflow.workflowNodeNotFound } else if(!workflowId) { throw Err.Project.Workflow.workflowNotFound } let workflowNode=await WorkflowNodeService.getItemById(workflowNodeId) if(!workflowNode) { return false } let workflow=await Workflow.getItemById(workflowId) if(!workflow) { return false } let isIn=await workflow.checkNode(workflowNodeId) if(!isIn) { return false } isIn=await this.checkWorkflow(workflowId) if(!isIn) { return false } return true } static async clearByOrganizationId(organizationId:string){ await workflowSolutionMapper.clearByOrganizationId(organizationId) } static async init(issueTypeSolutionId:string,issueTypeSolutionName:string,issueTypeTaskId:string,issueTypeBugId:string,issueTypeTicketId:string,workflowId:string,organizationId:string) { await workflowSolutionMapper.init(issueTypeSolutionId,issueTypeSolutionName,issueTypeTaskId,issueTypeBugId,issueTypeTicketId,workflowId,organizationId) } } export class WorkflowNodeService extends Entity { constructor() { super(workflowNodeMapper) } override async create(): Promise { if(this.getItem().status==ECommon_Model_Workflow_Node_Status.NOTSTART || this.getItem().status===undefined) { let obj=await workflowNodeMapper.getOpenNode(this.getItem().workflow_id) if(obj) { throw Err.Project.Workflow.workflowOpenNodeDuplicate } } let ret=await super.create() return ret; } override async update(): Promise { if(this.getItem().status==ECommon_Model_Workflow_Node_Status.NOTSTART) { let obj=await workflowNodeMapper.getOpenNode(this.getItem().workflow_id) if(obj && obj.id!=this.getId()) { throw Err.Project.Workflow.workflowOpenNodeDuplicate } } let ret=await super.update() return ret; } override async delete(eventPulish?: EServer_Common_Event_Types.Types): Promise { await super.delete() await FieldSolutionService.clearItemsByWorkflowNodeId(this.getId()) } async getActionList() { let ret=await workflowNodeMapper.getActionList(this.getId()) return ret; } } export class WorkflowActionService extends Entity { constructor() { super(workflowActionMapper) } }