import CompaniesManager from "../Companies/Companies"; import { CreateSystemNotificationParams, CreateSystemNotificationBySystemParams, DeleteNotificationsByDateParams, DeleteNotificationsByUserParams, DeleteSystemNotificationParams, DeleteSystemNotificationsByConversation, FindSystemNotificationsParams, ISystemNotification, ISystemNotificationsManager, PaginateSystemNotificationsParams, PaginateSystemNotificationsResults, ToggleStateSystemNotificationsParams, UnreadNotificationResults, UpdateSystemNotificationParams, } from "./SystemNotification.Interface"; import { SystemNotificationsAdapterMongoose } from "./SystemNotification.Adapter.Mongoose"; import { io } from "../../index"; import MessageConversationList from "../MessageConversations/MessagesConversations"; import { FilterQuery } from "mongoose"; import { validateSessionUser } from "../../helpers/check"; class SystemNotificationsManager implements ISystemNotificationsManager { notifications: SystemNotificationsAdapterMongoose; constructor() { this.notifications = new SystemNotificationsAdapterMongoose(); } public async setStateByUser(data: ToggleStateSystemNotificationsParams): Promise { await validateSessionUser({ sessionUser: data.sessionUser, }); await this.notifications.notificationsList.updateMany( { userId: data.sessionUser }, { $set: { readed: data.state } } ); const countUnreadNotifications = await this.finUnreadNotifications({ userId: data.sessionUser, sessionUser: data.sessionUser, }); io.to(`user:${data.sessionUser}`).emit("new_system_notification", countUnreadNotifications); } public async deleteNotificationsByUser(data: DeleteNotificationsByUserParams): Promise { await this.notifications.notificationsList.deleteMany({ userId: data.userId }); } public async deleteNotificationsByDate(data: DeleteNotificationsByDateParams): Promise { await validateSessionUser({ sessionUser: data.sessionUser, }); if (data.sessionUser !== data.userId) { throw new Error("No tienes permiso para eliminar estas notificaciones"); } const deleteFilter: FilterQuery = { userId: data.userId }; if (data.dateFrom || data.dateTo) { deleteFilter.notificationDate = {}; } if (data.dateFrom) { deleteFilter.notificationDate.$gte = data.dateFrom; } if (data.dateTo) { deleteFilter.notificationDate.$lte = data.dateTo; } await this.notifications.deleteByQuery(deleteFilter); const countUnreadNotifications = await this.finUnreadNotifications({ userId: data.sessionUser, sessionUser: data.sessionUser, }); io.to(`user:${data.sessionUser}`).emit("new_system_notification", countUnreadNotifications); } public async createNotification(data: CreateSystemNotificationParams): Promise { if (data.userId) { await validateSessionUser({ sessionUser: data.userId, }); } if (data.companyId) { const companyCheck = await CompaniesManager.companies.findOne({ _id: data.companyId }); if (!companyCheck) { throw new Error("La compañia no existe"); } } const newNotification = await this.notifications.create({ ...data, ...{ notificationDate: new Date(), readed: false, }, }); return newNotification; } public async createNotificationBySystem( data: CreateSystemNotificationBySystemParams ): Promise { const expectedToken = process.env.SYSTEM_KEY || process.env.API_KEY; if (!expectedToken || data.systemToken !== expectedToken) { throw new Error("Token de sistema inválido"); } const { systemToken, ...notificationData } = data; const notification = await this.createNotification(notificationData); const countUnreadNotifications = await this.finUnreadNotifications({ userId: data.userId, sessionUser: data.userId, }); io.to(`user:${data.userId}`).emit("new_system_notification", countUnreadNotifications); return notification; } public async updateNotification(data: UpdateSystemNotificationParams): Promise { await validateSessionUser({ sessionUser: data.sessionUser, }); const checkNotification = await this.notifications.notificationsList.findOne({ _id: data.id, }); if (!checkNotification) { throw new Error("Notificación invalida"); } if (String(checkNotification.userId) !== data.sessionUser) { throw new Error("No tienes permiso para modificar esta notificación"); } await this.notifications.update(data); const countUnreadNotifications = await this.finUnreadNotifications({ userId: data.sessionUser, sessionUser: data.sessionUser, }); io.to(`user:${data.sessionUser}`).emit("new_system_notification", countUnreadNotifications); } public async deleteNotification(data: DeleteSystemNotificationParams): Promise { await validateSessionUser({ sessionUser: data.sessionUser, }); const checkNotification = await this.notifications.notificationsList.findOne({ _id: data.id, }); if (!checkNotification) { throw new Error("Notificación invalida"); } if (String(checkNotification.userId) !== data.sessionUser) { throw new Error("No tienes permiso para eliminar esta notificación"); } await this.notifications.delete(data.id); const countUnreadNotifications = await this.finUnreadNotifications({ userId: data.sessionUser, sessionUser: data.sessionUser, }); io.to(`user:${data.sessionUser}`).emit("new_system_notification", countUnreadNotifications); } public async deleteConversationNotifications( data: DeleteSystemNotificationsByConversation ): Promise { await validateSessionUser({ sessionUser: data.sessionUser, }); if (!data.conversationId) { throw new Error("No se ha seleccionado una conversación"); } const conversation = await MessageConversationList.conversations.findOne({ _id: data.conversationId, }); if (!conversation) { throw new Error("Conversación invalida"); } await this.notifications.deleteMany({ conversationId: data.conversationId, userId: data.sessionUser, }); const countUnreadNotifications = await this.finUnreadNotifications({ userId: data.sessionUser, sessionUser: data.sessionUser, }); io.to(`user:${data.sessionUser}`).emit("new_system_notification", countUnreadNotifications); } public async paginateNotifications( filters: PaginateSystemNotificationsParams ): Promise { return await this.notifications.paginate(filters); } public async finUnreadNotifications( data: FindSystemNotificationsParams ): Promise { await validateSessionUser({ sessionUser: data.sessionUser, }); const unread = await this.notifications.find({ userId: data.userId, readed: false, }); if (!unread) { return { count: 0 }; } return { count: unread.length, }; } } const SystemNoficationsList = new SystemNotificationsManager(); export default SystemNoficationsList;