add : extend user subscription

This commit is contained in:
morteza-mortezai
2025-11-12 17:37:31 +03:30
parent b3f6ce05c5
commit 45036227da
4 changed files with 118 additions and 3 deletions
@@ -17,7 +17,7 @@ import { SUBSCRIPTIONS } from "../constants";
import { AddSubscriptionsToServiceDto } from "../DTO/create-subscription.dto";
import { SearchUserSubsQueryDto } from "../DTO/search-user-subs-query.dto";
import { ServiceSubsQueryDto } from "../DTO/service-subs-query.dto";
import { SubscribeServiceDto } from "../DTO/subscribe-service.dto";
import { ExtendUSerSubscribeServiceDto, SubscribeServiceDto } from "../DTO/subscribe-service.dto";
import { SubscriptionAccessDto } from "../DTO/subscription-access-dto";
import { UpdateSubscriptionPlanDto } from "../DTO/update-subscription.dto";
import { SubscriptionPlan } from "../entities/subscription.entity";
@@ -300,6 +300,86 @@ export class SubscriptionsService {
await queryRunner.release();
}
}
//************************************ */
async extendSubscribeToPlan(userSubscriptionId: string, dto: ExtendUSerSubscribeServiceDto, userId: string) {
const queryRunner = this.dataSource.createQueryRunner();
let isFree = false;
try {
await queryRunner.connect();
await queryRunner.startTransaction();
const userSubscription = await queryRunner.manager.findOne(UserSubscription, {
where: { id: userSubscriptionId },
relations: {
user: true,
plan: true,
},
});
if (!userSubscription) throw new BadRequestException(SubscriptionMessage.NOT_FOUND);
const user = await this.usersService.findOneByIdWithQueryRunner(userId, queryRunner);
const plan = await queryRunner.manager.findOne(SubscriptionPlan, {
where: { id: dto.planId, service: { id: dto.serviceId } },
relations: { service: true, directDiscount: true, }
});
if (!plan) throw new BadRequestException(SubscriptionMessage.NOT_FOUND);
if (plan.isFree) {
isFree = true;
const oneMonthAgo = dayjs().subtract(1, "month").toDate();
const existingFreePlanSubscription = await queryRunner.manager.findOne(UserSubscription, {
where: {
user: { id: userId },
plan: { isFree: true },
startDate: MoreThan(oneMonthAgo),
},
relations: {
plan: true,
},
});
if (existingFreePlanSubscription) {
throw new BadRequestException(SubscriptionMessage.FREE_PLAN_LIMIT_EXCEEDED);
}
}
const startDate =
userSubscription && dayjs(userSubscription.endDate).isAfter(dayjs()) ? dayjs(userSubscription.endDate).toDate() : dayjs().toDate();
const endDate = dayjs(startDate).add(plan.duration, "day").toDate();
// await queryRunner.manager.save(UserSubscription, userSubscription);
const invoiceDueDate = dayjs().add(INVOICE.DUEDATE, "day").toDate();
const invoice = await this.invoicesService.createInvoiceForSubscription(user, plan, userSubscription, invoiceDueDate, queryRunner);
userSubscription.plan = plan;
userSubscription.endDate = endDate;
await queryRunner.manager.save(userSubscription);
await this.addProvisioningJob(userSubscription, plan, user);
if (isFree) {
await this.invoicesService.payInvoice(invoice.id, user.id, undefined, queryRunner);
}
await queryRunner.commitTransaction();
return {
message: SubscriptionMessage.SUBSCRIBED,
userSubscription,
invoice,
};
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
}
//************************************ */
async getServiceSubscriptions(serviceId: string, queryDto: ServiceSubsQueryDto) {
const service = await this.danakServices.findServiceById(serviceId);