tuain-ecosystem-lib
Version:
Servicio de gestión mensajería instantanea de la plataforma Tuain
711 lines (674 loc) • 31.7 kB
JavaScript
const { ObjectId } = require('mongodb');
const {
dbQueries: { stores: storeQueries },
collections: {
thirdParties: thirdPartiesColl,
stores: storesColl,
storeGroupMembers: storeGroupMembersColl,
storeGroups: storeGroupsColl,
userRelations: userRelationsColl,
users: usersColl,
},
} = require('../../config');
const modErrs = {
findThird: {
notFound: ['01', 'No se encontraron terceros que se ajusten a la búsqueda'],
},
findStore: {
notFound: ['01', 'No se encontraron sucursales que se ajusten a la búsqueda'],
},
findExternalRef: {
notFound: ['01', 'No se encontró referencia externa'],
},
modifyStore: {
alreadyActive: ['01', 'Sucursal ya está activa'],
alreadyInactive: ['02', 'Sucursal ya está inactiva'],
},
createGroup: {
alreadyActive: ['01', 'Sucursal ya está activa'],
},
findGroup: {
alreadyActive: ['01', 'Sucursal ya está activa'],
emptyGroup: ['02', 'Grupo no contiene miembros'],
notFound: ['03', 'No se encontró ningun grupo'],
},
getStores: {
invalidSearch: ['01', 'Criterio de búsqueda inválido'],
notStoresFound: ['02', 'No se encontró ningun grupo'],
},
};
class StoreManager {
constructor(getDb, logger, errMgr, options) {
this.options = options;
this.getDb = getDb;
this.logger = logger;
this.errMgr = errMgr;
this.errMgr.addModuleSet('lib-stores', modErrs);
}
async getStores(reqData = null, constraints = null) {
const { thirdPartyId, groupId, storeType, storeIds: storeCodes } = reqData;
let storeIds = storeCodes;
const pageNumber = constraints?.requestedPage;
const recordsPerPage = constraints?.recordsPerPage || 0;
if (groupId && storeIds) {
const errorDetail = 'No se permite búsqueda por grupo y comercios simultaneamente';
const errorObj = this.errMgr.get(modErrs.getStores.notStoresFound, errorDetail);
return [errorObj, null];
}
if (groupId) {
const groupMembersCol = this.getDb().collection(storeGroupMembersColl);
const memberStores = await groupMembersCol.find(storeQueries.findGroupMembers(groupId)).toArray();
if (!memberStores || memberStores.length === 0) {
const errorDetail = `No se encontraon comercios dentro del grupo ${groupId}`;
const errorObj = this.errMgr.get(modErrs.getStores.notStoresFound, errorDetail);
return [errorObj, null];
}
storeIds = memberStores.map((item) => item.storeId);
}
const storeCol = this.getDb().collection(storesColl);
// const storesCursor = await storeCol.find(storeQueries.findStores(thirdPartyId, storeType, storeIds));
const storesCursor = await storeCol.aggregate(storeQueries.findStoresWithGroups(thirdPartyId, storeType, storeIds));
if (recordsPerPage && pageNumber) {
storesCursor.skip(recordsPerPage * (pageNumber - 1)).limit(recordsPerPage);
const count = await storesCursor.count();
const stores = await storesCursor.sort({ creation: -1 }).toArray();
return [null, { stores, count }];
}
const stores = await storesCursor.sort({ creation: -1 }).toArray();
return [null, stores];
}
async getStoresById(reqData = null) {
const { storeIds } = reqData;
const storeCol = this.getDb().collection(storesColl);
const stores = await storeCol.find(storeQueries.findStores(null, null, storeIds)).toArray();
if (!stores || stores.length < 1) {
const errorDetail = 'Establecimientos no encontrados';
const errorObj = this.errMgr.get(modErrs.findStore.notFound, errorDetail);
return [errorObj, null];
}
return [null, stores];
}
async getGroupsStores(reqData) {
const { groupIds } = reqData ?? {};
const groupMembersCol = this.getDb().collection(storeGroupMembersColl);
const memberStores = await groupMembersCol.find(storeQueries.findGroupsMembers(groupIds)).toArray();
if (!memberStores || memberStores.length === 0) {
const errorDetail = `No se encontraon comercios dentro de los grupos ${groupIds}`;
const errorObj = this.errMgr.get(modErrs.getStores.notStoresFound, errorDetail);
return [errorObj, null];
}
const groupStores = memberStores.map((item) => ({ groupId: item.groupId, storeId: item.storeId }));
return [null, groupStores];
}
async getStore(reqData) {
const { storeId } = reqData;
const storeCol = this.getDb().collection(storesColl);
const storeDetail = await storeCol.findOne(storeQueries.findById(storeId));
if (!storeDetail) {
const errorDetail = 'Sucursal no encontrado';
const errorObj = this.errMgr.get(modErrs.findStore.notFound, errorDetail);
return [errorObj, null];
}
return [null, storeDetail];
}
async createStore(storeData) {
const { thirdPartyId } = storeData;
const storeCol = this.getDb().collection(storesColl);
const thirdsCol = this.getDb().collection(thirdPartiesColl);
const thirdDetail = await thirdsCol.findOne(storeQueries.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 newStore = {
...storeData,
thirdPartyId: ObjectId(thirdPartyId),
enabled: false,
creation: new Date(),
};
const actionResult = await storeCol.insertOne(newStore);
const storeId = actionResult?.insertedId;
this.logger.debug(`Creación de una nueva sucursal ${newStore} con inserción ${storeId}`);
return [null, { storeId }];
}
async modifyStore(reqData) {
const { storeId, thirdPartyId } = reqData;
const storeCol = this.getDb().collection(storesColl);
const storeDetail = await storeCol.findOne(storeQueries.findById(storeId));
if (!storeDetail) {
const errorDetail = `Sucursal con Id ${storeId} no encontrada`;
const errorObj = this.errMgr.get(modErrs.findStore.notFound, errorDetail);
return [errorObj, null];
}
const storeData = {
...reqData,
};
if (thirdPartyId) {
storeData.thirdPartyId = ObjectId(thirdPartyId);
}
delete storeData.storeId;
const actionResult = await storeCol.updateOne(storeQueries.findById(storeId), storeQueries.updateObj(storeData));
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Modificación de sucursal ${storeId} ${JSON.stringify(storeData)} con resultado ${result}`);
return [null, { result }];
}
async addExternalRefStore(reqData) {
const { storeId, externalSource, externalCode, externalReference } = reqData;
const storeCol = this.getDb().collection(storesColl);
const storeDetail = await storeCol.findOne(storeQueries.findById(storeId));
if (!storeDetail) {
const errorDetail = `Sucursal con Id ${storeId} no encontrada`;
const errorObj = this.errMgr.get(modErrs.findStore.notFound, errorDetail);
return [errorObj, null];
}
const currentCoding = storeDetail.externalCoding?.find((item) => item.externalSource === externalSource);
if (currentCoding) {
await storeCol.updateOne(storeQueries.findById(storeId), storeQueries.removeExternalRef(externalSource, externalReference));
}
const externalRefData = { externalSource, externalCode, externalReference };
const actionResult = await storeCol.updateOne(storeQueries.findById(storeId), storeQueries.addExternalRef(externalRefData));
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Adición de una referencia externa a una sucursal ${externalRefData} con resultado ${result}`);
return [null, { result }];
}
async findStoreExternalRef(reqData) {
const { externalSource, externalCode, externalReference } = reqData;
const findEnabled = reqData.findEnabled ?? true;
const storeCol = this.getDb().collection(storesColl);
const storeDetail = await storeCol.findOne(storeQueries.findByExternalRef(externalSource, externalCode, externalReference));
if (!storeDetail) {
const errorDetail = `Sucursal con codigo externo ${externalCode} no encontrada`;
const errorObj = this.errMgr.get(modErrs.findStore.notFound, errorDetail);
return [errorObj, null];
}
if (findEnabled && !storeDetail.enabled) {
const errorDetail = `Sucursal con Id ${storeDetail._id.toString()} actualmente inactiva`;
const errorObj = this.errMgr.get(modErrs.modifyStore.alreadyInactive, errorDetail);
return [errorObj, null];
}
return [null, storeDetail];
}
async removeExternalRefStore(reqData) {
const { storeId, externalSource, externalReference } = reqData;
const storeCol = this.getDb().collection(storesColl);
const storeDetail = await storeCol.findOne(storeQueries.findById(storeId));
if (!storeDetail) {
const errorDetail = `Sucursal con Id ${storeId} no encontrada`;
const errorObj = this.errMgr.get(modErrs.findStore.notFound, errorDetail);
return [errorObj, null];
}
const currentCoding = storeDetail.externalCoding?.find((item) => item.externalSource === externalSource);
if (!currentCoding) {
const errorDetail = `Referencia externa ${externalSource} no encontrada en la sucursal storeId`;
const errorObj = this.errMgr.get(modErrs.findExternalRef.notFound, errorDetail);
return [errorObj, null];
}
const actionResult = await storeCol.updateOne(
storeQueries.findById(storeId),
storeQueries.removeExternalRef(externalSource, externalReference),
);
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Eliminacioń de una referencia externa a una sucursal ${externalSource} con resultado ${result}`);
return [null, { result }];
}
async activateStore(reqData) {
const { storeId } = reqData;
const storeCol = this.getDb().collection(storesColl);
const storeDetail = await storeCol.findOne(storeQueries.findById(storeId));
if (!storeDetail) {
const errorDetail = `Sucursal con Id ${storeId} no encontrada`;
const errorObj = this.errMgr.get(modErrs.findStore.notFound, errorDetail);
return [errorObj, null];
}
if (storeDetail.enabled) {
const errorDetail = `Sucursal con Id ${storeId} actualmente activa`;
const errorObj = this.errMgr.get(modErrs.modifyStore.alreadyActive, errorDetail);
return [errorObj, null];
}
const actionResult = await storeCol.updateOne(storeQueries.findById(storeId), storeQueries.updateObj({ enabled: true }));
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Activación de la sucursal ${storeId} con resultado ${result}`);
return [null, { result }];
}
async inactivateStore(reqData) {
const { storeId } = reqData;
const storeCol = this.getDb().collection(storesColl);
const storeDetail = await storeCol.findOne(storeQueries.findById(storeId));
if (!storeDetail) {
const errorDetail = `Sucursal con Id ${storeId} no encontrada`;
const errorObj = this.errMgr.get(modErrs.findStore.notFound, errorDetail);
return [errorObj, null];
}
if (!storeDetail.enabled) {
const errorDetail = `Sucursal con Id ${storeId} actualmente inactiva`;
const errorObj = this.errMgr.get(modErrs.modifyStore.alreadyInactive, errorDetail);
return [errorObj, null];
}
const actionResult = await storeCol.updateOne(storeQueries.findById(storeId), storeQueries.updateObj({ enabled: false }));
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Inactivación de la sucursal ${storeId} con resultado ${result}`);
return [null, { result }];
}
async deleteStore(reqData) {
const { storeId } = reqData;
const storeCol = this.getDb().collection(storesColl);
const storeDetail = await storeCol.findOne(storeQueries.findById(storeId));
if (!storeDetail) {
const errorDetail = `Sucursal con Id ${storeId} no encontrada`;
const errorObj = this.errMgr.get(modErrs.findStore.notFound, errorDetail);
return [errorObj, null];
}
if (storeDetail.enabled) {
const errorDetail = `Sucursal con Id ${storeId} actualmente activa`;
const errorObj = this.errMgr.get(modErrs.modifyStore.alreadyActive, errorDetail);
return [errorObj, null];
}
const actionResult = await storeCol.deleteOne(storeQueries.findById(storeId));
const result = actionResult?.result?.n > 0;
this.logger.debug(`Eliminación de la sucursal ${storeId} con resultado ${result}`);
return [null, { result }];
}
/**
* groups
*/
async findGroup(reqData) {
const { groupId } = reqData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await storeGroupCol.findOne(storeQueries.findById(groupId));
if (!groupDetail) {
const errorDetail = `Grupo ${groupId} no fue encontrado`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
return [null, groupDetail];
}
async createGroup(groupData) {
const { ownerId, name, groupType } = groupData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await storeGroupCol.findOne(storeQueries.findGroup(ownerId, name, groupType));
if (groupDetail) {
const errorDetail = `Grupo ${name} ya existe para el tercero ${ownerId}`;
const errorObj = this.errMgr.get(modErrs.createGroup.alreadyExist, errorDetail);
return [errorObj, null];
}
const newGroupData = {
...groupData,
ownerId: ObjectId(ownerId),
enabled: false,
creation: new Date(),
};
const actionResult = await storeGroupCol.insertOne(newGroupData);
this.logger.debug(`Creación de un nuevo grupo ${groupData} con resultado ${actionResult?.insertedId}`);
return [null, { groupId: actionResult?.insertedId }];
}
async modifyGroup(reqData) {
const { groupId } = reqData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await storeGroupCol.findOne(storeQueries.findById(groupId));
if (!groupDetail) {
const errorDetail = `Grupo con Id ${groupId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
const updateData = { ...reqData };
delete updateData.groupId;
const actionResult = await storeGroupCol.updateOne(storeQueries.findById(groupId), storeQueries.updateGroup(updateData));
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Modificación de grupo ${groupId} con resultado ${result}`);
return [null, { result }];
}
async addExternalRefStoreGroup(reqData) {
const { groupId, externalSource, externalCode, externalReference } = reqData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await storeGroupCol.findOne(storeQueries.findById(groupId));
if (!groupDetail) {
const errorDetail = `Grupo con Id ${groupId} no encontrada`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
const currentCoding = groupDetail.externalCoding?.find((item) => item.externalSource === externalSource);
if (currentCoding) {
await storeGroupCol.updateOne(
storeQueries.findById(groupId),
storeQueries.removeExternalRef(externalSource, externalReference),
);
}
const externalRefData = { externalSource, externalCode, externalReference };
const actionResult = await storeGroupCol.updateOne(
storeQueries.findById(groupId),
storeQueries.addExternalRef(externalRefData),
);
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Adición de una referencia externa a un grupo ${externalRefData} con resultado ${result}`);
return [null, { result }];
}
async findStoreGroupExternalRef(reqData) {
const { externalSource, externalCode, externalReference } = reqData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await storeGroupCol.findOne(
storeQueries.findByExternalRef(externalSource, externalCode, externalReference),
);
if (!groupDetail) {
const errorDetail = `Grupo con codigo externo ${externalCode} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
if (!groupDetail.enabled) {
const errorDetail = `Grupo con Id ${groupDetail._id.toString()} actualmente inactivo`;
const errorObj = this.errMgr.get(modErrs.findGroup.alreadyInactive, errorDetail);
return [errorObj, null];
}
return [null, groupDetail];
}
async removeExternalRefStoreGroup(reqData) {
const { groupId, externalSource, externalReference } = reqData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await storeGroupCol.findOne(storeQueries.findById(groupId));
if (!groupDetail) {
const errorDetail = `Grupo con Id ${groupId} no encontrada`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
const currentCoding = groupDetail.externalCoding?.find((item) => item.externalSource === externalSource);
if (!currentCoding) {
const errorDetail = `Referencia externa ${externalSource} no encontrada en el grupo`;
const errorObj = this.errMgr.get(modErrs.findExternalRef.notFound, errorDetail);
return [errorObj, null];
}
const actionResult = await storeGroupCol.updateOne(
storeQueries.findById(groupId),
storeQueries.removeExternalRef(externalSource, externalReference),
);
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Eliminacioń de una referencia externa a un grupo ${externalSource} con resultado ${result}`);
return [null, { result }];
}
async activateGroup(reqData) {
const { groupId } = reqData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await storeGroupCol.findOne(storeQueries.findById(groupId));
if (!groupDetail) {
const errorDetail = `Grupo con Id ${groupId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
if (groupDetail.enabled) {
const errorDetail = `Grupo con Id ${groupId} actualmente activo`;
const errorObj = this.errMgr.get(modErrs.findGroup.alreadyActive, errorDetail);
return [errorObj, null];
}
const actionResult = await storeGroupCol.updateOne(storeQueries.findById(groupId), storeQueries.updateObj({ enabled: true }));
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Activación del grupo ${groupId} con reultado ${result}`);
return [null, { result }];
}
async findOwnerGroup(groupData) {
const { ownerId, name, groupType } = groupData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await storeGroupCol.findOne(storeQueries.findGroup(ownerId, name, groupType));
if (!groupDetail) {
const errorDetail = `No se encontró grupo con ese dueño y nombre ${name}`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
return [null, groupDetail];
}
/**
* @deprecated Use getStoreGroupsByOwner
*/
async findStoreGroupsByOwner(groupData) {
return this.getStoreGroupsByOwner(groupData);
}
async getStoreGroupsByOwner(groupData) {
const { ownerId, groupType } = groupData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groups = await storeGroupCol.find(storeQueries.findStoreGroupsByOwner(ownerId, groupType)).toArray();
if (!groups || groups.length < 1) {
const errorDetail = `No se encontraron grupos con dueño ${ownerId}`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
return [null, groups];
}
async findStoreGroups(groupData) {
const { storeIds } = groupData;
const groupsCol = this.getDb().collection(storeGroupMembersColl);
if (!Array.isArray(storeIds) || storeIds.length === 0) {
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, 'Lista de storeIds vacía');
return [errorObj, null];
}
const BATCH_SIZE = 2000;
const promises = [];
for (let i = 0; i < storeIds.length; i += BATCH_SIZE) {
const batch = storeIds
.slice(i, i + BATCH_SIZE)
.filter((id) => ObjectId.isValid(id))
.map((id) => new ObjectId(id));
if (batch.length > 0) {
promises.push(
groupsCol.find({ storeId: { $in: batch } }, { projection: { _id: 0, storeId: 1, groupId: 1, enabled: 1 } }).toArray(),
);
}
}
const resultsArray = await Promise.all(promises);
const groups = resultsArray.flat();
if (groups.length === 0) {
const errorDetail = `No se encontraron grupos para los ${storeIds.length} stores en los miembros`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
return [null, groups];
}
async getStoreGroupMembers(reqData) {
const { groupId } = reqData;
const groupsCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await groupsCol.findOne(storeQueries.findById(groupId));
if (!groupDetail) {
const errorDetail = `Grupo con Id ${groupId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
const membersCol = this.getDb().collection(storeGroupMembersColl);
const groupMembers = await membersCol.find(storeQueries.findGroupMembers(groupId)).toArray();
if (!groupMembers || groupMembers?.length === 0) {
const errorDetail = `Grupo con Id ${groupId} vacío`;
const errorObj = this.errMgr.get(modErrs.findGroup.emptyGroup, errorDetail);
return [errorObj, null];
}
return [null, groupMembers];
}
async getStoreGroupMembersDetail(reqData) {
const { groupId } = reqData;
const groupsCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await groupsCol.findOne(storeQueries.findById(groupId));
if (!groupDetail) {
const errorDetail = `Grupo con Id ${groupId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
const membersCol = this.getDb().collection(storeGroupMembersColl);
const groupMembersDetail = await membersCol.aggregate(storeQueries.findGroupMembersDetail(groupId)).toArray();
if (!groupMembersDetail || groupMembersDetail?.length === 0) {
const errorDetail = `Grupo con Id ${groupId} vacío`;
const errorObj = this.errMgr.get(modErrs.findGroup.emptyGroup, errorDetail);
return [errorObj, null];
}
return [null, groupMembersDetail];
}
async inactivateGroup(reqData) {
const { groupId } = reqData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await storeGroupCol.findOne(storeQueries.findById(groupId));
if (!groupDetail) {
const errorDetail = `Grupo con Id ${groupId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
if (!groupDetail.enabled) {
const errorDetail = `Grupo con Id ${groupId} actualmente inactivo`;
const errorObj = this.errMgr.get(modErrs.findGroup.alreadyInactive, errorDetail);
return [errorObj, null];
}
const actionResult = await storeGroupCol.updateOne(
storeQueries.findById(groupId),
storeQueries.updateObj({ enabled: false }),
);
const result = actionResult?.result?.nModified > 0;
this.logger.debug(`Activación del grupo ${groupId} con reultado ${result}`);
return [null, { result }];
}
async deleteGroup(reqData) {
const { groupId } = reqData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await storeGroupCol.findOne(storeQueries.findById(groupId));
if (!groupDetail) {
const errorDetail = `Grupo con Id ${groupId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
if (groupDetail.enabled) {
const errorDetail = `Grupo con Id ${groupId} actualmente activo`;
const errorObj = this.errMgr.get(modErrs.findGroup.alreadyActive, errorDetail);
return [errorObj, null];
}
const actionResult = await storeGroupCol.deleteOne(storeQueries.findById(groupId));
const result = actionResult?.result?.n > 0;
this.logger.debug(`Eliminación del grupo ${groupId} con resultado ${result}`);
return [null, { result }];
}
async addStoreToGroup(reqData) {
const { groupId, storeId } = reqData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await storeGroupCol.findOne(storeQueries.findById(groupId));
if (!groupDetail) {
const errorDetail = `Grupo con Id ${groupId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
const storeCol = this.getDb().collection(storesColl);
const storeDetail = await storeCol.findOne(storeQueries.findById(storeId));
if (!storeDetail) {
const errorDetail = `Sucursal con Id ${storeId} no encontrada`;
const errorObj = this.errMgr.get(modErrs.findThird.notFound, errorDetail);
return [errorObj, null];
}
const existingThirdGroup = await this.existThirdGroup(storeId, groupId);
if (existingThirdGroup) {
const errorDetail = `Sucursal con Id ${storeId} ya existe en el grupo con Id ${groupId}`;
const errorObj = this.errMgr.get(modErrs.thirdPartyToGroup.alreadyExist, errorDetail);
return [errorObj, null];
}
const membersCol = this.getDb().collection(storeGroupMembersColl);
const newMemberData = {
...reqData,
enabled: false,
groupId: ObjectId(groupId),
storeId: ObjectId(storeId),
creation: new Date(),
};
const actionResult = await membersCol.insertOne(newMemberData);
this.logger.debug(`Adición de una sucursal a un grupo ${newMemberData} con resultado ${actionResult?.insertedId}`);
return [null, { membershipId: actionResult?.insertedId }];
}
async addStoresToGroup(reqData) {
const { groupId, storeIds } = reqData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await storeGroupCol.findOne(storeQueries.findById(groupId));
if (!groupDetail) {
const errorDetail = `Grupo con Id ${groupId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail);
return [errorObj, null];
}
const storeCol = this.getDb().collection(storesColl);
const actualStores = await storeCol.find(storeQueries.findStores(null, null, storeIds), { _id: 1 }).toArray();
let actualStoreIds = actualStores.map((store) => store._id);
if (actualStoreIds.length === 0) {
const errorDetail = 'Comercios no encontrados';
const errorObj = this.errMgr.get(modErrs.findThird.notFound, errorDetail);
return [errorObj, null];
}
// Se excluyen los comercios que ya se encuentran en el grupo
const membersCol = this.getDb().collection(storeGroupMembersColl);
const currentMembers = await membersCol
.find({ groupId: groupDetail?._id, storeId: { $in: actualStoreIds } }, { _id: 1 })
.toArray();
const currentMemberIds = currentMembers.map((store) => store._id);
actualStoreIds = actualStoreIds.filter((storeId) => !currentMemberIds.includes(storeId));
const currentDate = new Date();
const newMembersArray = actualStoreIds.map((storeId) => ({
groupId: groupDetail?._id,
storeId,
creation: currentDate,
enabled: true,
}));
await membersCol.insertMany(newMembersArray);
return [null, { storesAdded: actualStoreIds.length }];
}
async cleanStoreGroup(reqData) {
const { groupId } = reqData;
const storeGroupCol = this.getDb().collection(storeGroupsColl);
const groupDetail = await storeGroupCol.findOne(storeQueries.findById(groupId));
if (!groupDetail) {
const errorDetail = `Grupo con Id ${groupId} no encontrado`;
const errorObj = this.errMgr.get(modErrs.findingGroup.notFound, errorDetail);
return [errorObj, null];
}
const membersCol = this.getDb().collection(storeGroupMembersColl);
await membersCol.deleteMany({ groupId: ObjectId(groupId) });
return [null, null];
}
async deleteStoreFromGroup(reqData) {
const { groupId, storeId } = reqData;
const membersCol = this.getDb().collection(storeGroupMembersColl);
const memberDetail = await membersCol.findOne(storeQueries.findStoreGroupMember(storeId, groupId));
if (!memberDetail) {
const errorDetail = `No existe sucursal ${storeId} en grupo ${groupId}`;
const errorObj = this.errMgr.get(modErrs.storeGroup.notFound, errorDetail);
return [errorObj, null];
}
const actionResult = await membersCol.deleteOne(storeQueries.findById(memberDetail._id));
const result = actionResult?.result?.n > 0;
this.logger.debug(`Eliminación de la sucursal ${storeId} del grupo ${groupId} con resultado ${result}`);
return [null, { result }];
}
async existThirdGroup(storeId, groupId) {
const membersCol = this.getDb().collection(storeGroupMembersColl);
const memberDetail = await membersCol.findOne(storeQueries.findStoreGroupMember(storeId, groupId));
return memberDetail !== null && memberDetail !== undefined;
}
async findStoresByUser(reqData) {
const { userId: userIdInput, userName } = reqData;
let userId = userIdInput;
if (!userIdInput && userName) {
const usersCol = this.getDb().collection(usersColl);
const userInfo = await usersCol.findOne({ userName });
if (!userInfo) {
const errorDetail = `No se encontró usuario ${userName}`;
const errorObj = this.errMgr.get(modErrs.findThird.notFound, errorDetail);
return [errorObj, null];
}
userId = userInfo?._id;
}
const userRelationsCol = this.getDb().collection(userRelationsColl);
const userStoreInfo = await userRelationsCol.findOne(storeQueries.findStoreByUserId(userId));
if (!userStoreInfo || !userStoreInfo?.stores) {
const errorDetail = `No se encontró punto con usuario ${userId}`;
const errorObj = this.errMgr.get(modErrs.findThird.notFound, errorDetail);
return [errorObj, null];
}
// Se localizan los stores a los que pertenece el usuario
const { stores } = userStoreInfo;
const storeIds = stores?.map((item) => item.storeId);
const storeCol = this.getDb().collection(storesColl);
const userStores = await storeCol.find(storeQueries.findByIds(storeIds)).toArray();
// userStores.forEach((store) => { store.userId = userId; });
if (!userStores || userStores.length === 0) {
const errorDetail = `Usuario ${userId} no pertenece a ningún punto de atención`;
const errorObj = this.errMgr.get(modErrs.findThird.notFound, errorDetail);
return [errorObj, null];
}
return [null, userStores];
}
}
module.exports = StoreManager;