payment
This commit is contained in:
@@ -21,259 +21,259 @@ export class NotificationService {
|
||||
private readonly smsLogRepository: SmsLogRepository,
|
||||
) { }
|
||||
|
||||
async sendNotification(params: NotifRequest): Promise<Notification[]> {
|
||||
const { recipients, message, metadata, } = params;
|
||||
// async sendNotification(params: NotifRequest): Promise<Notification[]> {
|
||||
// const { recipients, message, metadata, } = params;
|
||||
|
||||
// create Database notifications
|
||||
const notifications = await this.createAdminBulkNotifications(
|
||||
recipients.map(recipient => ({
|
||||
title: message.title,
|
||||
content: message.content,
|
||||
adminId: 'adminId' in recipient ? recipient.adminId : null,
|
||||
userId: 'userId' in recipient ? recipient.userId : null,
|
||||
})),
|
||||
);
|
||||
// // create Database notifications
|
||||
// const notifications = await this.createAdminBulkNotifications(
|
||||
// recipients.map(recipient => ({
|
||||
// title: message.title,
|
||||
// content: message.content,
|
||||
// adminId: 'adminId' in recipient ? recipient.adminId : null,
|
||||
// userId: 'userId' in recipient ? recipient.userId : null,
|
||||
// })),
|
||||
// );
|
||||
|
||||
// get admin prefrences
|
||||
const preference = await this.preferenceService.findByRestaurantAndType(, message.title);
|
||||
// // get admin prefrences
|
||||
// const preference = await this.preferenceService.findByRestaurantAndType(, message.title);
|
||||
|
||||
if(preference?.channels?.length === 0) {
|
||||
this.logger.warn(`Notification type is NONE for restaurant ${}, title ${message.title}`);
|
||||
return notifications;
|
||||
}
|
||||
// if(preference?.channels?.length === 0) {
|
||||
// this.logger.warn(`Notification type is NONE for restaurant ${}, title ${message.title}`);
|
||||
// return notifications;
|
||||
// }
|
||||
|
||||
// send in app notification
|
||||
if (preference?.channels?.includes(NotifChannelEnum.IN_APP)) {
|
||||
await this.queueService.addBulkInAppNotifications(
|
||||
notifications.map(notification => ({
|
||||
recipient: { adminId: notification.admin?.id || '', },
|
||||
subject: message.title,
|
||||
body: message.content,
|
||||
notificationId: notification.id,
|
||||
})),
|
||||
);
|
||||
}
|
||||
// // send in app notification
|
||||
// if (preference?.channels?.includes(NotifChannelEnum.IN_APP)) {
|
||||
// await this.queueService.addBulkInAppNotifications(
|
||||
// notifications.map(notification => ({
|
||||
// recipient: { adminId: notification.admin?.id || '', },
|
||||
// subject: message.title,
|
||||
// body: message.content,
|
||||
// notificationId: notification.id,
|
||||
// })),
|
||||
// );
|
||||
// }
|
||||
|
||||
// add sms notifications to queue
|
||||
if (preference?.channels?.includes(NotifChannelEnum.SMS)) {
|
||||
await this.queueService.addBulkSmsNotifications(
|
||||
recipients.map(recipient => ({
|
||||
recipient,
|
||||
templateId: message.sms.templateId,
|
||||
parameters: message.sms.parameters,
|
||||
})),
|
||||
);
|
||||
}
|
||||
// // add sms notifications to queue
|
||||
// if (preference?.channels?.includes(NotifChannelEnum.SMS)) {
|
||||
// await this.queueService.addBulkSmsNotifications(
|
||||
// recipients.map(recipient => ({
|
||||
// recipient,
|
||||
// templateId: message.sms.templateId,
|
||||
// parameters: message.sms.parameters,
|
||||
// })),
|
||||
// );
|
||||
// }
|
||||
|
||||
this.logger.log(`Queued notification for restaurant ${}, title ${message.title}`);
|
||||
// this.logger.log(`Queued notification for restaurant ${}, title ${message.title}`);
|
||||
|
||||
return notifications;
|
||||
}
|
||||
// return notifications;
|
||||
// }
|
||||
|
||||
async createAdminBulkNotifications(
|
||||
params: {
|
||||
// async createAdminBulkNotifications(
|
||||
// params: {
|
||||
|
||||
title: NotifTitleEnum;
|
||||
content: string;
|
||||
adminId: string | null;
|
||||
userId: string | null;
|
||||
}[],
|
||||
): Promise < Notification[] > {
|
||||
const notifications = params.map(param => {
|
||||
return this.em.create(Notification, {
|
||||
admin: param.adminId,
|
||||
user: param.userId && param.userId.trim() !== '' ? param.userId : null,
|
||||
title: param.title,
|
||||
content: param.content,
|
||||
});
|
||||
});
|
||||
await this.em.persistAndFlush(notifications);
|
||||
return notifications;
|
||||
}
|
||||
|
||||
async findOne(id: string): Promise < Notification > {
|
||||
const notification = await this.em.findOne(Notification, { id }, { populate: ['restaurant', 'user'] });
|
||||
if(!notification) {
|
||||
throw new NotFoundException('Notification not found');
|
||||
}
|
||||
return notification;
|
||||
}
|
||||
|
||||
async findByRestaurant(
|
||||
: string,
|
||||
adminId: string,
|
||||
limit = 50,
|
||||
cursor ?: string,
|
||||
status ?: 'seen' | 'unseen',
|
||||
): Promise < { data: Notification[]; nextCursor: string | null } > {
|
||||
const where: FilterQuery<Notification> = {
|
||||
restaurant: { id: },
|
||||
admin: { id: adminId },
|
||||
};
|
||||
|
||||
// Filter by status (seen/unseen)
|
||||
if (status === 'seen') {
|
||||
where.seenAt = { $ne: null };
|
||||
} else if (status === 'unseen') {
|
||||
where.seenAt = null;
|
||||
}
|
||||
|
||||
// Cursor-based pagination: if cursor is provided, get items with id < cursor
|
||||
if (cursor) {
|
||||
where.id = { $lt: cursor };
|
||||
}
|
||||
|
||||
const notifications = await this.em.find(Notification, where, {
|
||||
orderBy: { createdAt: 'DESC', id: 'DESC' },
|
||||
limit: limit + 1, // fetch one extra to determine next page
|
||||
populate: ['user'],
|
||||
});
|
||||
|
||||
const hasNextPage = notifications.length > limit;
|
||||
const data = hasNextPage ? notifications.slice(0, limit) : notifications;
|
||||
const nextCursor = hasNextPage && data.length > 0 ? data[data.length - 1].id : null;
|
||||
|
||||
return {
|
||||
data,
|
||||
nextCursor: nextCursor ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
async findByUserAndRestaurant(
|
||||
userId: string,
|
||||
: string,
|
||||
limit = 50,
|
||||
cursor ?: string,
|
||||
status ?: 'seen' | 'unseen',
|
||||
): Promise < { data: Notification[]; nextCursor: string | null } > {
|
||||
const where: FilterQuery<Notification> = {
|
||||
user: { id: userId },
|
||||
restaurant: { id: },
|
||||
};
|
||||
|
||||
// Filter by status (seen/unseen)
|
||||
if (status === 'seen') {
|
||||
where.seenAt = { $ne: null };
|
||||
} else if (status === 'unseen') {
|
||||
where.seenAt = null;
|
||||
}
|
||||
|
||||
// Cursor-based pagination: if cursor is provided, get items with id < cursor (since ULIDs are time-ordered)
|
||||
if (cursor) {
|
||||
where.id = { $lt: cursor };
|
||||
}
|
||||
|
||||
const notifications = await this.em.find(Notification, where, {
|
||||
orderBy: { createdAt: 'DESC', id: 'DESC' },
|
||||
limit: limit + 1, // Fetch one extra to determine if there's a next page
|
||||
});
|
||||
|
||||
// Check if there's a next page
|
||||
const hasNextPage = notifications.length > limit;
|
||||
const data = hasNextPage ? notifications.slice(0, limit) : notifications;
|
||||
const nextCursor = hasNextPage && data.length > 0 ? data[data.length - 1].id : null;
|
||||
|
||||
return {
|
||||
data,
|
||||
nextCursor: nextCursor ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
async readNotificationAdmin(id: string, adminId: string, : string): Promise < void> {
|
||||
const notification = await this.em.findOne(Notification, {
|
||||
id,
|
||||
admin: { id: adminId },
|
||||
restaurant: { id: },
|
||||
});
|
||||
if(!notification) {
|
||||
throw new NotFoundException('Notification not found');
|
||||
}
|
||||
notification.seenAt = new Date();
|
||||
await this.em.persistAndFlush(notification);
|
||||
}
|
||||
async readNotificationAsUser(id: string, userId: string, : string): Promise < void> {
|
||||
const notification = await this.em.findOne(Notification, {
|
||||
id,
|
||||
user: { id: userId },
|
||||
restaurant: { id: },
|
||||
});
|
||||
if(!notification) {
|
||||
throw new NotFoundException('Notification not found');
|
||||
}
|
||||
notification.seenAt = new Date();
|
||||
await this.em.persistAndFlush(notification);
|
||||
}
|
||||
|
||||
async findByRestaurantAndType(: string, title: NotifTitleEnum, limit = 50): Promise < Notification[] > {
|
||||
return this.em.find(
|
||||
Notification,
|
||||
{
|
||||
restaurant: { id: },
|
||||
title,
|
||||
},
|
||||
{
|
||||
orderBy: { createdAt: 'DESC' },
|
||||
limit,
|
||||
populate: ['user'],
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async findByAdminAndRestaurant(adminId: string, : string, limit = 50): Promise < Notification[] > {
|
||||
return this.em.find(
|
||||
Notification,
|
||||
{ admin: { id: adminId }, restaurant: { id: } },
|
||||
{
|
||||
orderBy: { createdAt: 'DESC' },
|
||||
limit,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async countUnseenByUserAndRestaurant(userId: string, : string): Promise < number > {
|
||||
const where: FilterQuery<Notification> = {
|
||||
user: { id: userId },
|
||||
restaurant: { id: },
|
||||
seenAt: null,
|
||||
};
|
||||
return this.em.count(Notification, where);
|
||||
}
|
||||
|
||||
async countUnseenByRestaurant(adminId: string, : string): Promise < number > {
|
||||
const where: FilterQuery<Notification> = {
|
||||
admin: { id: adminId },
|
||||
restaurant: { id: },
|
||||
seenAt: null,
|
||||
};
|
||||
return this.em.count(Notification, where);
|
||||
}
|
||||
|
||||
readAllNotifsAsUser(userId: string, : string): Promise < number > {
|
||||
const where: FilterQuery<Notification> = {
|
||||
user: { id: userId },
|
||||
restaurant: { id: },
|
||||
seenAt: null,
|
||||
};
|
||||
return this.em.nativeUpdate(Notification, where, { seenAt: new Date() });
|
||||
}
|
||||
|
||||
readAllNotifsAsAdmin(adminId: string, : string): Promise < number > {
|
||||
const where: FilterQuery<Notification> = {
|
||||
admin: { id: adminId },
|
||||
restaurant: { id: },
|
||||
seenAt: null,
|
||||
};
|
||||
return this.em.nativeUpdate(Notification, where, { seenAt: new Date() });
|
||||
}
|
||||
|
||||
async getSmsCountByRestaurant(
|
||||
page: number = 1,
|
||||
limit: number = 10,
|
||||
): Promise < PaginatedResult < { : string; restaurantName: string; smsCount: number } >> {
|
||||
return this.smsLogRepository.getSmsCountByRestaurant(page, limit);
|
||||
}
|
||||
|
||||
async getSmsCountBy(: string): Promise < number > {
|
||||
return this.smsLogRepository.getSmsCountBy();
|
||||
}
|
||||
// title: NotifTitleEnum;
|
||||
// content: string;
|
||||
// adminId: string | null;
|
||||
// userId: string | null;
|
||||
// }[],
|
||||
// ): Promise < Notification[] > {
|
||||
// const notifications = params.map(param => {
|
||||
// return this.em.create(Notification, {
|
||||
// admin: param.adminId,
|
||||
// user: param.userId && param.userId.trim() !== '' ? param.userId : null,
|
||||
// title: param.title,
|
||||
// content: param.content,
|
||||
// });
|
||||
// });
|
||||
// await this.em.persistAndFlush(notifications);
|
||||
// return notifications;
|
||||
// }
|
||||
|
||||
// async findOne(id: string): Promise < Notification > {
|
||||
// const notification = await this.em.findOne(Notification, { id }, { populate: ['restaurant', 'user'] });
|
||||
// if(!notification) {
|
||||
// throw new NotFoundException('Notification not found');
|
||||
// }
|
||||
// return notification;
|
||||
// }
|
||||
|
||||
// async findByRestaurant(
|
||||
// : string,
|
||||
// adminId: string,
|
||||
// limit = 50,
|
||||
// cursor ?: string,
|
||||
// status ?: 'seen' | 'unseen',
|
||||
// ): Promise < { data: Notification[]; nextCursor: string | null } > {
|
||||
// const where: FilterQuery<Notification> = {
|
||||
// restaurant: { id: },
|
||||
// admin: { id: adminId },
|
||||
// };
|
||||
|
||||
// // Filter by status (seen/unseen)
|
||||
// if (status === 'seen') {
|
||||
// where.seenAt = { $ne: null };
|
||||
// } else if (status === 'unseen') {
|
||||
// where.seenAt = null;
|
||||
// }
|
||||
|
||||
// // Cursor-based pagination: if cursor is provided, get items with id < cursor
|
||||
// if (cursor) {
|
||||
// where.id = { $lt: cursor };
|
||||
// }
|
||||
|
||||
// const notifications = await this.em.find(Notification, where, {
|
||||
// orderBy: { createdAt: 'DESC', id: 'DESC' },
|
||||
// limit: limit + 1, // fetch one extra to determine next page
|
||||
// populate: ['user'],
|
||||
// });
|
||||
|
||||
// const hasNextPage = notifications.length > limit;
|
||||
// const data = hasNextPage ? notifications.slice(0, limit) : notifications;
|
||||
// const nextCursor = hasNextPage && data.length > 0 ? data[data.length - 1].id : null;
|
||||
|
||||
// return {
|
||||
// data,
|
||||
// nextCursor: nextCursor ?? null,
|
||||
// };
|
||||
// }
|
||||
|
||||
// async findByUserAndRestaurant(
|
||||
// userId: string,
|
||||
// : string,
|
||||
// limit = 50,
|
||||
// cursor ?: string,
|
||||
// status ?: 'seen' | 'unseen',
|
||||
// ): Promise < { data: Notification[]; nextCursor: string | null } > {
|
||||
// const where: FilterQuery<Notification> = {
|
||||
// user: { id: userId },
|
||||
// restaurant: { id: },
|
||||
// };
|
||||
|
||||
// // Filter by status (seen/unseen)
|
||||
// if (status === 'seen') {
|
||||
// where.seenAt = { $ne: null };
|
||||
// } else if (status === 'unseen') {
|
||||
// where.seenAt = null;
|
||||
// }
|
||||
|
||||
// // Cursor-based pagination: if cursor is provided, get items with id < cursor (since ULIDs are time-ordered)
|
||||
// if (cursor) {
|
||||
// where.id = { $lt: cursor };
|
||||
// }
|
||||
|
||||
// const notifications = await this.em.find(Notification, where, {
|
||||
// orderBy: { createdAt: 'DESC', id: 'DESC' },
|
||||
// limit: limit + 1, // Fetch one extra to determine if there's a next page
|
||||
// });
|
||||
|
||||
// // Check if there's a next page
|
||||
// const hasNextPage = notifications.length > limit;
|
||||
// const data = hasNextPage ? notifications.slice(0, limit) : notifications;
|
||||
// const nextCursor = hasNextPage && data.length > 0 ? data[data.length - 1].id : null;
|
||||
|
||||
// return {
|
||||
// data,
|
||||
// nextCursor: nextCursor ?? null,
|
||||
// };
|
||||
// }
|
||||
|
||||
// async readNotificationAdmin(id: string, adminId: string, : string): Promise < void> {
|
||||
// const notification = await this.em.findOne(Notification, {
|
||||
// id,
|
||||
// admin: { id: adminId },
|
||||
// restaurant: { id: },
|
||||
// });
|
||||
// if(!notification) {
|
||||
// throw new NotFoundException('Notification not found');
|
||||
// }
|
||||
// notification.seenAt = new Date();
|
||||
// await this.em.persistAndFlush(notification);
|
||||
// }
|
||||
// async readNotificationAsUser(id: string, userId: string, : string): Promise < void> {
|
||||
// const notification = await this.em.findOne(Notification, {
|
||||
// id,
|
||||
// user: { id: userId },
|
||||
// restaurant: { id: },
|
||||
// });
|
||||
// if(!notification) {
|
||||
// throw new NotFoundException('Notification not found');
|
||||
// }
|
||||
// notification.seenAt = new Date();
|
||||
// await this.em.persistAndFlush(notification);
|
||||
// }
|
||||
|
||||
// async findByRestaurantAndType(: string, title: NotifTitleEnum, limit = 50): Promise < Notification[] > {
|
||||
// return this.em.find(
|
||||
// Notification,
|
||||
// {
|
||||
// restaurant: { id: },
|
||||
// title,
|
||||
// },
|
||||
// {
|
||||
// orderBy: { createdAt: 'DESC' },
|
||||
// limit,
|
||||
// populate: ['user'],
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
|
||||
// async findByAdminAndRestaurant(adminId: string, : string, limit = 50): Promise < Notification[] > {
|
||||
// return this.em.find(
|
||||
// Notification,
|
||||
// { admin: { id: adminId }, restaurant: { id: } },
|
||||
// {
|
||||
// orderBy: { createdAt: 'DESC' },
|
||||
// limit,
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
|
||||
// async countUnseenByUserAndRestaurant(userId: string, : string): Promise < number > {
|
||||
// const where: FilterQuery<Notification> = {
|
||||
// user: { id: userId },
|
||||
// restaurant: { id: },
|
||||
// seenAt: null,
|
||||
// };
|
||||
// return this.em.count(Notification, where);
|
||||
// }
|
||||
|
||||
// async countUnseenByRestaurant(adminId: string, : string): Promise < number > {
|
||||
// const where: FilterQuery<Notification> = {
|
||||
// admin: { id: adminId },
|
||||
// restaurant: { id: },
|
||||
// seenAt: null,
|
||||
// };
|
||||
// return this.em.count(Notification, where);
|
||||
// }
|
||||
|
||||
// readAllNotifsAsUser(userId: string, : string): Promise < number > {
|
||||
// const where: FilterQuery<Notification> = {
|
||||
// user: { id: userId },
|
||||
// restaurant: { id: },
|
||||
// seenAt: null,
|
||||
// };
|
||||
// return this.em.nativeUpdate(Notification, where, { seenAt: new Date() });
|
||||
// }
|
||||
|
||||
// readAllNotifsAsAdmin(adminId: string, : string): Promise < number > {
|
||||
// const where: FilterQuery<Notification> = {
|
||||
// admin: { id: adminId },
|
||||
// restaurant: { id: },
|
||||
// seenAt: null,
|
||||
// };
|
||||
// return this.em.nativeUpdate(Notification, where, { seenAt: new Date() });
|
||||
// }
|
||||
|
||||
// async getSmsCountByRestaurant(
|
||||
// page: number = 1,
|
||||
// limit: number = 10,
|
||||
// ): Promise < PaginatedResult < { : string; restaurantName: string; smsCount: number } >> {
|
||||
// return this.smsLogRepository.getSmsCountByRestaurant(page, limit);
|
||||
// }
|
||||
|
||||
// async getSmsCountBy(: string): Promise < number > {
|
||||
// return this.smsLogRepository.getSmsCountBy();
|
||||
// }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user