tuain-ecosystem-lib
Version:
Servicio de gestión mensajería instantanea de la plataforma Tuain
319 lines (300 loc) • 15.7 kB
JavaScript
const { ObjectId } = require('mongodb');
const {
dbQueries: { prices: priceQueries },
collections: {
productPriceTypes: productPriceTypesColl, groupProductPrices: groupProductPricesColl,
productPricesHistory: productPricesHistoryColl,
},
} = require('../../config');
const modErrs = {
createProductPrice: {
alreadyExist: ['01', 'La definición de precio del producto ya existe'],
},
findProductPrice: {
notFound: ['01', 'Definición de precio del producto no encontrada'],
},
modifyProductPrice: {
alreadyActive: ['01', 'Definición de precio del producto activa'],
alreadyInactive: ['02', 'Definición de precio del producto no activa'],
},
groupProductPrice: {
alreadyExist: ['01', 'Tarifa de producto a grupo ya existe'],
notFound: ['02', 'Tarifa de producto a grupo no encontrada'],
},
};
class PriceManager {
constructor(getDb, logger, errMgr, options) {
this.options = options;
this.getDb = getDb;
this.logger = logger;
this.errMgr = errMgr;
this.errMgr.addModuleSet('lib-prices', modErrs);
}
async createProductPriceType(prodPriceData) {
const { name } = prodPriceData;
const prodPriceCol = this.getDb().collection(productPriceTypesColl);
const prodPriceDetail = await prodPriceCol.findOne(priceQueries.findByName(name));
if (prodPriceDetail) {
const errorDetail = `Precio de producto ${name} ya existe`;
const errorObj = this.errMgr.get(modErrs.createProductPrice.alreadyExist, errorDetail);
return [errorObj, null];
}
const newProdPriceData = { ...prodPriceData, enabled: false, creation: new Date() };
const actionResult = await prodPriceCol.insertOne(newProdPriceData);
this.logger.debug(`Creación de una nueva tarifa de producto ${newProdPriceData} con resultado ${actionResult?.insertedId}`);
return [null, { productPriceTypeId: actionResult?.insertedId }];
}
async getProductPriceTypes(reqData) {
const { productPriceTypeIds, productFamilyId, name } = reqData;
const query = (productFamilyId) ? { productFamilyId } : {};
if (productPriceTypeIds) { query._id = { $in: productPriceTypeIds }; }
if (productFamilyId) { query.productFamilyId = productFamilyId; }
if (name) { query.name = name; }
const prodPriceCol = this.getDb().collection(productPriceTypesColl);
const prodPrices = await prodPriceCol.find(query).toArray();
if (!prodPrices || prodPrices.length === 0) {
const errorDetail = `Precios de producto con familia ${productFamilyId} no encontrados`;
const errorObj = this.errMgr.get(modErrs.findProductPrice.notFound, errorDetail);
return [errorObj, null];
}
return [null, prodPrices];
}
async updateProductPriceType(reqData) {
const { productPriceTypeId } = reqData;
const prodPriceCol = this.getDb().collection(productPriceTypesColl);
const prodPriceDetail = await prodPriceCol.findOne(priceQueries.findById(productPriceTypeId));
if (!prodPriceDetail) {
const errorDetail = `Precio de producto con Id ${productPriceTypeId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findProductPrice.notFound, errorDetail);
return [errorObj, null];
}
const updateData = { ...reqData };
delete updateData.productPriceTypeId;
const actionResult = await prodPriceCol.updateOne(priceQueries.findById(productPriceTypeId),
priceQueries.updateObj(updateData));
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Modificación de una tarifa de producto ${updateData} con resultado ${result}`);
return [null, { result }];
}
async getProductPriceType(reqData) {
const { productPriceTypeId } = reqData;
const prodPriceCol = this.getDb().collection(productPriceTypesColl);
const prodPriceDetail = await prodPriceCol.findOne(priceQueries.findById(productPriceTypeId));
if (!prodPriceDetail) {
const errorDetail = `Precio de producto con Id ${productPriceTypeId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findProductPrice.notFound, errorDetail);
return [errorObj, null];
}
return [null, prodPriceDetail];
}
async activateProductPriceType(reqData) {
const { productPriceTypeId } = reqData;
const prodPriceCol = this.getDb().collection(productPriceTypesColl);
const prodPriceDetail = await prodPriceCol.findOne(priceQueries.findById(productPriceTypeId));
if (!prodPriceDetail) {
const errorDetail = `Precio de producto con Id ${productPriceTypeId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findProductPrice.notFound, errorDetail);
return [errorObj, null];
}
if (prodPriceDetail.enabled) {
const errorDetail = `Precio de producto con Id ${productPriceTypeId} actualmente activo`;
const errorObj = this.errMgr.get(modErrs.modifyProductPrice.alreadyActive, errorDetail);
return [errorObj, null];
}
const actionResult = await prodPriceCol.updateOne(priceQueries.findById(productPriceTypeId),
priceQueries.updateObj({ enabled: true }));
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Activación de la relación ${productPriceTypeId} con resultado ${result}`);
return [null, { result }];
}
async inactivateProductPriceType(reqData) {
const { productPriceTypeId } = reqData;
const prodPriceCol = this.getDb().collection(productPriceTypesColl);
const prodPriceDetail = await prodPriceCol.findOne(priceQueries.findById(productPriceTypeId));
if (!prodPriceDetail) {
const errorDetail = `Precio de producto con Id ${productPriceTypeId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findProductPrice.notFound, errorDetail);
return [errorObj, null];
}
if (!prodPriceDetail.enabled) {
const errorDetail = `Precio de producto con Id ${productPriceTypeId} actualmente inactivo`;
const errorObj = this.errMgr.get(modErrs.modifyProductPrice.alreadyActive, errorDetail);
return [errorObj, null];
}
const actionResult = await prodPriceCol.updateOne(priceQueries.findById(productPriceTypeId),
priceQueries.updateObj({ enabled: false }));
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Activación del precio del producto ${productPriceTypeId} con resultado ${result}`);
return [null, { result }];
}
async deleteProductPriceType(reqData) {
const { productPriceTypeId } = reqData;
const prodPriceCol = this.getDb().collection(productPriceTypesColl);
const actionResult = await prodPriceCol.deleteOne(priceQueries.findById(productPriceTypeId));
this.logger.debug(`Eliminación del precio del producto ${productPriceTypeId} con resultado ${actionResult?.result?.n}`);
const result = actionResult?.result?.n > 0;
return [null, { result }];
}
async defineGroupProductPrice(reqData) {
const { productPriceTypeId, productId, subproductId, groupId, priceValue, author } = reqData;
const groupProdPriceCol = this.getDb().collection(groupProductPricesColl);
const auditGroupProdPriceCol = this.getDb().collection(productPricesHistoryColl);
const groupProdPriceDetail = await groupProdPriceCol
.findOne(priceQueries.findGroupProdPrice(productPriceTypeId, productId, subproductId, groupId));
if (groupProdPriceDetail) {
const errorDetail = `Ya existe una definición de tarfa del producto para el grupo ${{ productId, subproductId, groupId }}`;
const errorObj = this.errMgr.get(modErrs.groupProductPrice.alreadyExist, errorDetail);
return [errorObj, null];
}
const newProdPriceData = {
...reqData,
productPriceTypeId: ObjectId(productPriceTypeId),
productId: ObjectId(productId),
subproductId: (subproductId) ? ObjectId(subproductId) : null,
groupId: ObjectId(groupId),
enabled: false,
creation: new Date(),
};
const auditGroupPriceChange = {
productPriceTypeId: ObjectId(productPriceTypeId),
productId: ObjectId(productId),
subproductId: (subproductId) ? ObjectId(subproductId) : null,
groupId: ObjectId(groupId),
author,
priceValue,
priceStartDate: new Date(),
priceEndDate: null,
};
auditGroupProdPriceCol.insertOne(auditGroupPriceChange);
const actionResult = await groupProdPriceCol.insertOne(newProdPriceData);
this.logger.debug(`Creación de una nueva tarifa de producto ${newProdPriceData} con resultado ${actionResult?.insertedId}`);
return [null, { groupProductPriceId: actionResult?.insertedId }];
}
async findGroupProductPrice(reqData) {
const { productPriceTypeId, productId, subproductId, groupId } = reqData;
const groupProdPriceCol = this.getDb().collection(groupProductPricesColl);
const groupProdPrice = await groupProdPriceCol.findOne(priceQueries
.findGroupProdPrice(productPriceTypeId, productId, subproductId, groupId));
if (!groupProdPrice) {
const errorDetail = `No existe una definición de tarfa del producto para el grupo ${{ productId, subproductId, groupId }}`;
const errorObj = this.errMgr.get(modErrs.groupProductPrice.alreadyExist, errorDetail);
return [errorObj, null];
}
return [null, groupProdPrice];
}
async findGroupProductPrices(reqData) {
const { productId, subproductId, groupId } = reqData;
const groupProdPriceCol = this.getDb().collection(groupProductPricesColl);
const groupProdPrices = await groupProdPriceCol.aggregate(priceQueries
.findGroupProdPrices(productId, subproductId, groupId)).toArray();
if (!groupProdPrices) {
const errorDetail = `No existen definiciones de tarfa del producto para el grupo ${{ productId, subproductId, groupId }}`;
const errorObj = this.errMgr.get(modErrs.groupProductPrice.notFound, errorDetail);
return [errorObj, null];
}
return [null, groupProdPrices];
}
async findGroupPrices(reqData) {
const { groupId, productId, subproductId } = reqData;
const groupProdPriceCol = this.getDb().collection(groupProductPricesColl);
const groupProdPrice = await groupProdPriceCol.find(priceQueries
.findGroupPrices(groupId, productId, subproductId)).toArray();
if (!groupProdPrice) {
const errorDetail = `No existe una definición de tarfa del producto para el grupo ${{ groupId }}`;
const errorObj = this.errMgr.get(modErrs.groupProductPrice.notFound, errorDetail);
return [errorObj, null];
}
return [null, groupProdPrice];
}
async updateGroupProductPrice(reqData) {
const { productPriceTypeId, productId, subproductId, groupId, priceValue, author } = reqData;
const groupProdPriceCol = this.getDb().collection(groupProductPricesColl);
const auditGroupProdPriceCol = this.getDb().collection(productPricesHistoryColl);
const groupProdPriceDetail = await groupProdPriceCol
.findOne(priceQueries.findGroupProdPrice(productPriceTypeId, productId, subproductId, groupId));
if (!groupProdPriceDetail) {
const errorDetail = `No existe una definición de tarfa del producto para el grupo ${{ productId, subproductId, groupId }}`;
const errorObj = this.errMgr.get(modErrs.groupProductPrice.alreadyExist, errorDetail);
return [errorObj, null];
}
const updateData = {
productId: ObjectId(productId),
subproductId: (subproductId) ? ObjectId(subproductId) : null,
groupId: ObjectId(groupId),
priceValue,
author,
update: new Date(),
};
groupProdPriceCol.updateOne(priceQueries
.findById(groupProdPriceDetail._id), priceQueries.updateObj(updateData));
const auditGroupPriceChange = {
productPriceTypeId: ObjectId(productPriceTypeId),
productId: ObjectId(productId),
subproductId: (subproductId) ? ObjectId(subproductId) : null,
groupId: ObjectId(groupId),
author,
priceValue,
priceStartDate: new Date(),
priceEndDate: null,
};
auditGroupProdPriceCol.insertOne(auditGroupPriceChange);
auditGroupProdPriceCol.updateOne(priceQueries
.findAuditGroupProdPrice(productPriceTypeId, productId, subproductId, groupId),
priceQueries.updateObj({ priceEndDate: new Date() }));
return [null, { groupProductPriceId: groupProdPriceDetail.id }];
}
async activateGroupProductPrice(reqData) {
const { productPriceTypeId, productId, subproductId, groupId } = reqData;
const groupProdPriceCol = this.getDb().collection(groupProductPricesColl);
const groupProdPriceDetail = await groupProdPriceCol
.findOne(priceQueries.findGroupProdPrice(productPriceTypeId, productId, subproductId, groupId));
if (!groupProdPriceDetail) {
const errorDetail = `No existe una definición de tarfa del producto para el grupo ${{ productId, subproductId, groupId }}`;
const errorObj = this.errMgr.get(modErrs.groupProductPrice.alreadyExist, errorDetail);
return [errorObj, null];
}
groupProdPriceCol.updateOne(priceQueries
.findById(groupProdPriceDetail._id), priceQueries.updateObj({ enabled: true }));
return [null, { groupProductPriceId: groupProdPriceDetail.id }];
}
async inctivateGroupProductPrice(reqData) {
const { productPriceTypeId, productId, subproductId, groupId } = reqData;
const groupProdPriceCol = this.getDb().collection(groupProductPricesColl);
const groupProdPriceDetail = await groupProdPriceCol
.findOne(priceQueries.findGroupProdPrice(productPriceTypeId, productId, subproductId, groupId));
if (!groupProdPriceDetail) {
const errorDetail = `No existe una definición de tarfa del producto para el grupo ${{ productId, subproductId, groupId }}`;
const errorObj = this.errMgr.get(modErrs.groupProductPrice.alreadyExist, errorDetail);
return [errorObj, null];
}
groupProdPriceCol.updateOne(priceQueries
.findById(groupProdPriceDetail._id), priceQueries.updateObj({ enabled: false }));
return [null, { groupProductPriceId: groupProdPriceDetail.id }];
}
async deleteGroupProductPrice(reqData) {
const { productPriceTypeId, productId, subproductId, groupId } = reqData;
const groupProdPriceCol = this.getDb().collection(groupProductPricesColl);
const auditGroupProdPriceCol = this.getDb().collection(productPricesHistoryColl);
const groupProdPriceDetail = await groupProdPriceCol
.findOne(priceQueries.findGroupProdPrice(productPriceTypeId, productId, subproductId, groupId));
if (!groupProdPriceDetail) {
const errorDetail = `No existe una definición de tarfa del producto para el grupo ${{ productId, subproductId, groupId }}`;
const errorObj = this.errMgr.get(modErrs.groupProductPrice.alreadyExist, errorDetail);
return [errorObj, null];
}
if (groupProdPriceDetail.enabled) {
const errorDetail = `La tarfa del producto para el grupo ${{ productId, subproductId, groupId }} está activa`;
const errorObj = this.errMgr.get(modErrs.groupProductPrice.alreadyExist, errorDetail);
return [errorObj, null];
}
const actionResult = await groupProdPriceCol
.deleteOne(priceQueries.findGroupProdPrice(productPriceTypeId, productId, subproductId, groupId));
this.logger.debug(`Eliminación de la tarfa del producto para el grupo ${{ productId, subproductId, groupId }}`);
const result = actionResult?.result?.n > 0;
auditGroupProdPriceCol.updateOne(priceQueries
.findAuditGroupProdPrice(productPriceTypeId, productId, subproductId, groupId),
priceQueries.updateObj({ priceEndDate: new Date() }));
return [null, { result }];
}
}
module.exports = PriceManager;