Files
dsc-api/src/modules/dmenu/providers/premium.service.ts
T
2025-12-27 13:04:35 +03:30

95 lines
2.9 KiB
TypeScript

import { BadRequestException, Injectable } from "@nestjs/common";
import dayjs from "dayjs";
import Decimal from "decimal.js";
import { SubscriptionMessage } from "../../../common/enums/message.enum";
import { InvoicesService } from "../../invoices/providers/invoices.service";
import { UserSubscription } from "../../subscriptions/entities/user-subscription.entity";
import { UserSubscriptionsRepository } from "../../subscriptions/repositories/user-subscriptions.repository";
import { BuyPremiumPlanDto } from "../DTO/buy-premium-plan.dto";
@Injectable()
export class PremiumService {
constructor(
private readonly userSubscriptionsRepository: UserSubscriptionsRepository,
private readonly invoicesService: InvoicesService,
) {}
async buyPremiumPlan(dto: BuyPremiumPlanDto, userId: string) {
// Find the user's current subscription
const userSubscription = await this.userSubscriptionsRepository.findOne({
where: { id: dto.userSubscriptionId, user: { id: userId } },
relations: {
user: true,
plan: { service: true },
},
});
if (!userSubscription) {
throw new BadRequestException(SubscriptionMessage.NOT_FOUND);
}
// Calculate remaining days
const remainingDays = this.calculateRemainingDays(userSubscription);
// Extract duration from current plan and convert to months
const planDurationInMonths = Math.round(userSubscription.plan.duration / 30);
// Get premium pricing based on extracted duration
const premiumPrice = this.getPremiumPrice(planDurationInMonths);
// Create invoice items for premium purchase
const invoiceItems = [{
name: `Premium Plan - ${planDurationInMonths} Months`,
count: 1,
unitPrice: premiumPrice.toNumber(),
discount: 0,
}];
// Create invoice directly
const createInvoiceDto = {
userId: userSubscription.user.id,
items: invoiceItems,
isRecurring: false,
};
const invoice = await this.invoicesService.createInvoiceAdmin(createInvoiceDto, {
ip: '',
headers: {},
userId: userSubscription.user.id
});
return {
message: "Premium plan purchased successfully",
userSubscription,
invoice,
remainingDays,
premiumPrice: premiumPrice.toNumber(),
};
}
//************************************ */
private calculateRemainingDays(userSubscription: UserSubscription): number {
const now = dayjs();
const endDate = dayjs(userSubscription.endDate);
if (endDate.isBefore(now)) {
return 0;
}
return endDate.diff(now, 'day');
}
//************************************ */
private getPremiumPrice(durationInMonths: number): Decimal {
switch (durationInMonths) {
case 6:
return new Decimal(5000000);
case 12:
return new Decimal(10000000);
default:
throw new BadRequestException("Invalid premium plan duration. Only 6 and 12 month plans are supported.");
}
}
}