tuain-bpm-lib
Version:
Servicio de gestión de manejo de procesos de la plataforma Tuain
212 lines (204 loc) • 7.26 kB
JavaScript
const {
collections: {
execution: { processes: processColl },
},
// schemas: { execution: instanceSchemas },
dbQueries: {
execution: { process: processQueries },
},
process: {
elements: { task: TASK, gateway: GATEWAY, event: EVENT },
eventTypes: { start: START },
},
} = require('../../../config');
const modErrs = {
newProcessInstance: {
notStartEvent: ['01', 'No se encontró definición del evento de inicialización start'],
missingRequiredVariable: ['02', 'Variable requerida para iniciar el proceso no se encuentra'],
},
findInstance: {
notFound: ['01', 'No se encontró proceso con la información dada'],
},
};
async function saveNewInstance(inputUsers, inputGroups) {
const procCol = this.rwPool.collection(processColl);
const processVarNames = Object.keys(this.processDefinition?.variables);
const userRoles = this.processDefinition?.userRoles;
const groupRoles = Object.keys(this.processDefinition?.groupRoles ?? {});
const newInstanceData = {
ecosystem: this._ecosystem,
name: this.name,
creation: new Date(),
variables: {},
users: {},
groups: {},
};
for (let index = 0; index < processVarNames.length; index++) {
const processVarName = processVarNames[index];
newInstanceData.variables[processVarName] = null;
}
for (let index = 0; index < userRoles.length; index++) {
const roleName = userRoles[index];
newInstanceData.users[roleName] = inputUsers[roleName] ?? null;
}
for (let index = 0; index < groupRoles.length; index++) {
const roleName = groupRoles[index];
newInstanceData.groups[roleName] = inputGroups[roleName] ?? null;
}
this.logger.log({
level: 'debug',
label: 'processInstance',
action: 'saveInstanceDB',
message: `Se dispara la creación de una nueva instancia del proceso ${this.name} con ${JSON.stringify(newInstanceData, null, 2)}`,
});
const actionResult = await procCol.insertOne(newInstanceData);
const procId = actionResult?.insertedId.toString();
if (!procId) {
this.logger.log({
level: 'error',
label: 'processInstance',
action: 'saveInstanceDB',
message: `No fue posible la creación de una nueva instancia del proceso ${this.name}`,
});
const errorObj = this.errorObj.get(modErrs.newProcessInstance.saveFailure);
return [errorObj, null];
}
this.logger.log({
level: 'info',
label: 'processInstance',
action: 'saveInstanceDB',
message: `Creación de una nueva instancia del proceso ${this.name} con id ${procId}`,
});
return [null, procId];
}
async function newInstance(inputVars, users, groups) {
const startEvent = Object.values(this.processDefinition?.events).find((value) => value.type === START);
if (!startEvent) {
const message = `No se tiene evento inicial para el proceso ${this.name}`;
this.logger.log({
level: 'error',
label: 'processInstance',
action: 'newInstance',
message,
});
const errorObj = this.errMgr.get(modErrs.newProcessInstance.notStartEvent, message);
return [errorObj, null];
}
const [saveErr, procId] = await this.saveNewInstance(users, groups);
if (saveErr) {
return [saveErr, null];
}
this.logger.log({
level: 'info',
label: 'processInstance',
action: 'newInstance',
message: `Se dispara evento inicial de la instancia ${procId} del proceso ${this.name}`,
});
this.triggerEvent(procId, START, inputVars);
return [null, procId];
}
async function findInstance(inputVars) {
const procCol = this.rwPool.collection(processColl);
const findInstanceQuery = {
ecosystem: this._ecosystem,
name: this.name,
variables: {},
};
const inputVarNames = Object.keys(inputVars);
for (let index = 0; index < inputVarNames.length; index++) {
const inputVarName = inputVarNames[index];
findInstanceQuery.variables[inputVarName] = inputVars[inputVarName];
}
const foundInstance = await procCol.findOne(findInstanceQuery);
if (!foundInstance) {
const errorObj = this.errMgr.get(modErrs.findInstance.notFound);
return [errorObj, null];
}
return [null, { procId: foundInstance._id }];
}
async function updateBasicInfoInstance(reqData) {
const { procId } = reqData;
const procCol = this.rwPool.collection(processColl);
const procDetail = await procCol.findOne(processQueries.findProcess(procId));
if (!procDetail) {
const errorDetail = `Instancia ${procId} del proceso ${this.name} no existe`;
const errorObj = this.errMgr.get(modErrs.updateProc.notFound, errorDetail);
return [errorObj, null];
}
const updateData = { ...reqData };
delete updateData.procId;
const actionResult = await procCol.updateOne(...processQueries.updateProc(procId, updateData));
const result = actionResult?.result?.nModified > 0;
if (!result) {
this.logger.log({
level: 'warn',
label: 'processInstance',
action: 'updateProcInstanceDB',
message: `No se pudo efectuar modificación de la instancia de proceso ${procId}`,
});
}
return [null, { result }];
}
async function goToNode(procId, name, type, originType, originName, originId) {
this.logger.log({
level: 'silly',
label: 'processInstance',
action: 'goToNode',
message: `Se solicita la ejecución del nodo ${name} de tipo ${type} dentro del proceso ${this.name}:${procId} desde ${originName}/${originType}:${originId}`,
});
let newNodeId;
const origin = { id: originId, type: originType, name: originName };
if (type === TASK) {
const [errorTask, taskId] = await this.startNewTask(procId, name, origin);
if (errorTask) {
this.logger.log({
level: 'error',
label: 'processInstance',
action: 'goToNode',
message: `No fue posible iniciar la tarea ${name} desde ${originName} para el proceso ${this.name}:${procId}`,
});
return [errorTask, null];
}
newNodeId = taskId;
} else if (type === GATEWAY) {
const [errorGateway, gatewayId] = await this.startNewGateway(procId, name, origin);
if (errorGateway) {
this.logger.log({
level: 'error',
label: 'processInstance',
action: 'goToNode',
message: `No fue posible iniciar el gateway ${name} desde ${originName} para el proceso ${this.name}:${procId}`,
});
return [errorGateway, null];
}
newNodeId = gatewayId;
} else if (type === EVENT) {
const [errorGateway, gatewayId] = await this.registerTimerEvent(procId, name, {});
if (errorGateway) {
this.logger.log({
level: 'error',
label: 'processInstance',
action: 'goToNode',
message: `No fue posible iniciar el gateway ${name} desde ${originName} para el proceso ${this.name}:${procId}`,
});
return [errorGateway, null];
}
newNodeId = gatewayId;
}
if (originType === TASK) {
this.updateTaskNextNode(procId, originId, newNodeId, type, name);
} else if (originType === GATEWAY) {
this.updateGatewayNextNode(procId, originId, newNodeId, type, name);
}
return [null, newNodeId];
}
module.exports = {
methods: {
saveNewInstance,
newInstance,
findInstance,
updateBasicInfoInstance,
goToNode,
},
errors: modErrs,
};