95 lines
2.9 KiB
TypeScript
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.");
|
|
}
|
|
}
|
|
}
|