tuain-form-manager
Version:
Component library to perform operations on Tuain Development Framework forms to interchange information on web or mobile applications based on the data interchange of abstract forms making trnasformation on the data upon actions required on both sides (fr
215 lines (205 loc) • 8 kB
JavaScript
const crypto = require('crypto');
const path = require('path');
const modErrs = require('./module-errors');
const { customizeFormDefinition } = require('./form-utils');
const START_OPERATION = 'startOperation';
class FormManager {
constructor(rootPath, formsDefinitions, cacheManager, appLogger, errMgr, formClasses = null) {
this.rootPath = rootPath ?? '';
this.formsDefinitions = formsDefinitions;
this.formClasses = formClasses;
this._formsSignature = null;
this.logger = appLogger;
this.errMgr = errMgr;
this.errMgr.addModuleSet('forms-lib', modErrs);
this.getFormsSignature = () => this._formsSignature;
this.calculateFormsSignature();
}
calculateFormsSignature() {
this._formsSignature = {};
const formNames = Object.keys(this.formsDefinitions);
for (let index = 0; index < formNames.length; index++) {
const formName = formNames[index];
const formDefString = JSON.stringify(this.formsDefinitions[formName]);
const formHash = crypto.createHash('sha1').update(formDefString).digest('hex');
this._formsSignature[formName] = formHash;
}
}
get signatures() {
return this._formsSignature;
}
getFormFlatDefinition(formCode) {
const formDefinition = this.formsDefinitions?.[formCode]?.definition ?? null;
if (formDefinition) {
return JSON.parse(JSON.stringify(formDefinition));
}
return null;
}
async getFormDefinition(requestContext, formCode, customizeForm = true, execStart = true) {
const { enabledFunctions } = requestContext;
let formDefinition;
let errorObj = null;
try {
formDefinition = this.getFormFlatDefinition(formCode);
if (!formDefinition) {
const errorDetail = `Definición de formulario ${formCode} no encontrada`;
this.logger.log({
level: 'error',
label: 'FormManager',
action: 'getFormDefinition',
message: errorDetail,
});
errorObj = this.errMgr.get(modErrs.getFormDefinition.formNotFound, errorDetail);
return [errorObj, null];
}
if (customizeForm) {
formDefinition = customizeFormDefinition(formDefinition, enabledFunctions);
if (!formDefinition) {
const errorDetail = `Usuario sin privilegios para ejecutar el formulario ${formCode}`;
this.logger.log({
level: 'error',
label: 'FormManager',
action: 'getFormDefinition',
message: errorDetail,
});
errorObj = this.errMgr.get(modErrs.getFormDefinition.formNotAllowed, errorDetail);
return [errorObj, null];
}
}
if (execStart) {
[errorObj, formDefinition] = await this.executeFormStart(requestContext, formDefinition, formCode);
}
} catch (err) {
const errorDetail = `Excepción no controlada en ${formCode}: ${err.message}\n${err.stack}`;
this.logger.log({
level: 'error',
label: 'FormManager',
action: 'getFormDefinition',
message: errorDetail,
});
errorObj = this.errMgr.get(modErrs.getFormDefinition.formPopulateFail, errorDetail);
}
return [errorObj, formDefinition];
}
async executeFormStart(requestContext, formDefinition, formCode) {
const executeActionRequest = {
formCode,
formSubject: '',
currentMode: '',
actionCode: START_OPERATION,
actionSubject: '',
formData: { fields: formDefinition.fields },
};
const [errorObj, modifiedFormDef] = await this.executeFormAction(requestContext, formCode, executeActionRequest);
if (modifiedFormDef?.fields) {
for (let index = 0; index < modifiedFormDef?.fields?.length; index++) {
const modifiedField = modifiedFormDef?.fields[index];
const currentField = formDefinition.fields.find((fld) => fld.fieldCode === modifiedField.fieldCode);
Object.assign(currentField, modifiedField);
}
}
return [errorObj, formDefinition];
}
async executeFormAction(requestContext, formCode, requestData) {
let resultForm = null;
let errorObj = null;
let message;
const { actionCode } = requestData;
const formDefinition = this.getFormFlatDefinition(formCode);
if (!formDefinition) {
message = `Definición de formulario ${formCode} no encontrada`;
this.logger.log({
level: 'error',
label: 'FormManager',
action: 'executeFormAction',
message,
});
errorObj = this.errMgr.get(modErrs.formActionExec.formNotFound, message);
return [errorObj, null];
}
try {
let FormClass;
if (this.formClasses) {
FormClass = this.formClasses[formCode];
} else {
const { formMapping, formClassDirectory } = this.formsDefinitions;
const classFileName = formMapping?.[formCode]?.class ?? this.formsDefinitions?.[formCode]?.classFile;
const moduleName = classFileName ? path.resolve(this.rootPath, formClassDirectory ?? '', classFileName) : '';
if (!moduleName) {
message = `No existe nombre de archivo para el componente de gestión formulario ${formCode}`;
this.logger.log({
level: 'error',
label: 'FormManager',
action: 'executeFormAction',
message,
});
errorObj = this.errMgr.get(modErrs.formActionExec.formNotFound, message);
return [errorObj, null];
}
FormClass = require(moduleName);
}
if (!FormClass) {
message = `No se encontró componente para la atenciónn del formulario ${formCode}`;
this.logger.log({
level: 'error',
label: 'FormManager',
action: 'executeFormAction',
message,
});
errorObj = this.errMgr.get(modErrs.formActionExec.formNotFound, message);
return [errorObj, null];
}
const requireSession = formDefinition.form.requireSession ?? false;
if (requireSession) {
const { currentSession } = requestContext ?? {};
const { sessionDetail } = currentSession ?? {};
if (!currentSession || !sessionDetail) {
// El formulario requiere de la existencia de una sesión
message = `No existe una sesión válida para procesar la solicitud del formulario ${formCode}`;
this.logger.log({
level: 'error',
label: 'FormManager',
action: 'executeFormAction',
message,
});
errorObj = this.errMgr.get(modErrs.formActionExec.sessionNotFound, message);
return [errorObj, null];
}
}
const formCustomObject = new FormClass(this.logger, this.errMgr, requestContext, formDefinition, requestData);
if (!formCustomObject) {
message = `No fue posible instanciar la clase de gestión del formulario ${formCode}`;
this.logger.log({
level: 'error',
label: 'FormManager',
action: 'executeFormAction',
message,
});
errorObj = this.errMgr.get(modErrs.formActionExec.formNotFound, message);
return [errorObj, null];
}
[errorObj, resultForm] = await formCustomObject.executeFormAction(actionCode);
message = `END FORM ACTION ${formCode} / ${actionCode} / ${errorObj?.errorCode ?? ''}`;
this.logger.log({
level: 'info',
label: 'FormManager',
action: 'executeFormAction',
message,
});
return [errorObj, resultForm];
} catch (err) {
message =
`Excepción no controlada: ${err.message}\n${err.stack}` +
`------ END BY EXCEPTION FORM ACTION ${formCode} / ${actionCode} ------`;
this.logger.log({
level: 'error',
label: 'FormManager',
action: 'executeFormAction',
message,
});
errorObj = this.errMgr.get(modErrs.formActionExec.formNotFound, message);
return [errorObj, null];
}
}
}
module.exports = FormManager;