trial
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
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<number> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user