UNPKG

tuain-ecosystem-lib

Version:

Servicio de gestión mensajería instantanea de la plataforma Tuain

711 lines (674 loc) 31.7 kB
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;