import { Injectable, Logger } from '@nestjs/common'; import { Cron, CronExpression } from '@nestjs/schedule'; import { SalonNotificationsService } from '../notifications/salon-notifications.service'; import { SmsService } from '../sms/sms.service'; import { SalonSubscriptionsService } from './salon-subscriptions.service'; @Injectable() export class SubscriptionAutomationService { private readonly logger = new Logger(SubscriptionAutomationService.name); constructor( private readonly salonSubscriptionsService: SalonSubscriptionsService, private readonly salonNotificationsService: SalonNotificationsService, private readonly smsService: SmsService, ) {} /** * Detects subscriptions (trial or paid) whose validity period just ended * and, once per subscription, notifies the salon owner in-app and by SMS * that they need to purchase a plan to keep using the product. Access is * already blocked automatically by `ActiveSubscriptionGuard` once the * subscription's `endDate` has passed, independent of this job. */ @Cron(CronExpression.EVERY_DAY_AT_10AM, { name: 'subscription-expiry-notifications', }) async notifyExpiredSubscriptions(): Promise { const subscriptions = await this.salonSubscriptionsService.findSubscriptionsPendingExpiryNotification(); let notifiedCount = 0; for (const subscription of subscriptions) { try { await this.salonSubscriptionsService.markExpiryNotified( subscription.id, ); const planLabel = subscription.plan?.isTrial ? 'دوره آزمایشی رایگان' : `اشتراک ${subscription.plan?.name ?? ''}`.trim(); await this.salonNotificationsService.notifySubscriptionExpired({ salonId: subscription.salonId, salonOwnerId: subscription.salon.ownerId, salonName: subscription.salon.name, planLabel, endDate: subscription.endDate, }); const ownerMobile = subscription.salon.owner?.mobile; if (ownerMobile) { await this.smsService.sendSms( ownerMobile, `${planLabel} سالن ${subscription.salon.name} به پایان رسید. برای ادامه استفاده از امکانات و ارسال پیامک، همین حالا اشتراک تهیه کنید.`, ); } notifiedCount += 1; } catch (error) { this.logger.error( `Failed to send expiry notification for subscription ${subscription.id}`, error instanceof Error ? error.stack : undefined, ); } } if (notifiedCount > 0) { this.logger.log( `Sent expiry notifications for ${notifiedCount} subscription(s)`, ); } return notifiedCount; } }