UNPKG

prg-class

Version:

Clases genéricas utilizadas por microservicios Programamos SPA.

416 lines (415 loc) 18 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.UploadExcelDataSave = void 0; const fs = require("fs"); // Clases. const Excel = require("exceljs"); const F = require("prg-function"); const C = require("prg-constant"); const exec_sp_1 = require("./exec-sp"); class UploadExcelDataSave extends exec_sp_1.ExecSP { constructor(alMaxRecord = 1000, alMaxMbUpload = 20480, alMaxColumns = 100) { super(); this.mlIndex = 0; this.msSpNameTemp = ''; this.msSpNameProc = ''; this.moFields = []; this.mlRowStartData = 10; this.moFieldMissing = []; this.mbAudit = false; this.msGuid = ''; this.mbHasCompanyUpload = false; this.mlYear = 0; this.mlMonth = 0; this.mlMaxRecord = 1000; this.mlMaxMbUpload = 20480; this.mlMaxColumns = 100; this.msErrMissingField = 'ERR_MISSING_FIELD'; this.msErrEmptyXls = 'ERR_EMPTY_EXCEL'; this.msErrMissingData = 'ERR_MISSING_DATA'; this.loCol = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ]; this.mlMaxColumns = alMaxRecord; this.mlMaxMbUpload = alMaxMbUpload; this.mlMaxColumns = alMaxColumns; } fnUploadFile(aoFiles, aoParams, aoUPRM) { this.doAudit('Entrada.aoParams', aoParams); return new Promise((rs, rj) => { this.moUPRM = aoUPRM; return this.uploadFile(aoFiles, aoParams, aoUPRM).then((d) => { if (d.error) { return rj(d); } return rs(d); }); }).catch((err) => { return err; }); } uploadFile(aoFiles, aoParams, aoUPRM) { return __awaiter(this, void 0, void 0, function* () { let loDataNew = []; const lsKey = F.getUuid(); this.msGuid = lsKey; this.doAudit('uploadFile.lsKey', lsKey); this.setCols(); /*** VALIDACIONES GENERALES ***/ const loRetValPre = yield this.preValData(aoParams); if (loRetValPre.error) { return loRetValPre; // En caso de error, sale. } /*** LEE DATOS DESDE EXCEL ***/ const loRetData = yield this.getFileData(aoFiles); if (loRetData.error) { return loRetData; // En caso de error, sale. } this.mlYear = F.intval(aoParams.Year); this.mlMonth = F.intval(aoParams.Month); loDataNew = loRetData.json.d; this.doAudit('uploadFile.loDataNew', loDataNew); /*** ELIMINA ARCHIVO EXCEL ***/ this.tempFileDelete(loRetData.json.p); /*** VALIDACIONES POSTERIORES A LECTURA DE DATOS DESDE EXCEL ***/ const loRetValPost = yield this.postValData(loDataNew); if (loRetValPost.error) { return loRetValPost; // En caso de error, sale. } /*** UPLOAD DE DATOS A TABLA TEMPORAL ***/ const loRetTempUpload = yield this.uploadTempData(0, loDataNew, aoUPRM); if (loRetTempUpload.error) { return loRetTempUpload; // En caso de error, sale. } /*** PROCESA DATOS EN BASE DE DATOS ***/ const loRetProcData = yield this.procTempDataDB(aoUPRM); if (loRetProcData.error) { return loRetProcData; // En caso de error, sale. } return loRetProcData; }); } setCols() { for (let i = 0; i < 5; i++) { const lsL1 = this.loCol[i]; for (let j = 0; j < 26; j++) { const lsL2 = this.loCol[j]; this.loCol.push(`${lsL1}${lsL2}`); } } } doAudit(asTitle, aoValue) { if (this.mbAudit) { this.developerMsg(asTitle, aoValue); } } tempFileDelete(asFile) { let lsRet = ''; try { fs.unlinkSync(asFile); } catch (error) { F.fnLogError(`No se pudo eliminar archivo: <<${asFile}>>. Error:${error}.`); } return lsRet; } preValData(aoData) { return __awaiter(this, void 0, void 0, function* () { if (!aoData || F.intval(aoData.Year) <= 0) { return F.fnRetErrBP('Debe ingresar año de proceso.'); } if (!aoData || F.intval(aoData.Month) <= 0 || F.intval(aoData.Month) > 12) { return F.fnRetErrBP('Debe ingresar un valor de mes entre 1 y 12.'); } return F.fnRetOk(''); }); } postValData(aoData) { return __awaiter(this, void 0, void 0, function* () { return F.fnRetOk(''); }); } uploadTempData(alIndex, aoData, aoUPRM) { return __awaiter(this, void 0, void 0, function* () { this.mlIndex = alIndex; if (alIndex >= aoData.length) { return F.fnRetOk(`Registros procesados: ${alIndex + 1}`); } const loRet = yield this.fnSpExecute(aoData, aoUPRM, this.mbAudit); if (loRet.error) { return loRet; } alIndex++; return this.uploadTempData(alIndex, aoData, aoUPRM); }); } procTempDataDB(aoUPRM) { return __awaiter(this, void 0, void 0, function* () { this.msSPName = this.getSpName('db_siab', this.msSpNameProc); const loRet = yield this.fnSpExecute(null, aoUPRM, this.mbAudit); return loRet; }); } getSPParams(aoParam) { const loPrm = [this.msGuid, this.mlYear, this.mlMonth]; if (F.trim(this.msSPName).indexOf(this.msSpNameTemp) >= 0) { if (this.moFields && this.moFields.length > 0) { this.moFields.forEach((r) => { let loVal = aoParam[this.mlIndex][r.n]; if (r.t === 'STRING') { loVal = F.trim(loVal); } if (r.t === 'INT') { loVal = F.intval(loVal); } if (r.t === 'DECIMAL') { loVal = F.floatval(loVal); } if (r.t === 'MONEY') { loVal = F.floatval(loVal); } if (r.t === 'DATE') { loVal = loVal; } loPrm.push(loVal); }); } if (this.mbHasCompanyUpload) { loPrm.push(this.getCompany()); } } return loPrm; } getFileData(aoFiles) { return new Promise((rs, rj) => { const loData = []; let lsName = ''; let lsPath = ''; let llSiz = 0; const lsErrFile = 'Debe seleccionar archivo.'; const llMaxMByteSize = this.mlMaxMbUpload; const llMaxCol = this.mlMaxColumns; if (!aoFiles || aoFiles === undefined || aoFiles === null) { return rj(F.fnReturn(lsErrFile, null, C.HttpCode.Error.BadRequest)); } if (!this.moUPRM || this.moUPRM === undefined || this.moUPRM === null) { return rj(F.fnReturn(':)', null, C.HttpCode.Error.BadRequest)); } if (aoFiles.length === undefined) { const lsFldFile = 'file'; const loFiles = aoFiles; const loFile = loFiles[lsFldFile]; aoFiles = [loFile]; } const lsFldPath = 'path'; const loFile0 = aoFiles[0]; lsPath = F.trim(loFile0['path']); lsName = F.trim(loFile0.name); llSiz = loFile0.size; if (lsPath === '') { return rj(F.fnReturn(lsErrFile, null, C.HttpCode.Error.BadRequest)); } if (lsName === '') { return rj(F.fnReturn(lsErrFile, null, C.HttpCode.Error.BadRequest)); } if (llSiz <= 0) { return rj(F.fnReturn(lsErrFile, null, C.HttpCode.Error.BadRequest)); } const loAux = lsPath.split('.'); if (loAux.length <= 0) { return rj(F.fnReturn(lsErrFile, null, C.HttpCode.Error.BadRequest)); } const lsExt = loAux[loAux.length - 1]; if (lsExt !== 'xls' && lsExt !== 'xlsx') { return rj(F.fnReturn('Debe seleccionar un archivo Excel.', null, C.HttpCode.Error.BadRequest)); } const llDiv = (1024 * 1024); let llAux1 = 0; llAux1 = (llSiz / llDiv); if (llAux1 > llMaxMByteSize) { const lsErr = C.Err.Generic.Upload.MaxSize; return rj(F.fnReturn(`${lsErr} ${llMaxMByteSize} Mb.`, null, C.HttpCode.Error.BadRequest)); } if (!fs.existsSync(lsPath)) { return rj(F.fnReturn('No se pudo abrir archivo.', null, C.HttpCode.Error.ServerError)); } const loWb = new Excel.Workbook(); return loWb.xlsx.readFile(lsPath).then(() => { let lbAux = false; let lsErr = ''; const loWS = loWb.getWorksheet(1); // Lee la primera Hoja. if (!loWS) { return rj(F.fnReturn('La planilla Excel no tiene hojas.', null, C.HttpCode.Error.ServerError)); } for (let i = 0; i < this.moFields.length; i++) { for (let j = 0; j < llMaxCol; j++) { const lsLet = this.loCol[j]; const loCell = loWS.getCell(`${lsLet}1`); if (loCell.value === this.moFields[i].n) { this.moFields[i].i = j; this.moFields[i].ce = lsLet; break; } } } for (let i = 0; i < this.moFields.length; i++) { if (this.moFields[i].m && this.moFields[i].i < 0) { lsErr = this.msErrMissingField; break; } } let llQty = 0; if (lsErr === '') { // Cuenta cantidad de registros. for (let i = (this.mlRowStartData + 0); i < (this.mlRowStartData + this.mlMaxRecord); i++) { const loCell = loWS.getCell(`A${i + 1}`); llQty++; if (!loCell || loCell.value === null) { // No hay mas datos, sale. break; } } if (llQty <= 0) { // Valida que se ingrese, al menos un registro. lsErr = this.msErrEmptyXls; } else { // Carga datos en un json. for (let i = this.mlRowStartData + 1; i < (llQty + this.mlRowStartData); i++) { const loRow = this.getNewRow(); for (let j = 0; j < this.moFields.length; j++) { const lsLet = this.moFields[j].ce; // this.loCol[j]; const lsFN = F.trim(this.moFields[j].n); if (F.trim(lsLet) === '') { loRow[lsFN] = null; } else { const loCell = loWS.getCell(lsLet + i); const lsVal = loCell && loCell.result ? F.trim(loCell.result.toString()) : F.trim(loCell.value); if (F.trim(this.moFields[j].t) === 'DATE') { const loDate = loCell && loCell.model && loCell.model.value ? this.formatDate(new Date(loCell.model.value)) : null; loRow[lsFN] = loDate; } else { loRow[lsFN] = lsVal; } } // tutu } loData.push(loRow); } } } if (lsErr === '' && loData.length > 0) { // No hay errores y se recuperaron datos. Valida campos obligatorios. if (this.checkErrorMissigValue(loData)) { lsErr = this.msErrMissingData; } if (lsErr === '') { lbAux = true; // Hasta aquí­ vamos bien. } } if (!lbAux) { // No existe hoja1, o no existen los campos necesarios. if (lsErr === this.msErrMissingField) { const lsErrDef = 'El archivo excel no tiene el formato esperado.'; const loFld1 = []; this.moFields.forEach((r) => { if (F.intval(r.i) <= 0) { loFld1.push(r.c); } }); lsErr = `${lsErrDef} Debe tener los campos: ${F.trim(loFld1.join(', '))}.`; } if (lsErr === this.msErrEmptyXls) { lsErr = 'La planilla Excel no tiene datos.'; } if (lsErr === this.msErrMissingData) { lsErr = `La planilla Excel no tiene ingresados todos los datos necesarios. Falta: ${this.getMissingField()}`; } if (lsErr === null || lsErr === undefined || lsErr === '') { const lsErrDef = 'El archivo excel no tiene el formato esperado.'; const loFld1 = []; this.moFields.forEach((r) => { loFld1.push(r.c); }); lsErr = `${lsErrDef} Debe tener los campos: ${F.trim(loFld1.join(', '))}.`; } return rj(F.fnReturn(lsErr, null, C.HttpCode.Error.BadRequest)); } else { return rs(F.fnReturn(null, { d: loData, p: lsPath }, C.HttpCode.Ok.OK)); } }); }).catch((err) => { return err; }); } formatDate(aoDate) { if (!aoDate) { return ''; } const loDate = new Date(aoDate); if (!loDate.getFullYear()) { return ''; } const lsDateTZ = loDate.toISOString(); const loDateArr = lsDateTZ.split('.'); if (!loDateArr || loDateArr.length < 2) { return ''; } return loDateArr[0]; } getNewRow() { const loRet = {}; if (this.moFields && this.moFields.length > 0) { this.moFields.forEach((r) => { loRet[r.n] = null; }); } return loRet; } getMissingField() { if (!this.moFieldMissing || this.moFieldMissing.length <= 0) { return ''; } return this.moFieldMissing.join(','); } checkErrorMissigValue(aoData) { const FL = this.moFields; if (!FL || FL.length <= 0) { return false; } for (let j = 0; j < aoData.length; j++) { for (let i = 0; i < FL.length; i++) { const lsFld = FL[i].n; if (this.moFieldMissing.indexOf(lsFld) < 0) { const loV = aoData[j] === null || aoData[j] === undefined ? null : aoData[j][lsFld]; const lbN = loV === undefined || loV === null; const lbErrorString = !lbN && FL[i].t === 'STRING' && F.trim(loV) === ''; const lbErrorNumber = !lbN && FL[i].t === 'NUMBER' && F.floatval(loV) <= 0; const lbErrorDate = !lbN && FL[i].t === 'DATE' && !F.fnIsDate(loV); if (FL[i].m && (lbN || lbErrorString || lbErrorNumber || lbErrorDate)) { this.moFieldMissing.push(lsFld); } } } } return !this.moFieldMissing || this.moFieldMissing.length <= 0 ? false : true; } setField(asFieldName, asFieldCaption = '', asType = '', abMandatory = false) { if (!this.moFields || this.moFields.length <= 0) { this.moFields = []; } asFieldName = F.trim(asFieldName); if (F.trim(asFieldCaption) === '') { asFieldCaption = asFieldName; } if (F.trim(asType) === '') { asType = 'STRING'; } this.moFields.push({ n: asFieldName, c: asFieldCaption, t: asType, m: abMandatory, i: -1, ce: '' }); } } exports.UploadExcelDataSave = UploadExcelDataSave;