import { EntityManager } from "@mikro-orm/postgresql"; import { BadRequestException, Injectable, Logger, NotFoundException } from "@nestjs/common"; import { CommonMessage, NotificationMessage, UserMessage } from "../../../common/enums/message.enum"; import { NotifType } from "../../settings/enums/notif-settings.enum"; import { UserSettingsService } from "../../settings/services/user-settings.service"; import { User } from "../../users/entities/user.entity"; import { CreateNotificationDto } from "../DTO/create-notification.dto"; import { SearchNotificationQueryDto } from "../DTO/search-notification-query.dto"; import { Notification } from "../entities/notification.entity"; import { IBaseNotificationData, IChangePasswordNotificationData, INewEmailNotificationData } from "../interfaces/ISendNotificationData"; import { NotificationRepository } from "../repositories/notifications.repository"; @Injectable() export class NotificationsService { private readonly logger = new Logger(NotificationsService.name); constructor( private readonly em: EntityManager, private readonly notificationRepository: NotificationRepository, private readonly userSettingsService: UserSettingsService, ) {} //************************ */ async createNotification(createNotificationDto: CreateNotificationDto, em?: EntityManager) { if (!em) { const localEm = this.em.fork(); await localEm.begin(); try { // const user = await localEm.findOne(User, { id: createNotificationDto.recipientId }); if (!user) throw new NotFoundException(UserMessage.USER_NOT_FOUND); const notification = localEm.create(Notification, { ...createNotificationDto, recipient: user, }); await localEm.persistAndFlush(notification); await localEm.commit(); return notification; // } catch (error) { this.logger.error("error in createNotification", error); await localEm.rollback(); throw error; // } // } else { // const user = await em.findOne(User, { id: createNotificationDto.recipientId, deletedAt: null }); if (!user) throw new NotFoundException(UserMessage.USER_NOT_FOUND); const notification = em.create(Notification, { ...createNotificationDto, recipient: user, }); // await em.persistAndFlush(notification); return notification; } } //************************ */ async markAsRead(notificationId: string, userId: string) { const notification = await this.notificationRepository.findOne({ id: notificationId, recipient: { id: userId }, deletedAt: null }); if (!notification) throw new BadRequestException(NotificationMessage.NOTIFICATION_NOT_FOUND_OR_ACCESS_DENIED); notification.isRead = true; await this.em.flush(); return { message: CommonMessage.UPDATE_SUCCESS, }; } //************************ */ async getAllNotifications(queryDto: SearchNotificationQueryDto, recipientId: string) { const [notifications, count] = await this.notificationRepository.getAllNotifications(queryDto, recipientId); const notificationCount = await this.countUserNotifications(recipientId); return { notifications, notificationCount, count, paginate: true }; } //************************ */ async getNotificationById(id: string) { const notification = await this.notificationRepository.findOne({ id, deletedAt: null }); if (!notification) throw new BadRequestException(NotificationMessage.NOTIFICATION_NOT_FOUND_OR_ACCESS_DENIED); return { notification }; } //************************ */ async countUserNotifications(userId: string) { const notificationCount = await this.notificationRepository.count({ recipient: { id: userId }, isRead: false, deletedAt: null }); return notificationCount; } //************************ */ async markAllAsRead(userId: string) { await this.notificationRepository.nativeUpdate({ recipient: { id: userId }, deletedAt: null }, { isRead: true }); return { message: CommonMessage.UPDATE_SUCCESS, }; } //************************ */ async createLoginNotification(recipientId: string, _data: IBaseNotificationData) { const loginDate = new Date().toLocaleString("fa-IR"); const message = NotificationMessage.LOGIN_MESSAGE.replace("[loginDate]", loginDate); //sent notification based on the userSettings const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType(NotifType.USER_LOGIN, recipientId); if (isActive) { return this.createNotification({ title: NotificationMessage.LOGIN, type: NotifType.USER_LOGIN, message, recipientId }); } } //************************ */ async createNewEmailNotification(recipientId: string, data: INewEmailNotificationData, em: EntityManager) { const message = NotificationMessage.NEW_EMAIL_MESSAGE.replace("[subject]", data.newEmail); const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType(NotifType.NEW_EMAIL, recipientId); if (isActive) { return this.createNotification({ title: NotificationMessage.NEW_EMAIL, type: NotifType.NEW_EMAIL, message, recipientId }, em); } } //************************ */ async changePasswordNotification(recipientId: string, _data: IChangePasswordNotificationData, em: EntityManager) { const message = NotificationMessage.CHANGE_PASSWORD_MESSAGE; const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType(NotifType.CHANGE_PASSWORD, recipientId); if (isActive) { return this.createNotification({ title: NotificationMessage.CHANGE_PASSWORD, type: NotifType.CHANGE_PASSWORD, message, recipientId }, em); } } }