import { BadRequestException, Injectable, Logger, NotFoundException } from "@nestjs/common"; import { InjectDataSource } from "@nestjs/typeorm"; import { DataSource, QueryRunner } from "typeorm"; import { CommonMessage, NotificationMessage } from "../../../common/enums/message.enum"; import { NotifType } from "../../settings/enums/notif-settings.enum"; import { UserSettingsService } from "../../settings/providers/user-settings.service"; import { dateFormat, numberFormat } from "../../utils/providers/international.utils"; import { SmsService } from "../../utils/providers/sms.service"; import { CreateNotificationDto } from "../DTO/create-notification.dto"; import { SearchNotificationQueryDto } from "../DTO/search-notification-query.dto"; import { Notification } from "../entities/notification.entity"; import { IAnnouncementNotificationData, IBaseNotificationData, IInvoiceNotificationData, ITicketNotificationData, IWalletNotificationData, } from "../interfaces/ISendNotificationData"; import { NotificationRepository } from "../repositories/notifications.repository"; @Injectable() export class NotificationsService { private readonly logger = new Logger(NotificationsService.name); constructor( private readonly notificationRepository: NotificationRepository, private readonly smsService: SmsService, private readonly userSettingsService: UserSettingsService, @InjectDataSource() private readonly dataSource: DataSource, ) {} //************************ */ async createNotification(createNotificationDto: CreateNotificationDto, queryRunner?: QueryRunner) { if (!queryRunner) { const localQueryRunner = this.dataSource.createQueryRunner(); await localQueryRunner.connect(); await localQueryRunner.startTransaction(); try { // const notification = localQueryRunner.manager.create(Notification, { ...createNotificationDto, recipient: { id: createNotificationDto.recipientId }, }); await localQueryRunner.manager.save(notification); await localQueryRunner.commitTransaction(); return notification; // } catch (error) { this.logger.error("error in createNotification", error); await localQueryRunner.rollbackTransaction(); throw error; // } finally { await localQueryRunner.release(); } // } else { // const notification = queryRunner.manager.create(Notification, { ...createNotificationDto, recipient: { id: createNotificationDto.recipientId }, }); // await queryRunner.manager.save(notification); return notification; } } //************************ */ async markAsRead(notificationId: string, userId: string) { const notification = await this.notificationRepository.findOne({ where: { id: notificationId, recipient: { id: userId } }, }); if (!notification) throw new NotFoundException(NotificationMessage.NOTIFICATION_NOT_FOUND_OR_ACCESS_DENIED); notification.isRead = true; return this.notificationRepository.save(notification); } //************************ */ async getAllNotifications(queryDto: SearchNotificationQueryDto, recipientId: string) { return await this.notificationRepository.getAllNotifications(queryDto, recipientId); } //************************ */ async getNotificationById(id: string) { const notification = await this.notificationRepository.findOneBy({ id }); if (!notification) throw new BadRequestException(NotificationMessage.NOTIFICATION_NOT_FOUND_OR_ACCESS_DENIED); return { notification }; } //************************ */ async countUserNotifications(userId: string) { const notificationCount = await this.notificationRepository.count({ where: { recipient: { id: userId }, isRead: false } }); return notificationCount; } //************************ */ async markAllAsRead(userId: string) { await this.notificationRepository.update({ recipient: { id: userId } }, { isRead: true }); return { message: CommonMessage.UPDATE_SUCCESS, }; } //************************ */ async createLoginNotification(recipientId: string, sendNotifData: 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) { await this.smsService.sendLoginSms(sendNotifData.userPhone, loginDate); //send email too } return this.createNotification({ title: NotificationMessage.LOGIN, type: NotifType.USER_LOGIN, message, recipientId }); } //************************ */ async createInvoiceCreationNotification(recipientId: string, data: IInvoiceNotificationData, queryRunner: QueryRunner) { const message = NotificationMessage.INVOICE_CREATION_MESSAGE.replace("[id]", data.invoiceId); //sent notification based on the userSettings const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType( NotifType.CREATE_INVOICE, recipientId, queryRunner, ); if (isActive) { await this.smsService.sendInvoiceCreationSms( data.userPhone, data.invoiceId, data.price, data.items, dateFormat(data.createDate), dateFormat(data.dueDate), ); //send email too } return this.createNotification( { title: NotificationMessage.INVOICE_CREATION, type: NotifType.CREATE_INVOICE, message, recipientId }, queryRunner, ); } //************************ */ async createAnnouncementNotification(recipientId: string, data: IAnnouncementNotificationData, queryRunner: QueryRunner) { const message = NotificationMessage.ANNOUNCEMENT_MESSAGE; //sent notification based on the userSettings const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType( NotifType.ANNOUNCEMENT, recipientId, queryRunner, ); if (isActive) { await this.smsService.sendAnnouncementSms(data.userPhone, data.title, data.description, dateFormat(data.date)); //send email too } return this.createNotification({ title: NotificationMessage.ANNOUNCEMENT, type: NotifType.ANNOUNCEMENT, message, recipientId }); } //************************ */ async createWalletChargeNotification(recipientId: string, data: IWalletNotificationData, queryRunner: QueryRunner) { const message = NotificationMessage.WALLET_CHARGE_MESSAGE.replace("[amount]", numberFormat(data.amount)); //sent notification based on the userSettings const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType( NotifType.WALLET_CHARGE, recipientId, queryRunner, ); if (isActive) { await this.smsService.sendWalletChargeSms( data.userPhone, numberFormat(data.amount), numberFormat(data.balance), dateFormat(data.date), ); //send email too } return this.createNotification({ title: NotificationMessage.WALLET_CHARGE, type: NotifType.WALLET_CHARGE, message, recipientId }); } //************************ */ async createWalletDeductionNotification(recipientId: string, data: IWalletNotificationData, queryRunner: QueryRunner) { const message = NotificationMessage.WALLET_DEDUCTION_MESSAGE.replace("[amount]", numberFormat(data.amount)); //sent notification based on the userSettings const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType( NotifType.WALLET_DEDUCTION, recipientId, queryRunner, ); if (isActive) { await this.smsService.sendWalletDeductionSms( data.userPhone, numberFormat(data.amount), numberFormat(data.balance), data.reason, dateFormat(data.date), ); //send email too } return this.createNotification({ title: NotificationMessage.WALLET_DEDUCTION, type: NotifType.WALLET_DEDUCTION, message, recipientId }); } // //************************ */ async createAnswerTicketNotification(recipientId: string, data: ITicketNotificationData, queryRunner: QueryRunner) { const message = NotificationMessage.ANSWER_TICKET_MESSAGE.replace("[ticketId]", data.ticketId); //sent notification based on the userSettings const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType( NotifType.ANSWER_TICKET, recipientId, queryRunner, ); if (isActive) { await this.smsService.sendAnswerTicketSms(data.userPhone, data.ticketId, data.subject); //send email too } return this.createNotification({ title: NotificationMessage.ANSWER_TICKET, type: NotifType.ANSWER_TICKET, message, recipientId }); } // //************************ */ async createTicketNotification(recipientId: string, data: ITicketNotificationData, queryRunner: QueryRunner) { const message = NotificationMessage.CREATE_TICKET_MESSAGE.replace("[ticketId]", data.ticketId); //sent notification based on the userSettings const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType( NotifType.CREATE_TICKET, recipientId, queryRunner, ); if (isActive) { await this.smsService.sendCreateTicketSms(data.userPhone, data.ticketId, data.subject, dateFormat(data.date)); //send email too } return this.createNotification({ title: NotificationMessage.CREATE_TICKET, type: NotifType.CREATE_TICKET, message, recipientId }); } //************************ */ //TODO: fix this cause this for admin async createAssignTicketNotificationForAdmin(recipientId: string, data: ITicketNotificationData, queryRunner: QueryRunner) { const message = NotificationMessage.ASSIGN_TICKET_MESSAGE.replace("[ticketId]", data.ticketId); //sent notification based on the userSettings // const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType( // NotifType.ANSWER_TICKET, // recipientId, // queryRunner, // ); // if (isActive) { await this.smsService.sendTicketAssignedToAdminSms(data.userPhone, data.ticketId, data.subject, data.user!); //send email too // } return this.createNotification( { title: NotificationMessage.ASSIGN_TICKET, type: NotifType.ASSIGN_TICKET, message, recipientId }, queryRunner, ); } //************************ */ // async createBillInvoiceReminderNotification(recipientId: string, sendNotifData: ISendNotificationData) { // const message = NotificationMessage.BILL_INVOICE_REMINDER_MESSAGE; // //sent notification based on the userSettings // const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType(NotifType.BILL_INVOICE_REMINDER, recipientId); // if (isActive) { // await this.smsService.sendBillInvoiceReminderSms(sendNotifData.userPhone, sendNotifData.dueDate, sendNotifData.invoiceId); // //send email too // } // return this.createNotification({ title: NotificationMessage.BILL_INVOICE_REMINDER, message, recipientId }); // } //************************ */ // async createBillInvoiceNotification(recipientId: string, sendNotifData: ISendNotificationData) { // const message = NotificationMessage.BILL_INVOICE_MESSAGE; // //sent notification based on the userSettings // const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType(NotifType.BILL_INVOICE, recipientId); // if (isActive) { // await this.smsService.sendBillInvoiceSms(sendNotifData.userPhone, sendNotifData.amount, sendNotifData.invoiceId); // //send email too // } // return this.createNotification({ title: NotificationMessage.BILL_INVOICE, message, recipientId }); // } // //************************ */ // async createServiceNotification(recipientId: string, sendNotifData: ISendNotificationData) { // const message = NotificationMessage.CREATE_SERVICE_MESSAGE.replace("[serviceName]", sendNotifData.serviceName); // //sent notification based on the userSettings // const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType(NotifType.CREATE_SERVICE, recipientId); // if (isActive) { // await this.smsService.sendCreateServiceSms(sendNotifData.userPhone, sendNotifData.serviceName); // //send email too // } // return this.createNotification({ title: NotificationMessage.CREATE_SERVICE, message, recipientId }); // } // //************************ */ // async createUnblockServiceNotification(recipientId: string, sendNotifData: ISendNotificationData) { // const message = NotificationMessage.UNBLOCK_SERVICE_MESSAGE.replace("[serviceName]", sendNotifData.serviceName); // //sent notification based on the userSettings // const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType(NotifType.UNBLOCK_SERVICE, recipientId); // if (isActive) { // await this.smsService.sendUnblockServiceSms(sendNotifData.userPhone, sendNotifData.serviceName); // //send email too // } // return this.createNotification({ title: NotificationMessage.UNBLOCK_SERVICE, message, recipientId }); // } // //************************ */ // async createBlockServiceNotification(recipientId: string, sendNotifData: ISendNotificationData) { // const message = NotificationMessage.BLOCK_SERVICE_MESSAGE.replace("[serviceName]", sendNotifData.serviceName); // //sent notification based on the userSettings // const { isActive } = await this.userSettingsService.getUserNotificationSettingWithType(NotifType.BLOCK_SERVICE, recipientId); // if (isActive) { // await this.smsService.sendBlockServiceSms(sendNotifData.userPhone, sendNotifData.serviceName); // //send email too // } // return this.createNotification({ title: NotificationMessage.BLOCK_SERVICE, message, recipientId }); // } }