tuain-ecosystem-lib
Version:
Servicio de gestión mensajería instantanea de la plataforma Tuain
531 lines (504 loc) • 23.4 kB
JavaScript
const { ObjectId } = require('mongodb');
const {
dbQueries: { setups: setupQueries },
collections: {
thirdParties: thirdPartiesColl,
thirdpartySetups: thirdpartySetupsColl,
thirdpartySetupsHistory: thirdpartySetupsHistoryColl,
productPriceSetups: productPriceSetupsColl,
setups: setupsColl,
setupPricesHistory: setupPricesHistoryColl,
},
} = require('../../config');
const modErrs = {
modifySetup: {
alreadyActive: ['01', 'Definición de Setup activa'],
alreadyInactive: ['02', 'Definición de Setup no activa'],
},
setup: {
alreadyExist: ['01', 'Setup ya existe'],
notFound: ['02', 'Setup no encontrada'],
},
setupProductPrice: {
alreadyExist: ['01', 'Setup de tarifa ya existe'],
notFound: ['02', 'Setup de tarifa no encontrada'],
},
modifyProductPriceSetup: {
alreadyActive: ['01', 'Definición de precio del producto activa'],
alreadyInactive: ['02', 'Definición de precio del producto no activa'],
},
productPriceSetup: {
alreadyExist: ['01', 'Tarifa de producto ya existe'],
notFound: ['02', 'Tarifa de producto no encontrada'],
invalidScale: ['03', 'Tarifa de producto no es valida'],
},
findGroup: {
notFound: ['01', 'No se encontraron grupos que se ajusten a la búsqueda'],
},
findThird: {
notFound: ['01', 'No se encontraron terceros que se ajusten a la búsqueda'],
},
findGroupSetup: {
notFound: ['01', 'No se encontraró setup de grupo'],
multipleSetups: ['02', 'Se encontrarón múltiples setup de grupos'],
},
};
class SetupManager {
constructor(getDb, logger, errMgr, options) {
this.options = options;
this.getDb = getDb;
this.logger = logger;
this.errMgr = errMgr;
this.errMgr.addModuleSet('lib-setups', modErrs);
}
async getProductSetups() {
const setupCol = this.getDb().collection(setupsColl);
const setups = await setupCol.find().toArray();
return [null, setups];
}
async getProductSetup(reqData) {
const { setupId } = reqData;
const setupCol = this.getDb().collection(setupsColl);
const setupDetail = await setupCol.findOne(setupQueries.findById(setupId));
if (!setupDetail) {
const errorDetail = `Setup con Id ${setupId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.setup.notFound, errorDetail);
return [errorObj, null];
}
return [null, setupDetail];
}
async createProductSetup(reqData) {
const { environmentId } = reqData;
const setupCol = this.getDb().collection(setupsColl);
const newSetupData = {
...reqData,
environmentId: ObjectId(environmentId),
enabled: false,
creation: new Date(),
};
const actionResult = await setupCol.insertOne(newSetupData);
this.logger.debug(`Creación de un nuevo setup ${newSetupData} con resultado ${actionResult?.insertedId}`);
return [null, { setupId: actionResult?.insertedId }];
}
async updateProductSetup(reqData) {
const { setupId, environmentId } = reqData;
const setupCol = this.getDb().collection(setupsColl);
const setupDetail = await setupCol.findOne(setupQueries.findById(setupId));
if (!setupDetail) {
const errorDetail = `Setup con Id ${setupId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.setup.notFound, errorDetail);
return [errorObj, null];
}
const updateData = { ...reqData };
if (environmentId) {
updateData.environmentId = ObjectId(environmentId);
}
delete updateData.setupId;
const actionResult = await setupCol.updateOne(setupQueries.findById(setupId), setupQueries.updateObj(updateData));
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Modificación de un setup ${updateData} con resultado ${result}`);
return [null, { result }];
}
async activateProductSetup(reqData) {
const { setupId } = reqData;
const setupCol = this.getDb().collection(setupsColl);
const setupDetail = await setupCol.findOne(setupQueries.findById(setupId));
if (!setupDetail) {
const errorDetail = `No existe una definición de setup ${{ setupId }}`;
const errorObj = this.errMgr.get(modErrs.setup.notFound, errorDetail);
return [errorObj, null];
}
if (setupDetail.enabled) {
const errorDetail = `Setup con Id ${setupId} actualmente inactiva`;
const errorObj = this.errMgr.get(modErrs.modifySetup.alreadyInactive, errorDetail);
return [errorObj, null];
}
const actionResult = await setupCol.updateOne(setupQueries.findById(setupId), setupQueries.updateObj({ enabled: true }));
const result = actionResult?.result?.nModified > 0;
return [null, { result }];
}
async inactivateProductSetup(reqData) {
const { setupId } = reqData;
const setupCol = this.getDb().collection(productPriceSetupsColl);
const setupDetail = await setupCol.findOne(setupQueries.findById(setupId));
if (!setupDetail) {
const errorDetail = `No existe una definición de setup ${{ setupId }}`;
const errorObj = this.errMgr.get(modErrs.setup.notFound, errorDetail);
return [errorObj, null];
}
if (!setupDetail.enabled) {
const errorDetail = `Setup con Id ${setupId} actualmente inactiva`;
const errorObj = this.errMgr.get(modErrs.modifySetup.alreadyInactive, errorDetail);
return [errorObj, null];
}
const actionResult = await setupCol.updateOne(setupQueries.findById(setupId), setupQueries.updateObj({ enabled: false }));
const result = actionResult?.result?.nModified > 0;
return [null, { result }];
}
async findThirdProductSetups(reqData) {
const { thirdPartyId } = reqData;
const thirdPartyCol = this.getDb().collection(thirdPartiesColl);
const thirdSetupCol = this.getDb().collection(thirdpartySetupsColl);
const thirdDetail = await thirdPartyCol.findOne(setupQueries.findById(thirdPartyId));
if (!thirdDetail) {
const errorDetail = `Grupo con Id ${thirdPartyId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
const thirdSetups = await thirdSetupCol.find(setupQueries.findThirdSetup(thirdPartyId)).toArray();
if (!thirdSetups || thirdSetups.length === 0) {
const errorDetail = `No existen setups para tercero ${thirdPartyId}`;
const errorObj = this.errMgr.get(modErrs.findGroupSetup.notFound, errorDetail);
return [errorObj, null];
}
return [null, thirdSetups];
/**
const setupCol = this.getDb().collection(setupsColl);
let setupIds = thirdSetups.map(item => item.setupId);
const setupsSet = new Set(setupIds);
setupIds = [...setupsSet];
const setupsInfo = await setupCol.find(setupQueries.findByIds(setupIds)).toArray();
if (!setupsInfo || setupsInfo.length === 0) {
const errorDetail = `Setups ${setupIds} no encontrados`;
const errorObj = this.errMgr.get(modErrs.setup.notFound, errorDetail);
return [errorObj, null];
}
const allSetups = thirdSetups.map(item => ({
...item,
setupDetail: setupsInfo.find(stp => stp._id.toString() === item.setupId),
}));
return [null, allSetups];
*/
}
async findThirdProductSetup(reqData) {
const { thirdPartyId, groupId } = reqData;
const setupCol = this.getDb().collection(setupsColl);
const thirdPartyCol = this.getDb().collection(thirdPartiesColl);
const thirdSetupCol = this.getDb().collection(thirdpartySetupsColl);
const thirdDetail = await thirdPartyCol.findOne(setupQueries.findById(thirdPartyId));
if (!thirdDetail) {
const errorDetail = `Grupo con Id ${thirdPartyId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
const thirdSetupDetail = await thirdSetupCol.find(setupQueries.findThirdSetup(thirdPartyId, groupId)).toArray();
if (!thirdSetupDetail) {
const errorDetail = `Setup para grupo con Id ${thirdPartyId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findGroupSetup.notFound, errorDetail);
return [errorObj, null];
}
if (thirdSetupDetail.length > 1) {
const errorDetail = `Tercero ${thirdPartyId} cuenta con múltiples tarifarios`;
const errorObj = this.errMgr.get(modErrs.findGroupSetup.multipleSetups, errorDetail);
return [errorObj, null];
}
const setupId = thirdSetupDetail?.[0]?.setupId ?? null;
const setupDetail = await setupCol.findOne(setupQueries.findById(setupId));
if (!setupDetail) {
const errorDetail = `Setup con Id ${setupId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.setup.notFound, errorDetail);
return [errorObj, null];
}
return [null, setupDetail];
}
async defineThirdPartyProductSetup(reqData) {
const { setupId, thirdPartyId, groupId } = reqData;
const setupCol = this.getDb().collection(setupsColl);
const thirdPartyCol = this.getDb().collection(thirdPartiesColl);
const thirdSetupCol = this.getDb().collection(thirdpartySetupsColl);
const thirdSetupHisCol = this.getDb().collection(thirdpartySetupsHistoryColl);
const setupDetail = await setupCol.findOne(setupQueries.findById(setupId));
if (!setupDetail) {
const errorDetail = `Setup con Id ${setupId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.setup.notFound, errorDetail);
return [errorObj, null];
}
const thirdDetail = await thirdPartyCol.findOne(setupQueries.findById(thirdPartyId));
if (!thirdDetail) {
const errorDetail = `Tercero con Id ${thirdPartyId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findThird.notFound, errorDetail);
return [errorObj, null];
}
const thirdSetupDetail = await thirdSetupCol.findOne(setupQueries.findThirdSetup(thirdPartyId, groupId));
let thirdSetupId;
if (thirdSetupDetail) {
thirdSetupId = thirdSetupDetail?.id;
if (thirdSetupDetail.setupId.toString() === setupId) {
return [null, { result: true }];
}
const thirdSetupHisRecord = {
...thirdSetupDetail,
endDate: new Date(),
};
delete thirdSetupHisRecord._id;
delete thirdSetupHisRecord.active;
await thirdSetupHisCol.insertOne(thirdSetupHisRecord);
const updateData = {
setupId: ObjectId(setupId),
active: true,
creation: new Date(),
};
const updateResult = await thirdSetupCol.updateOne(
setupQueries.findById(thirdSetupDetail._id),
setupQueries.updateObj(updateData),
);
const result = updateResult?.result?.nModified > 0;
this.logger.debug(`Modificación de un setup ${updateData} con resultado ${result}`);
} else {
const newThirdSetup = {
setupId: ObjectId(setupId),
thirdPartyId: ObjectId(thirdPartyId),
active: true,
creation: new Date(),
};
if (groupId) {
newThirdSetup.groupId = ObjectId(groupId);
}
const actionResult = await thirdSetupCol.insertOne(newThirdSetup);
thirdSetupId = actionResult?.insertedId;
}
this.logger.debug(`CAsihnación tarifario ${setupId} en ${thirdSetupId}`);
return [null, { thirdSetupId }];
}
/*
ProductPrices
*/
async defineProductPriceSetup(reqData) {
const { setupId, productPriceTypeId, productId, subproductId, author } = reqData;
const auditProdPriceSetupCol = this.getDb().collection(setupPricesHistoryColl);
const prodPriceSetupCol = this.getDb().collection(productPriceSetupsColl);
const setupProdPriceDetail = await prodPriceSetupCol.findOne(
setupQueries.findSetupProdPrice(productPriceTypeId, productId, subproductId, setupId),
);
if (setupProdPriceDetail) {
const errorDetail = `Ya existe una definición de tarfa del producto para el setup ${{ productId, subproductId, setupId }}`;
const errorObj = this.errMgr.get(modErrs.setupProductPrice.alreadyExist, errorDetail);
return [errorObj, null];
}
const newProdPriceData = {
...reqData,
productPriceTypeId: ObjectId(productPriceTypeId),
setupId: ObjectId(setupId),
productId: ObjectId(productId),
subproductId: subproductId ? ObjectId(subproductId) : null,
enabled: false,
creation: new Date(),
};
const auditSetupPriceChange = {
productPriceTypeId: ObjectId(productPriceTypeId),
setupId: ObjectId(setupId),
productId: ObjectId(productId),
subproductId: subproductId ? ObjectId(subproductId) : null,
author,
priceStartDate: new Date(),
priceEndDate: null,
};
auditProdPriceSetupCol.insertOne(auditSetupPriceChange);
const actionResult = await prodPriceSetupCol.insertOne(newProdPriceData);
this.logger.debug(`Creación de una nueva tarifa de producto ${newProdPriceData} con resultado ${actionResult?.insertedId}`);
return [null, { productPriceSetupId: actionResult?.insertedId }];
}
async getProductPriceSetup(reqData) {
const { productPriceSetupId } = reqData;
const prodPriceSetupCol = this.getDb().collection(productPriceSetupsColl);
const setupProdPriceDetail = await prodPriceSetupCol.findOne(setupQueries.findById(productPriceSetupId));
if (!setupProdPriceDetail) {
const errorDetail = `No existe una definición de tarfa del producto para el setup ${{ productPriceSetupId }}`;
const errorObj = this.errMgr.get(modErrs.setupProductPrice.notFound, errorDetail);
return [errorObj, null];
}
return [null, setupProdPriceDetail];
}
async getThirdPartyProductPriceSetup(reqData) {
const { setupId, productId, subproductId } = reqData;
const prodPriceSetupCol = this.getDb().collection(productPriceSetupsColl);
let setupProdPriceDetail = await prodPriceSetupCol.findOne(setupQueries.findSetupConfig(setupId, productId, subproductId));
if (subproductId && !setupProdPriceDetail) {
setupProdPriceDetail = await prodPriceSetupCol.findOne(setupQueries.findSetupConfig(setupId, productId));
}
if (!setupProdPriceDetail) {
const errorDetail = `No existe una definición de tarfa del producto ${productId}/${subproductId ?? ''} para el setup ${setupId}}`;
const errorObj = this.errMgr.get(modErrs.setupProductPrice.notFound, errorDetail);
return [errorObj, null];
}
return [null, setupProdPriceDetail];
}
async updateProductPriceSetup(reqData) {
const { productPriceTypeId, productId, subproductId, setupId, author } = reqData;
const auditProdPriceSetupCol = this.getDb().collection(setupPricesHistoryColl);
const prodPriceSetupCol = this.getDb().collection(productPriceSetupsColl);
const setupProdPriceDetail = await prodPriceSetupCol.findOne(
setupQueries.findSetupProdPrice(productPriceTypeId, productId, subproductId, setupId),
);
if (!setupProdPriceDetail) {
const errorDetail = `No existe una definición de tarfa del producto para el setup ${{ productId, subproductId, setupId }}`;
const errorObj = this.errMgr.get(modErrs.setupProductPrice.alreadyExist, errorDetail);
return [errorObj, null];
}
const updateData = {
productId: ObjectId(productId),
subproductId: subproductId ? ObjectId(subproductId) : null,
setupId: ObjectId(setupId),
author,
update: new Date(),
};
prodPriceSetupCol.updateOne(setupQueries.findById(setupProdPriceDetail._id), setupQueries.updateObj(updateData));
const auditSetupPriceChange = {
productPriceTypeId: ObjectId(productPriceTypeId),
productId: ObjectId(productId),
subproductId: subproductId ? ObjectId(subproductId) : null,
setupId: ObjectId(setupId),
author,
priceStartDate: new Date(),
priceEndDate: null,
};
auditProdPriceSetupCol.insertOne(auditSetupPriceChange);
auditProdPriceSetupCol.updateOne(
setupQueries.findAuditSetupProdPrice(productPriceTypeId, productId, subproductId, setupId),
setupQueries.updateObj({ priceEndDate: new Date() }),
);
return [null, { setupProductPriceId: setupProdPriceDetail.id }];
}
async getProductSetupsPrices(reqData) {
const { setupId } = reqData;
const prodPriceSetupCol = this.getDb().collection(productPriceSetupsColl);
const setupProdPrices = await prodPriceSetupCol.find(setupQueries.findBySetup(setupId)).toArray();
return [null, setupProdPrices];
}
async getSetupPrices() {
const prodPriceSetupCol = this.getDb().collection(productPriceSetupsColl);
const setupProdPrices = await prodPriceSetupCol.find().toArray();
return [null, setupProdPrices];
}
async activateProductPriceSetup(reqData) {
const { productPriceSetupId } = reqData;
const prodPriceSetupCol = this.getDb().collection(productPriceSetupsColl);
const setupProdPriceDetail = await prodPriceSetupCol.findOne(setupQueries.findById(productPriceSetupId));
if (!setupProdPriceDetail) {
const errorDetail = `No existe una definición de setup de tarifa del producto ${{ productPriceSetupId }}`;
const errorObj = this.errMgr.get(modErrs.productPriceSetup.notFound, errorDetail);
return [errorObj, null];
}
const actionResult = await prodPriceSetupCol.updateOne(
setupQueries.findById(setupProdPriceDetail._id),
setupQueries.updateObj({ enabled: true }),
);
const result = actionResult?.result?.nModified > 0;
return [null, { result }];
}
async inactivateProductPriceSetup(reqData) {
const { productPriceSetupId } = reqData;
const prodPriceSetupCol = this.getDb().collection(productPriceSetupsColl);
const prodPriceSetupDetail = await prodPriceSetupCol.findOne(setupQueries.findById(productPriceSetupId));
if (!prodPriceSetupDetail) {
const errorDetail = `No existe una definición de setup de tarifa ${{ productPriceSetupId }}`;
const errorObj = this.errMgr.get(modErrs.productPriceSetup.notFound, errorDetail);
return [errorObj, null];
}
const actionResult = await prodPriceSetupCol.updateOne(
setupQueries.findById(productPriceSetupId),
setupQueries.updateObj({ enabled: false }),
);
const result = actionResult?.result?.nModified > 0;
return [null, { result }];
}
async deleteProductPriceSetup(reqData) {
const { productPriceSetupId } = reqData;
const prodPriceSetupCol = this.getDb().collection(productPriceSetupsColl);
const prodPriceSetupDetail = await prodPriceSetupCol.findOne(setupQueries.findById(productPriceSetupId));
if (!prodPriceSetupDetail) {
const errorDetail = `No existe una definición de setupuración tarfa del producto ${{ productPriceSetupId }}`;
const errorObj = this.errMgr.get(modErrs.productPriceSetup.notFound, errorDetail);
return [errorObj, null];
}
if (prodPriceSetupDetail.enabled) {
const errorDetail = `Sucursal con Id ${productPriceSetupId} actualmente activa`;
const errorObj = this.errMgr.get(modErrs.modifyProductPriceSetup.alreadyActive, errorDetail);
return [errorObj, null];
}
const actionResult = await prodPriceSetupCol.deleteOne(setupQueries.findById(productPriceSetupId));
const result = actionResult?.result?.n > 0;
this.logger.debug(`Eliminación de configuración de precio ${productPriceSetupId} con resultado ${result}`);
return [null, { result }];
}
async addProductPriceSetupScale(reqData) {
const { productPriceSetupId, scale } = reqData;
const prodPriceSetupCol = this.getDb().collection(productPriceSetupsColl);
const prodPriceSetupDetail = await prodPriceSetupCol.findOne(setupQueries.findById(productPriceSetupId));
if (!prodPriceSetupDetail) {
const errorDetail = `No existe una definición de setupuración tarfa del producto ${{ productPriceSetupId }}`;
const errorObj = this.errMgr.get(modErrs.productPriceSetup.notFound, errorDetail);
return [errorObj, null];
}
if (prodPriceSetupDetail.enabled) {
const errorDetail = `Sucursal con Id ${productPriceSetupId} actualmente activa`;
const errorObj = this.errMgr.get(modErrs.modifyProductPriceSetup.alreadyActive, errorDetail);
return [errorObj, null];
}
const actionResult = await prodPriceSetupCol.updateOne(
setupQueries.findById(productPriceSetupId),
setupQueries.addScale(scale),
);
const result = actionResult?.result?.n > 0;
this.logger.debug(`Eliminación de configuración de precio ${productPriceSetupId} con resultado ${result}`);
return [null, { result }];
}
async deleteProductPriceSetupScale(reqData) {
const { productPriceSetupId, minValue } = reqData;
const prodPriceSetupCol = this.getDb().collection(productPriceSetupsColl);
const prodPriceSetupDetail = await prodPriceSetupCol.findOne(setupQueries.findById(productPriceSetupId));
if (!prodPriceSetupDetail) {
const errorDetail = `No existe una definición de setupuración tarfa del producto ${{ productPriceSetupId }}`;
const errorObj = this.errMgr.get(modErrs.productPriceSetup.notFound, errorDetail);
return [errorObj, null];
}
if (prodPriceSetupDetail.enabled) {
const errorDetail = `Sucursal con Id ${productPriceSetupId} actualmente activa`;
const errorObj = this.errMgr.get(modErrs.modifyProductPriceSetup.alreadyActive, errorDetail);
return [errorObj, null];
}
const actionResult = await prodPriceSetupCol.updateOne(
setupQueries.findById(productPriceSetupId),
setupQueries.deleteScale(minValue),
);
const result = actionResult?.result?.n > 0;
this.logger.debug(`Eliminación de configuración de precio ${productPriceSetupId} con resultado ${result}`);
return [null, { result }];
}
async verifyProductPriceSetup(reqData) {
const { productPriceSetupId } = reqData;
const prodPriceSetupCol = this.getDb().collection(productPriceSetupsColl);
const prodPriceSetupDetail = await prodPriceSetupCol.findOne(setupQueries.findById(productPriceSetupId));
const { scales = [] } = prodPriceSetupDetail;
if (!prodPriceSetupDetail || scales?.length === 0) {
const errorDetail = `No existe una definición de setup para la tarifa del producto ${productPriceSetupId}`;
const errorObj = this.errMgr.get(modErrs.productPriceSetup.notFound, errorDetail);
return [errorObj, null];
}
scales?.sort((a, b) => {
if (a?.minValue < b?.minValue) {
return -1;
}
if (a?.minValue > b?.minValue) {
return 1;
}
return 0;
});
if (+scales[0].minValue !== 0 || +scales[scales.length - 1].maxValue !== -1) {
const errorDetail = 'La tarifa tiene que empezar en 0 terminar en -1';
const errorObj = this.errMgr.get(modErrs.productPriceSetup.invalidScale, errorDetail);
return [errorObj, null];
}
for (let index = 1; index < scales.length; index++) {
const elem = scales[index];
const prevElemt = scales[index - 1];
if (prevElemt.maxValue !== elem.minValue) {
const errorDetail = 'Hay valores donde no está definida la tarifa (tiene que empezar en 0 terminar en -1)';
const errorObj = this.errMgr.get(modErrs.productPriceSetup.invalidScale, errorDetail);
return [errorObj, null];
}
}
return [null, { result: true }];
}
}
module.exports = SetupManager;