feat: implement support plan subscription functionality

This commit is contained in:
mahyargdz
2025-05-05 17:01:13 +03:30
parent 47c9cd47e6
commit 1ea3195f4f
9 changed files with 177 additions and 5 deletions
@@ -1,17 +1,26 @@
import { BadRequestException, Injectable } from "@nestjs/common";
import dayjs from "dayjs";
import { DataSource } from "typeorm";
import { SupportPlanMessage } from "../../../common/enums/message.enum";
import { INVOICE } from "../../invoices/constants";
import { InvoicesService } from "../../invoices/providers/invoices.service";
import { UsersService } from "../../users/providers/users.service";
import { CreateSupportPlanDto } from "../DTO/create-support-plan.dto";
import { GetSupportPlanListQueryDto } from "../DTO/get-support-plan-list-query.dto";
import { UpdateSupportPlanDto } from "../DTO/update-support-plan-feature.dto";
import { UserSupportPlanStatus } from "../enums/user-support-plan-status.enum";
import { SupportPlanFeatureRepository } from "../repositories/support-plan-feature.repository";
import { SupportPlanRepository } from "../repositories/support-plan.repository";
import { UserSupportPlanRepository } from "../repositories/user-support-plan.repository";
@Injectable()
export class SupportPlansService {
constructor(
private readonly supportPlanRepo: SupportPlanRepository,
private readonly supportPlanFeatureRepo: SupportPlanFeatureRepository,
private readonly userSupportPlanRepo: UserSupportPlanRepository,
private readonly usersService: UsersService,
private readonly invoicesService: InvoicesService,
private readonly dataSource: DataSource,
) {}
@@ -32,6 +41,14 @@ export class SupportPlansService {
paginate: true,
};
}
//***************************************** */
async getSupportPlansListUser() {
const supportPlans = await this.supportPlanRepo.getSupportPlansListUser();
return {
supportPlans,
};
}
//***************************************** */
async getSupportPlanById(id: string) {
const supportPlan = await this.supportPlanRepo.getSupportPlanById(id);
@@ -90,4 +107,60 @@ export class SupportPlansService {
await queryRunner.release();
}
}
//***************************************** */
async subscribeToSupportPlan(id: string, userId: string) {
const queryRunner = this.dataSource.createQueryRunner();
try {
await queryRunner.connect();
await queryRunner.startTransaction();
const supportPlan = await queryRunner.manager.findOne(this.supportPlanRepo.target, { where: { id } });
if (!supportPlan) throw new BadRequestException(SupportPlanMessage.SUPPORT_PLAN_NOT_FOUND);
const user = await this.usersService.findOneByIdWithQueryRunner(userId, queryRunner);
const existingUserSupportPlan = await queryRunner.manager.findOne(this.userSupportPlanRepo.target, {
where: { user: { id: userId }, supportPlan: { id } },
});
if (existingUserSupportPlan) throw new BadRequestException(SupportPlanMessage.SUPPORT_PLAN_ALREADY_SUBSCRIBED_OR_INVOICE_EXIST);
const existingUserSupport = await queryRunner.manager.findOne(this.userSupportPlanRepo.target, {
where: { user: { id: userId } },
});
if (existingUserSupport) throw new BadRequestException(SupportPlanMessage.USER_ALREADY_HAS_SUPPORT_PLAN);
const startDate = dayjs().toDate();
const endDate = dayjs().add(supportPlan.duration, "day").toDate();
const userSupportPlan = queryRunner.manager.create(this.userSupportPlanRepo.target, { user, supportPlan, startDate, endDate });
await queryRunner.manager.save(this.userSupportPlanRepo.target, userSupportPlan);
const invoiceDueDate = dayjs(userSupportPlan.startDate).add(INVOICE.DUEDATE, "day").toDate();
const invoice = await this.invoicesService.createInvoiceForSupportPlan(
user,
supportPlan,
userSupportPlan,
invoiceDueDate,
queryRunner,
);
userSupportPlan.status = UserSupportPlanStatus.INACTIVE;
await queryRunner.manager.save(this.userSupportPlanRepo.target, userSupportPlan);
await queryRunner.commitTransaction();
return {
message: SupportPlanMessage.SUPPORT_PLAN_SUBSCRIBED,
invoice,
};
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
}
}