tuain-bpm-lib
Version:
Servicio de gestión de manejo de procesos de la plataforma Tuain
353 lines (337 loc) • 14.5 kB
JavaScript
const yn = require('yn');
const merge = require('lodash.merge');
const {
collections: {
execution: { processes: processColl },
},
dbQueries: {
execution: { process: processQueries },
},
process: {
varTypes: { boolean: BOOLEAN, string: STRING, integer: INTEGER, float: FLOAT, object: OBJECT },
},
} = require('../../../config');
const modErrs = {
obtainAttribute: {
notDefined: ['01', 'Atributo no está definido en el proceso'],
},
obtainVariable: {
notDefined: ['01', 'Variable no está definida en el proceso'],
},
touchUser: {
notDefined: ['01', 'Rol de usuario no está definida en el proceso'],
},
touchGroup: {
notDefined: ['01', 'Rol de grupo no está definida en el proceso'],
},
updateProc: {
notFound: ['01', 'No fue posible encontrar'],
},
};
async function setSubject(procId, subject) {
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 actionResult = await procCol.updateOne(...processQueries.updateProcSubject(procId, subject));
const result = actionResult?.result?.nModified > 0;
if (!result) {
const message = `[BPM] No se pudo efectuar modificación de la variable ${name} de la instancia de proceso ${procId}`;
this.logger.log({ level: 'silly', label: 'processInstance', action: 'setVarDB', message });
}
return [null, { result }];
}
async function getSubject(procId, procDetailInput = null) {
let procDetail;
if (!procDetailInput) {
const procCol = this.roPool.collection(processColl);
procDetail = await procCol.findOne(processQueries.findProcess(procId));
if (!procDetail) {
const message = `[BPM] : Instancia ${procId} del proceso ${this.name} no existe`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'getVar', message });
}
} else {
procDetail = procDetailInput;
}
return procDetail.subject;
}
function newVarValue(type, value, currentValue = null) {
let varValue;
if (type === BOOLEAN) {
varValue = yn(value) ?? false;
} else if (type === INTEGER) {
varValue = isNaN(value) ? 0 : +value;
} else if (type === FLOAT) {
varValue = isNaN(value) ? 0 : +value;
} else if (type === STRING) {
varValue = (value ?? '').toString().trim();
} else if (type === OBJECT) {
varValue = currentValue && typeof currentValue === 'object' ? merge(currentValue, value) : structuredClone({ ...value });
} else {
varValue = (value ?? '')?.toString().trim() ?? null;
}
return varValue;
}
async function setVar(procId, name, value) {
let message;
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];
}
if (!name) {
message = `[BPM] : Se solicita asignar valor a una variable indefinida ${name}`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'setVar', message });
const errorObj = this.errMgr.get(modErrs.obtainVariable.notDefined, message);
return [errorObj, null];
}
const varDef = this.processDefinition?.variables?.[name];
if (!varDef) {
message = `[BPM] : La variable ${name} no se encuentra en la definición del proceso`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'setVar', message });
const errorObj = this.errMgr.get(modErrs.obtainVariable.notDefined, message);
return [errorObj, null];
}
let varValue = newVarValue(varDef.type, value, procDetail?.variables?.[name] ?? null);
const actionResult = await procCol.updateOne(...processQueries.updateProcVar(procId, name, varValue));
const result = actionResult?.result?.nModified > 0;
if (!result) {
message = `[BPM] No se pudo efectuar modificación de la variable ${name} de la instancia de proceso ${procId}`;
this.logger.log({ level: 'silly', label: 'processInstance', action: 'setVarDB', message });
}
return [null, { result }];
}
async function setVars(procId, inVarsAndValues) {
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];
}
let message;
let varsAndValues = {};
let currentVarValues = procDetail?.variables ?? {};
let varNames = Object.keys(inVarsAndValues);
for (let index = 0; index < varNames.length; index++) {
const name = varNames[index];
if (!name) {
message = `[BPM] : Se solicita asignar valor a una variable indefinida ${name}`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'setVars', message });
continue;
}
const varDef = this.processDefinition?.variables?.[name];
if (!varDef) {
message = `[BPM] : La variable ${name} no se encuentra en la definición del proceso`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'setVars', message });
continue;
}
varsAndValues[name] = newVarValue(varDef.type, inVarsAndValues[name], currentVarValues?.[name] ?? null);
}
// Se actualiza el objeto del proceso con los nuevos valores
let result = false;
if (Object.keys(varsAndValues)?.length > 0) {
const actionResult = await procCol.updateOne(...processQueries.updateProcVars(procId, varsAndValues));
result = actionResult?.result?.nModified > 0;
}
if (!result) {
message = `[BPM] No se pudo efectuar modificación de las variable en la instancia de proceso ${procId}`;
this.logger.log({ level: 'silly', label: 'processInstance', action: 'setVarDB', message });
}
return [null, { result }];
}
async function getAttribute(procId, name, procDetailInput = null) {
let message;
let procDetail;
if (!procDetailInput) {
const procCol = this.roPool.collection(processColl);
procDetail = await procCol.findOne(processQueries.findProcess(procId));
if (!procDetail) {
message = `[BPM] : Instancia ${procId} del proceso ${this.name} no existe`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'getVar', message });
}
} else {
procDetail = procDetailInput;
}
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 attrDef = this.processDefinition?.attributes?.[name];
if (!attrDef) {
message = `[BPM] : El atributo ${name} no se encuentra en la definición del proceso`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'getAttribute', message });
const errorObj = this.errMgr.get(modErrs.obtainAttribute.notDefined, message);
return [errorObj, null];
}
let attrValue = procDetail?.attributes?.[name] ?? null;
return attrValue;
}
async function getVar(procId, name, procDetailInput = null) {
let message;
let procDetail;
if (!procDetailInput) {
const procCol = this.roPool.collection(processColl);
procDetail = await procCol.findOne(processQueries.findProcess(procId));
if (!procDetail) {
message = `[BPM] : Instancia ${procId} del proceso ${this.name} no existe`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'getVar', message });
}
} else {
procDetail = procDetailInput;
}
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 varDef = this.processDefinition?.variables?.[name];
if (!varDef) {
message = `[BPM] : La variable ${name} no se encuentra en la definición del proceso`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'getVar', message });
return null;
}
return newVarValue(varDef.type, procDetail?.variables?.[name] ?? null);
}
async function getVars(procId, varNames, procDetailInput = null) {
let message;
let procDetail;
if (!procDetailInput) {
const procCol = this.roPool.collection(processColl);
procDetail = await procCol.findOne(processQueries.findProcess(procId));
if (!procDetail) {
message = `[BPM] : Instancia ${procId} del proceso ${this.name} no existe`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'getVar', message });
}
} else {
procDetail = procDetailInput;
}
if (!procDetail) {
const errorDetail = `Instancia ${procId} del proceso ${this.name} no existe`;
const errorObj = this.errMgr.get(modErrs.updateProc.notFound, errorDetail);
return [errorObj, null];
}
let varValues = [];
for (let index = 0; index < varNames.length; index++) {
const name = varNames[index];
let varValue = null;
if (!name) {
message = `En los nombres de variables ${varNames.join(', ')} se recibió nombre inválido en ${index}`;
this.logger.log({ level: 'warning', label: 'getVars', action: 'getVars', message });
}
const varDef = name ? this.processDefinition?.variables?.[name] : null;
if (!varDef) {
message = `[BPM] : La variable ${name} no se encuentra en la definición del proceso`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'getVar', message });
}
varValue = name && varDef ? (newVarValue(varDef.type, procDetail?.variables?.[name]) ?? null) : null;
varValues.push(varValue);
}
return varValues;
}
async function assignUser(procId, roleName, user) {
let message;
const userRole = this.processDefinition?.userRoles?.find((item) => item === roleName);
if (!userRole) {
message = `[BPM] : El rol de usuario ${roleName} no se encuentra en la definición del proceso`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'assignUser', message });
const errorObj = this.errMgr.get(modErrs.touchUser.notDefined, message);
return [errorObj, null];
}
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 actionResult = await procCol.updateOne(...processQueries.updateProcUser(procId, roleName, user));
const result = actionResult?.result?.nModified > 0;
if (!result) {
message = `[BPM] No se pudo efectuar modificación del rol de usuario ${roleName} de la instancia de proceso ${procId}`;
this.logger.log({ level: 'silly', label: 'processInstance', action: 'assignUserDB', message });
}
return [null, { result }];
}
async function getUser(procId, roleName) {
let message;
const userRole = this.processDefinition?.userRoles?.find((item) => item === roleName);
if (!userRole) {
message = `[BPM] : El rol de usuario ${roleName} no se encuentra en la definición del proceso`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'getUser', message });
const errorObj = this.errMgr.get(modErrs.touchUser.notDefined, message);
return [errorObj, null];
}
const procCol = this.roPool.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];
}
return procDetail?.users?.[roleName] ?? null;
}
async function assignGroup(procId, roleName, group) {
let message;
const groupRole = this.processDefinition?.groupRoles?.[roleName];
if (!groupRole) {
message = `[BPM] : El rol de grupo ${roleName} no se encuentra en la definición del proceso`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'assignGroup', message });
const errorObj = this.errMgr.get(modErrs.touchGroup.notDefined, message);
return [errorObj, null];
}
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 actionResult = await procCol.updateOne(...processQueries.updateProcGroup(procId, roleName, group));
const result = actionResult?.result?.nModified > 0;
if (!result) {
message = `[BPM] No se pudo efectuar modificación del rol de grupo ${roleName} de la instancia de proceso ${procId}`;
this.logger.log({ level: 'silly', label: 'processInstance', action: 'assignGroupDB', message });
}
return [null, { result }];
}
async function getGroup(procId, roleName) {
let message;
const groupRole = this.processDefinition?.groupRoles?.[roleName];
if (!groupRole) {
message = `[BPM] : El rol de grupo ${roleName} no se encuentra en la definición del proceso`;
this.logger.log({ level: 'error', label: 'processInstance', action: 'getGroup', message });
const errorObj = this.errMgr.get(modErrs.touchGroup.notDefined, message);
return [errorObj, null];
}
const procCol = this.roPool.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];
}
return procDetail?.groupRoles?.[roleName] ?? null;
}
module.exports = {
methods: {
setSubject,
getSubject,
setVar,
setVars,
getAttribute,
getVar,
getVars,
assignUser,
getUser,
assignGroup,
getGroup,
},
errors: modErrs,
};