chore: apply discount on plan

This commit is contained in:
Matin
2025-02-18 10:10:23 +03:30
parent 6014da7e73
commit ff96fd6c32
4 changed files with 66 additions and 25 deletions
@@ -5,6 +5,7 @@ import { DataSource, In } from "typeorm";
import { ServiceMessage, SubscriptionMessage, WalletMessage } from "../../../common/enums/message.enum";
import { DanakServicesService } from "../../danak-services/providers/danak-services.service";
import { DiscountCalculationType } from "../../discounts/enums/discount-type.enum";
import { InvoicesService } from "../../invoices/providers/invoices.service";
import { UsersService } from "../../users/providers/users.service";
import { PaginationUtils } from "../../utils/providers/pagination.utils";
@@ -146,6 +147,8 @@ export class SubscriptionsService {
.createQueryBuilder("subscription")
.leftJoin("subscription.service", "service")
.addSelect(["service.id"])
.leftJoin("subscription.discounts", "discount")
.addSelect(["discount.calculationType", "discount.amount", "discount.startDate", "discount.endDate", "discount.isActive"])
.where("service.id = :serviceId", { serviceId });
if (queryDto.q) {
@@ -158,9 +161,31 @@ export class SubscriptionsService {
const [subscriptions, count] = await queryBuilder.skip(skip).take(limit).getManyAndCount();
const transformedSubscriptions = subscriptions.map((subscription) => {
let price = new Decimal(subscription.price);
if (subscription.discounts && subscription.discounts.length > 0) {
subscription.discounts.forEach((discount) => {
if (discount.isActive && new Date() >= discount.startDate && new Date() <= discount.endDate) {
if (discount.calculationType === DiscountCalculationType.PERCENTAGE) {
const discountAmount = price.mul(discount.amount).div(100);
price = price.sub(discountAmount);
} else if (discount.calculationType === DiscountCalculationType.FIXED) {
price = price.sub(discount.amount);
}
}
});
}
return {
...subscription,
finalPrice: price.toNumber(),
};
});
return {
service,
subscriptions,
subscriptions: transformedSubscriptions,
count,
pagination: true,
};
@@ -193,6 +218,7 @@ export class SubscriptionsService {
where: { id: subscribeDto.planId, service: { id: serviceId } },
relations: {
service: true,
discounts: true,
},
});
@@ -208,15 +234,34 @@ export class SubscriptionsService {
const userWallet = await this.walletsService.getWalletByUserId(user.id, queryRunner);
if (userWallet.balance < plan.price) throw new BadRequestException(WalletMessage.INSUFFICIENT_BALANCE);
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);
}
}
});
}
plan.price = finalPrice;
if (new Decimal(userWallet.balance).lessThan(finalPrice)) throw new BadRequestException(WalletMessage.INSUFFICIENT_BALANCE);
// if (userWallet.balance < plan.price) throw new BadRequestException(WalletMessage.INSUFFICIENT_BALANCE);
//
userWallet.balance = new Decimal(userWallet.balance).sub(plan.price);
userWallet.balance = new Decimal(userWallet.balance).sub(finalPrice);
await queryRunner.manager.save(Wallet, userWallet);
//
await this.walletsService.createSubscriptionTransaction(plan.price, userWallet.id, queryRunner);
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);