prg-class
Version:
Clases genéricas utilizadas por microservicios Programamos SPA.
416 lines (415 loc) • 18 kB
JavaScript
"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;