143 lines
5.7 KiB
TypeScript
Executable File
143 lines
5.7 KiB
TypeScript
Executable File
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);
|
|
}
|
|
}
|
|
}
|