first commit
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
import mongoose, { Document, FilterQuery, Model, Schema, model } from "mongoose";
|
||||
import {
|
||||
CreateSystemNotificationParams,
|
||||
DeleteSystemNotificationsByConversation,
|
||||
FindSystemNotificationsParams,
|
||||
ISystemNotification,
|
||||
ISystemNotificationsAdapter,
|
||||
PaginateSystemNotificationsParams,
|
||||
PaginateSystemNotificationsResults,
|
||||
UpdateSystemNotificationParams,
|
||||
} from "./SystemNotification.Interface";
|
||||
|
||||
export interface ISystemNotificationDocument extends Omit<ISystemNotification, "id">, Document {}
|
||||
|
||||
export class SystemNotificationsAdapterMongoose implements ISystemNotificationsAdapter {
|
||||
schema: Schema;
|
||||
notificationsList: Model<ISystemNotificationDocument>;
|
||||
|
||||
constructor() {
|
||||
this.schema = new Schema({
|
||||
userId: { type: Schema.Types.ObjectId, required: false, ref: "User" },
|
||||
companyId: { type: Schema.Types.ObjectId, required: false, ref: "Companie" },
|
||||
serviceId: { type: Schema.Types.ObjectId, required: false, ref: "Service" },
|
||||
conversationId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
required: false,
|
||||
ref: "MessagesConversation",
|
||||
},
|
||||
subject: { type: String, required: true },
|
||||
message: { type: String, required: true },
|
||||
notificationDate: { type: Date, required: true },
|
||||
readed: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
this.notificationsList = model<ISystemNotificationDocument>("SystemNotification", this.schema);
|
||||
}
|
||||
|
||||
public async create(data: CreateSystemNotificationParams): Promise<ISystemNotification> {
|
||||
return await this.notificationsList.create(data);
|
||||
}
|
||||
|
||||
public async update(data: UpdateSystemNotificationParams): Promise<void> {
|
||||
const updateNotification = await this.notificationsList.findOne({ _id: data.id });
|
||||
|
||||
if (!updateNotification) {
|
||||
throw new Error("Notificación invalida");
|
||||
}
|
||||
|
||||
updateNotification.readed = data.readed;
|
||||
|
||||
await updateNotification.save();
|
||||
}
|
||||
|
||||
public async delete(id: string): Promise<void> {
|
||||
await this.notificationsList.findByIdAndDelete(id).exec();
|
||||
}
|
||||
|
||||
public async deleteMany(
|
||||
data: Omit<DeleteSystemNotificationsByConversation, "sessionUser">
|
||||
): Promise<void> {
|
||||
await this.notificationsList.deleteMany(data).exec();
|
||||
}
|
||||
|
||||
public async deleteByQuery(data: FilterQuery<ISystemNotification>): Promise<void> {
|
||||
await this.notificationsList.deleteMany(data).exec();
|
||||
}
|
||||
|
||||
public async find(
|
||||
filters: Omit<FindSystemNotificationsParams, "sessionUser">
|
||||
): Promise<ISystemNotification[]> {
|
||||
return this.notificationsList.find(filters).exec();
|
||||
}
|
||||
|
||||
public async findOne(
|
||||
filters: FindSystemNotificationsParams
|
||||
): Promise<ISystemNotificationDocument | null> {
|
||||
return this.notificationsList.findOne(filters).exec();
|
||||
}
|
||||
|
||||
// Método para búsqueda con expresiones regulares y paginación
|
||||
public async paginate(
|
||||
data: PaginateSystemNotificationsParams
|
||||
): Promise<PaginateSystemNotificationsResults> {
|
||||
const skip = (data.page - 1) * data.limit;
|
||||
|
||||
// Construye los criterios de búsqueda
|
||||
const searchCriteria: mongoose.FilterQuery<ISystemNotification> = {};
|
||||
|
||||
// Agrega filtro por query usando expresiones regulares para 'name' y 'description'
|
||||
if (data.query) {
|
||||
const regex = new RegExp(data.query, "i");
|
||||
searchCriteria.$or = [{ subject: regex }, { message: regex }];
|
||||
}
|
||||
|
||||
// Filtra por categoryId si está presente
|
||||
if (data.userId !== undefined) {
|
||||
searchCriteria.userId = data.userId;
|
||||
}
|
||||
|
||||
if (data.companyId !== undefined) {
|
||||
searchCriteria.companyId = data.companyId;
|
||||
}
|
||||
|
||||
if (data.conversationId !== undefined) {
|
||||
searchCriteria.conversationId = data.conversationId;
|
||||
}
|
||||
|
||||
if (data.serviceId !== undefined) {
|
||||
searchCriteria._id = data.serviceId;
|
||||
}
|
||||
|
||||
if (data.readed) {
|
||||
searchCriteria.readed = data.readed;
|
||||
}
|
||||
|
||||
// Realiza la consulta con paginación
|
||||
const results = await this.notificationsList
|
||||
.find(searchCriteria)
|
||||
.sort({ notificationDate: -1 })
|
||||
.skip(skip)
|
||||
.limit(data.limit)
|
||||
.exec();
|
||||
|
||||
// Cuenta el total de documentos que coinciden con los criterios de búsqueda
|
||||
const count = await this.notificationsList.countDocuments(searchCriteria).exec();
|
||||
|
||||
return {
|
||||
data: results,
|
||||
page: data.page,
|
||||
pages: Math.ceil(count / data.limit),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
import { FilterQuery } from "mongoose";
|
||||
|
||||
export type FindSystemNotificationsParams = {
|
||||
id?: string;
|
||||
userId?: string;
|
||||
companyId?: string;
|
||||
serviceId?: string;
|
||||
conversationId?: string;
|
||||
notificationDate?: Date;
|
||||
readed?: boolean;
|
||||
sessionUser: string;
|
||||
};
|
||||
|
||||
export type ToggleStateSystemNotificationsParams = {
|
||||
state: boolean;
|
||||
sessionUser: string;
|
||||
};
|
||||
|
||||
export type PaginateSystemNotificationsParams = {
|
||||
query?: string;
|
||||
userId?: string;
|
||||
companyId?: string;
|
||||
serviceId?: string;
|
||||
conversationId?: string;
|
||||
dateFrom?: Date;
|
||||
dateTo?: Date;
|
||||
readed?: boolean;
|
||||
page: number;
|
||||
limit: number;
|
||||
sessionUser: string;
|
||||
};
|
||||
|
||||
export type UnreadNotificationResults = {
|
||||
count: number;
|
||||
};
|
||||
|
||||
export type PaginateSystemNotificationsResults = {
|
||||
data: ISystemNotification[];
|
||||
page: number;
|
||||
pages: number;
|
||||
};
|
||||
|
||||
export enum NotificationType {
|
||||
APPOINTMENT = 'APPOINTMENT',
|
||||
COMPANY = 'COMPANY',
|
||||
EMPLOYEE = 'EMPLOYEE',
|
||||
SCHEDULE = 'SCHEDULE',
|
||||
SCHEDULE_EXCEPTION = 'SCHEDULE_EXCEPTION',
|
||||
SCHEDULE_RESTRICTION = 'SCHEDULE_RESTRICTION',
|
||||
MESSAGE = 'MESSAGE',
|
||||
BILLING = 'BILLING',
|
||||
SYSTEM = 'SYSTEM'
|
||||
}
|
||||
|
||||
export type CreateSystemNotificationParams = {
|
||||
userId?: string;
|
||||
companyId?: string;
|
||||
serviceId?: number;
|
||||
conversationId?: string;
|
||||
subject: string;
|
||||
message: string;
|
||||
type?: string;
|
||||
code?: string;
|
||||
};
|
||||
|
||||
export type UpdateSystemNotificationParams = {
|
||||
id: string;
|
||||
readed: boolean;
|
||||
sessionUser: string;
|
||||
};
|
||||
|
||||
export type DeleteSystemNotificationParams = {
|
||||
id: string;
|
||||
sessionUser: string;
|
||||
};
|
||||
|
||||
export type DeleteSystemNotificationsByConversation = {
|
||||
conversationId: string;
|
||||
userId: string;
|
||||
sessionUser: string;
|
||||
};
|
||||
|
||||
export type DeleteNotificationsByUserParams = {
|
||||
userId: string;
|
||||
};
|
||||
|
||||
export type DeleteNotificationsByDateParams = {
|
||||
userId: string;
|
||||
dateFrom?: Date;
|
||||
dateTo?: Date;
|
||||
sessionUser: string;
|
||||
};
|
||||
|
||||
export interface ISystemNotification {
|
||||
id?: string;
|
||||
userId?: string;
|
||||
companyId?: string;
|
||||
serviceId?: string;
|
||||
conversationId?: string;
|
||||
subject: string;
|
||||
message: string;
|
||||
notificationDate: Date;
|
||||
readed: boolean;
|
||||
type?: string;
|
||||
code?: string;
|
||||
}
|
||||
|
||||
export interface ISystemNotificationsAdapter {
|
||||
create(data: CreateSystemNotificationParams): Promise<ISystemNotification>;
|
||||
update(data: UpdateSystemNotificationParams): Promise<void>;
|
||||
delete(id: string): Promise<void>;
|
||||
deleteMany(data: Omit<DeleteSystemNotificationsByConversation, "sessionUser">): Promise<void>;
|
||||
find(filters: FindSystemNotificationsParams): Promise<ISystemNotification[]>;
|
||||
findOne(filters: FindSystemNotificationsParams): Promise<ISystemNotification | null>;
|
||||
paginate(filters: PaginateSystemNotificationsParams): Promise<PaginateSystemNotificationsResults>;
|
||||
deleteByQuery(data: FilterQuery<ISystemNotification>): Promise<void>;
|
||||
}
|
||||
|
||||
export interface ISystemNotificationsManager {
|
||||
notifications: ISystemNotificationsAdapter;
|
||||
createNotification(data: CreateSystemNotificationParams): Promise<ISystemNotification>;
|
||||
updateNotification(data: UpdateSystemNotificationParams): Promise<void>;
|
||||
deleteNotification(data: DeleteSystemNotificationParams): Promise<void>;
|
||||
deleteConversationNotifications(data: DeleteSystemNotificationsByConversation): Promise<void>;
|
||||
paginateNotifications(
|
||||
data: PaginateSystemNotificationsParams
|
||||
): Promise<PaginateSystemNotificationsResults>;
|
||||
finUnreadNotifications(data: FindSystemNotificationsParams): Promise<UnreadNotificationResults>;
|
||||
deleteNotificationsByUser(data: DeleteNotificationsByUserParams): Promise<void>;
|
||||
setStateByUser(data: ToggleStateSystemNotificationsParams): Promise<void>;
|
||||
deleteNotificationsByDate(data: DeleteNotificationsByDateParams): Promise<void>;
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
import CompaniesManager from "../Companies/Companies";
|
||||
import {
|
||||
CreateSystemNotificationParams,
|
||||
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<void> {
|
||||
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<void> {
|
||||
await this.notifications.notificationsList.deleteMany({ userId: data.userId });
|
||||
}
|
||||
|
||||
public async deleteNotificationsByDate(data: DeleteNotificationsByDateParams): Promise<void> {
|
||||
await validateSessionUser({
|
||||
sessionUser: data.sessionUser,
|
||||
});
|
||||
|
||||
if (data.sessionUser !== data.userId) {
|
||||
throw new Error("No tienes permiso para eliminar estas notificaciones");
|
||||
}
|
||||
|
||||
const deleteFilter: FilterQuery<ISystemNotification> = { 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<ISystemNotification> {
|
||||
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 updateNotification(data: UpdateSystemNotificationParams): Promise<void> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
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<PaginateSystemNotificationsResults> {
|
||||
return await this.notifications.paginate(filters);
|
||||
}
|
||||
|
||||
public async finUnreadNotifications(
|
||||
data: FindSystemNotificationsParams
|
||||
): Promise<UnreadNotificationResults> {
|
||||
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;
|
||||
Reference in New Issue
Block a user