update: add new field for subscription of user when purchased

This commit is contained in:
mahyargdz
2025-02-28 12:08:46 +03:30
parent 93c5ad49d3
commit 76feef7645
29 changed files with 220 additions and 302 deletions
@@ -225,11 +225,13 @@ export class SubscriptionsService {
if (!plan) throw new BadRequestException(SubscriptionMessage.NOT_FOUND);
const startDate = new Date();
const endDate = new Date();
endDate.setDate(startDate.getDate() + plan.duration);
const startDate = dayjs().toDate();
const endDate = dayjs().add(plan.duration, "day").toDate();
// const startDate = new Date();
// const endDate = new Date();
// endDate.setDate(startDate.getDate() + plan.duration);
//
const userSubscription = queryRunner.manager.create(UserSubscription, { user, plan, startDate, endDate });
const userSubscription = queryRunner.manager.create(UserSubscription, { ...subscribeDto, user, plan, startDate, endDate });
await queryRunner.manager.save(UserSubscription, userSubscription);
@@ -237,18 +239,16 @@ export class SubscriptionsService {
let finalPrice = new Decimal(plan.price);
if (plan.discounts && plan.discounts.length > 0) {
plan.discounts.forEach((discount) => {
if (discount.isActive && new Date() >= discount.startDate && new Date() <= discount.endDate) {
if (discount.calculationType === DiscountCalculationType.PERCENTAGE) {
const discountAmount = finalPrice.mul(discount.amount).div(100);
finalPrice = finalPrice.sub(discountAmount);
} else if (discount.calculationType === DiscountCalculationType.FIXED) {
finalPrice = finalPrice.sub(discount.amount);
}
}
});
}
const activeDiscounts =
plan.discounts?.filter((discount) => discount.isActive && new Date() >= discount.startDate && new Date() <= discount.endDate) || [];
activeDiscounts.forEach((discount) => {
if (discount.calculationType === DiscountCalculationType.PERCENTAGE) {
finalPrice = finalPrice.sub(finalPrice.mul(discount.amount).div(100));
} else if (discount.calculationType === DiscountCalculationType.FIXED) {
finalPrice = finalPrice.sub(discount.amount);
}
});
plan.price = finalPrice;
@@ -264,8 +264,7 @@ export class SubscriptionsService {
await this.walletsService.createSubscriptionTransaction(finalPrice, userWallet.id, queryRunner);
//TODO: need queue handling for notification
const invoiceDueDate = new Date(userSubscription.endDate);
invoiceDueDate.setDate(userSubscription.endDate.getDate() - 3);
const invoiceDueDate = dayjs(userSubscription.endDate).subtract(3, "day").toDate();
const invoice = await this.invoicesService.createInvoiceForSubscription(userId, plan, invoiceDueDate, queryRunner);
userSubscription.status = SubscriptionStatus.ACTIVE;
@@ -419,19 +418,4 @@ export class SubscriptionsService {
const growthRate = ((currentYearCount - lastYearCount) / lastYearCount) * 100;
return Math.round(growthRate * 100) / 100;
}
/********************************* */
async activeUserSubscription(userId: string, serviceId: string) {
const activeSubscription = await this.userSubscriptionsRepository.findOne({
where: {
user: { id: userId },
plan: { service: { id: serviceId } },
status: SubscriptionStatus.ACTIVE,
},
relations: ["plan", "plan.service"],
});
console.log(activeSubscription);
return activeSubscription;
}
}
@@ -1,8 +1,7 @@
import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common";
import { SubscriptionsService } from "./subscriptions.service";
import { CommonMessage, ServiceMessage, UserMessage, UserQuickAccessMessage } from "../../../common/enums/message.enum";
import { DanakServicesService } from "../../danak-services/providers/danak-services.service";
import { CommonMessage, UserMessage, UserQuickAccessMessage } from "../../../common/enums/message.enum";
import { UsersService } from "../../users/providers/users.service";
import { UserQuickAccessRepository } from "../repositories/users-quick-access.repository";
@@ -11,32 +10,25 @@ export class UserQuickAccessService {
constructor(
private readonly quickAccessRepository: UserQuickAccessRepository,
private readonly usersService: UsersService,
private readonly danakServicesService: DanakServicesService,
private readonly subscriptionService: SubscriptionsService,
) {}
async addQuickAccess(userId: string, serviceId: string) {
async addQuickAccess(userId: string, userSubId: string) {
const { user } = await this.usersService.findOneById(userId);
if (!user) throw new NotFoundException(UserMessage.USER_NOT_FOUND);
const service = await this.danakServicesService.findServiceById(serviceId);
if (!service) throw new NotFoundException(ServiceMessage.SERVICE_NOT_EXIST);
const activeSubscription = await this.subscriptionService.activeUserSubscription(user.id, service.id);
if (!activeSubscription) {
throw new BadRequestException(UserQuickAccessMessage.USER_SUBS_NOT_FOUND);
}
const { userSubscription } = await this.subscriptionService.getUserSubscriptionById(userSubId, user.id);
const userQuickAccesses = await this.quickAccessRepository.count({ where: { user: { id: userId }, isActive: true } });
if (userQuickAccesses >= 4) {
throw new BadRequestException(UserQuickAccessMessage.QUICK_ACCESS_LIMIT_REACHED);
}
if (userQuickAccesses >= 4) throw new BadRequestException(UserQuickAccessMessage.QUICK_ACCESS_LIMIT_REACHED);
const existQuickAccess = await this.quickAccessRepository.findOne({
where: { user: { id: user.id }, userSubscription: { id: userSubId } },
});
const existQuickAccess = await this.quickAccessRepository.findOne({ where: { user: { id: user.id }, service: { id: service.id } } });
console.log(existQuickAccess);
if (existQuickAccess) throw new BadRequestException(UserQuickAccessMessage.QUICK_ACCESS_EXIST);
const quickAccess = this.quickAccessRepository.create({ user, service });
const quickAccess = this.quickAccessRepository.create({ user, userSubscription, service: userSubscription.plan.service });
await this.quickAccessRepository.save(quickAccess);
@@ -45,18 +37,22 @@ export class UserQuickAccessService {
quickAccess,
};
}
async removeQuickAccess(userId: string, serviceId: string) {
await this.quickAccessRepository.delete({ user: { id: userId }, service: { id: serviceId } });
//************************************** */
async removeQuickAccess(userId: string, userSubId: string) {
await this.quickAccessRepository.delete({ user: { id: userId }, userSubscription: { id: userSubId } });
return {
message: CommonMessage.DELETED,
};
}
//************************************** */
async getUserQuickAccess(userId: string) {
const quickAccesses = await this.quickAccessRepository.find({
where: { user: { id: userId }, isActive: true },
relations: ["service"],
relations: {
userSubscription: true,
service: true,
},
});
return { quickAccesses };
}