diff --git a/src/modules/notifications/controllers/notifications.controller.ts b/src/modules/notifications/controllers/notifications.controller.ts index 086d54f..bccf4e5 100644 --- a/src/modules/notifications/controllers/notifications.controller.ts +++ b/src/modules/notifications/controllers/notifications.controller.ts @@ -10,6 +10,7 @@ import { UpdatePreferenceDto } from '../dto/update-preference.dto'; import { AdminId } from 'src/common/decorators/admin-id.decorator'; import { API_HEADER_SLUG } from 'src/common/constants/index'; import { NotificationMessage } from 'src/common/enums/message.enum'; +import { SuperAdminAuthGuard } from 'src/modules/auth/guards/superAdminAuth.guard'; @ApiTags('notifications') @Controller() @@ -149,4 +150,19 @@ export class NotificationsController { ) { return this.preferenceService.updatePreference(preferenceId, restaurantId, dto); } + + @UseGuards(SuperAdminAuthGuard) + @ApiBearerAuth() + @Get('super-admin/sms-count') + @ApiOperation({ summary: 'Get SMS count for each restaurant with pagination' }) + @ApiQuery({ name: 'page', required: false, type: Number, description: 'Page number (default: 1)', minimum: 1 }) + @ApiQuery({ name: 'limit', required: false, type: Number, description: 'Items per page (default: 10)', minimum: 1 }) + async getSmsCount( + @Query('page') page?: number, + @Query('limit') limit?: number, + ) { + const parsedPage = page ? parseInt(page.toString(), 10) : 1; + const parsedLimit = limit ? parseInt(limit.toString(), 10) : 10; + return await this.notificationService.getSmsCountByRestaurant(parsedPage, parsedLimit); + } } diff --git a/src/modules/notifications/repositories/sms-log.repository.ts b/src/modules/notifications/repositories/sms-log.repository.ts index 2653094..0b4f9cf 100644 --- a/src/modules/notifications/repositories/sms-log.repository.ts +++ b/src/modules/notifications/repositories/sms-log.repository.ts @@ -1,11 +1,63 @@ import { Injectable } from '@nestjs/common'; import { EntityManager, EntityRepository } from '@mikro-orm/postgresql'; import { SmsLog } from '../entities/smsLogs.entity'; +import { PaginatedResult } from '../../../common/interfaces/pagination.interface'; @Injectable() export class SmsLogRepository extends EntityRepository { constructor(readonly em: EntityManager) { super(em, SmsLog); } + + async getSmsCountByRestaurant( + page: number = 1, + limit: number = 10, + ): Promise> { + const offset = (page - 1) * limit; + + // Get total count of unique restaurants with SMS logs + const totalResult = await this.em.execute( + ` + SELECT COUNT(DISTINCT sl.restaurant_id) as total + FROM sms_logs sl + WHERE sl.restaurant_id IS NOT NULL + `, + ); + const total = parseInt(totalResult[0]?.total || '0', 10); + + // Get paginated results with SMS counts grouped by restaurant + const results = await this.em.execute( + ` + SELECT + r.id as "restaurantId", + r.name as "restaurantName", + COUNT(sl.id)::int as "smsCount" + FROM sms_logs sl + INNER JOIN restaurants r ON sl.restaurant_id = r.id + GROUP BY r.id, r.name + ORDER BY "smsCount" DESC, r.name ASC + LIMIT ? OFFSET ? + `, + [limit, offset], + ); + + const data = results.map((row: any) => ({ + restaurantId: row.restaurantId, + restaurantName: row.restaurantName || 'Unknown', + smsCount: parseInt(row.smsCount || '0', 10), + })); + + const totalPages = Math.ceil(total / limit); + + return { + data, + meta: { + total, + page, + limit, + totalPages, + }, + }; + } } diff --git a/src/modules/notifications/services/notification.service.ts b/src/modules/notifications/services/notification.service.ts index b35dca5..18f20e8 100644 --- a/src/modules/notifications/services/notification.service.ts +++ b/src/modules/notifications/services/notification.service.ts @@ -5,6 +5,9 @@ import { NotificationPreferenceService } from './notification-preference.service import { NotificationQueueService } from './notification-queue.service'; import { NotificationsGateway } from '../notifications.gateway'; import { NotifChannelEnum, NotifRequest, NotifTitleEnum } from '../interfaces/notification.interface'; +import { SmsLog } from '../entities/smsLogs.entity'; +import { SmsLogRepository } from '../repositories/sms-log.repository'; +import { PaginatedResult } from '../../../common/interfaces/pagination.interface'; @Injectable() export class NotificationService { @@ -15,6 +18,7 @@ export class NotificationService { private readonly preferenceService: NotificationPreferenceService, private readonly queueService: NotificationQueueService, private readonly notificationGateway: NotificationsGateway, + private readonly smsLogRepository: SmsLogRepository, ) { } async sendNotification(params: NotifRequest): Promise { @@ -263,4 +267,11 @@ export class NotificationService { }; return this.em.nativeUpdate(Notification, where, { seenAt: new Date() }); } + + async getSmsCountByRestaurant( + page: number = 1, + limit: number = 10, + ): Promise> { + return this.smsLogRepository.getSmsCountByRestaurant(page, limit); + } }