update: the danak services module and add new route to fetch the danak service

This commit is contained in:
mahyargdz
2025-04-16 15:28:45 +03:30
parent fb8f16deb4
commit 999ce9cee2
30 changed files with 713 additions and 465 deletions
+142 -130
View File
@@ -1,182 +1,194 @@
// import { randomBytes } from "node:crypto";
// import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common";
// import { In } from "typeorm";
// // eslint-disable-next-line import/no-named-as-default
// import Decimal from "decimal.js";
// import { CommonMessage, DiscountMessage, SubscriptionMessage, UserMessage } from "../../../common/enums/message.enum";
// import { SubscriptionsPlanRepository } from "../../subscriptions/repositories/subscriptions.repository";
// import { UserRepository } from "../../users/repositories/users.repository";
// import { PaginationUtils } from "../../utils/providers/pagination.utils";
// import { User } from "../../users/entities/user.entity";
// import { CreateDiscountDto } from "../DTO/create-discount.dto";
// import { SearchDiscountsDto } from "../DTO/discount-search-query.dto";
// import { DiscountRepository } from "../repositories/discount.repository";
// import { UpdateDiscountDto } from "../DTO/update-discount.dto";
// import { Discount } from "../entities/discount.entity";
// import { DiscountType } from "../enums/discount-type.enum";
// import { DiscountServicesRepository } from "../repositories/discount-services.repository";
// import { DiscountRepository } from "../repositories/discounts.repository";
// import { UsageDiscountRepository } from "../repositories/usage-discounts.repository";
// @Injectable()
// export class DiscountService {
// export class DiscountsService {
// constructor(
// private readonly discountRepository: DiscountRepository,
// private readonly subscriptionPlanRepository: SubscriptionsPlanRepository,
// private readonly userRepository: UserRepository,
// private readonly discountServicesRepository: DiscountServicesRepository,
// private readonly usageDiscountRepository: UsageDiscountRepository,
// ) {}
// /******************************************** */
// async create(createDiscountDto: CreateDiscountDto) {
// const { subscriptionPlanIds, ...discountData } = createDiscountDto;
// const existingDiscount = await this.discountRepository.findByCode(createDiscountDto.title);
// if (existingDiscount) {
// throw new BadRequestException(DISCOUNT_ERROR_MESSAGES.ALREADY_EXISTS);
// }
// const code = await this.generateUniqueCouponCode();
// // Create the discount without product relations
// const { targetProducts, ...discountData } = createDiscountDto;
// const discount = this.discountRepository.create({
// const discount = await this.discountRepository.create({
// ...discountData,
// code,
// startDate: new Date(createDiscountDto.startDate),
// endDate: new Date(createDiscountDto.endDate),
// status: createDiscountDto.status || DiscountStatus.ACTIVE,
// isActive: createDiscountDto.isActive !== undefined ? createDiscountDto.isActive : true,
// });
// if (createDiscountDto.subscriptionPlanIds && createDiscountDto.subscriptionPlanIds.length) {
// const subscriptionPlans = await this.subscriptionPlanRepository.find({
// where: { id: In(createDiscountDto.subscriptionPlanIds) },
// });
// if (subscriptionPlans.length !== createDiscountDto.subscriptionPlanIds.length) {
// throw new NotFoundException(SubscriptionMessage.NOT_FOUND);
// }
// discount.subscriptionPlans = subscriptionPlans;
// // Add product relations if provided
// if (targetProducts && targetProducts.length > 0) {
// await this.discountServicesRepository.createMany(discount.id, targetProducts);
// }
// if (createDiscountDto.userIds) {
// const users = await this.userRepository.find({ where: { id: In(createDiscountDto.userIds) } });
// if (users.length !== createDiscountDto.userIds.length) {
// throw new NotFoundException(UserMessage.USER_NOT_FOUND);
// }
// discount.users = users;
// // Fetch the complete discount with relations
// const fullDiscount = await this.discountRepository.findById(discount.id);
// if (!fullDiscount) {
// throw new NotFoundException(DISCOUNT_ERROR_MESSAGES.NOT_FOUND);
// }
// await this.discountRepository.save(discount);
// return {
// message: CommonMessage.CREATED,
// discount,
// };
// return fullDiscount;
// }
// /******************************************** */
// async findAll(options?: any): Promise<[Discount[], number]> {
// return this.discountRepository.findAll(options);
// }
// async findByCode(code: string) {
// const discount = await this.discountRepository.findOne({
// where: { code, isActive: true },
// relations: ["subscriptionPlans"],
// });
// async findById(id: string): Promise<Discount> {
// const discount = await this.discountRepository.findById(id);
// if (!discount) {
// throw new NotFoundException(DiscountMessage.NOT_FOUND);
// throw new NotFoundException(DISCOUNT_ERROR_MESSAGES.NOT_FOUND);
// }
// return { discount };
// return discount;
// }
// /******************************************** */
// async update(id: string, updateDiscountDto: UpdateDiscountDto): Promise<Discount> {
// // Validate discount exists
// await this.findById(id);
// async findDiscountsByUser(queryDto: SearchDiscountsDto, userId: string) {
// const user = await this.userRepository.findOneBy({
// id: userId,
// });
// if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
// // Handle product relations separately
// const { targetProducts, startDate: startDateStr, endDate: endDateStr, ...otherFields } = updateDiscountDto;
// const { limit, skip } = PaginationUtils(queryDto);
// // Initialize update data with other fields
// const updateData: Partial<Discount> = { ...otherFields };
// const queryBuilder = this.discountRepository.createQueryBuilder("discount");
// queryBuilder
// .leftJoin("discount.users", "user")
// .where("user.id = :userId", { userId: user.id })
// .leftJoinAndSelect("discount.subscriptionPlans", "subscriptionPlans")
// .leftJoin("subscriptionPlans.service", "service")
// .addSelect(["service.id", "service.name", "service.title", "service.link", "service.icon", "service.description"]);
// if (queryDto.q) {
// queryBuilder.andWhere("discount.code ILIKE :q", { q: `%${queryDto.q}%` });
// // Add date fields if they exist
// if (startDateStr) {
// updateData.startDate = new Date(startDateStr);
// }
// queryBuilder.orderBy("discount.createdAt", "DESC").skip(skip).take(limit);
// const [discounts, count] = await queryBuilder.getManyAndCount();
// return {
// discounts,
// count,
// paginate: true,
// };
// }
// /******************************************** */
// async findAll(queryDto: SearchDiscountsDto) {
// const { limit, skip } = PaginationUtils(queryDto);
// const queryBuilder = this.discountRepository.createQueryBuilder("discount");
// queryBuilder
// .leftJoinAndSelect("discount.subscriptionPlans", "subscriptionPlans")
// .leftJoin("subscriptionPlans.service", "service")
// .addSelect(["service.id", "service.name", "service.title", "service.link", "service.icon", "service.description"])
// .leftJoinAndSelect("discount.users", "users");
// if (queryDto.q) {
// queryBuilder.andWhere("discount.code ILIKE :q", { q: `%${queryDto.q}%` });
// if (endDateStr) {
// updateData.endDate = new Date(endDateStr);
// }
// queryBuilder.orderBy("discount.createdAt", "DESC").skip(skip).take(limit);
// // Update the discount entity
// const updatedDiscount = await this.discountRepository.update(id, updateData);
// if (!updatedDiscount) {
// throw new NotFoundException(DISCOUNT_ERROR_MESSAGES.NOT_FOUND);
// }
// const [discounts, count] = await queryBuilder.getManyAndCount();
// // Handle product relations if provided
// if (targetProducts !== undefined) {
// // Remove existing relations
// await this.discountServicesRepository.deleteByDiscountId(id);
// return {
// discounts,
// count,
// paginate: true,
// };
// // Add new relations if not empty
// if (targetProducts.length > 0) {
// await this.discountServicesRepository.createMany(id, targetProducts);
// }
// }
// // Return the updated discount with relations
// return this.findById(id);
// }
// /******************************************** */
// async findOne(id: string) {
// const discount = await this.discountRepository.findOne({
// where: { id },
// relations: ["subscriptionPlans"],
// });
// if (!discount) throw new BadRequestException(DiscountMessage.NOT_FOUND);
// return { discount };
// async delete(id: string): Promise<void> {
// const discount = await this.findById(id);
// await this.discountRepository.delete(discount.id);
// }
// /******************************************** */
// async toggleActive(id: string, isActive: boolean): Promise<Discount> {
// await this.findById(id);
// const updatedDiscount = await this.discountRepository.update(id, { isActive });
// if (!updatedDiscount) {
// throw new NotFoundException(DISCOUNT_ERROR_MESSAGES.NOT_FOUND);
// }
// return updatedDiscount;
// }
// async validateDiscount(code: string, user: User, productId?: string): Promise<Discount> {
// const discount = await this.discountRepository.findValidByCode(code);
// async toggleActive(id: string) {
// const discount = await this.discountRepository.findOne({ where: { id } });
// if (!discount) {
// throw new BadRequestException(DiscountMessage.NOT_FOUND);
// throw new BadRequestException(DISCOUNT_ERROR_MESSAGES.INVALID);
// }
// discount.isActive = !discount.isActive;
// // Check if user has already used this discount
// const usageCount = await this.usageDiscountRepository.countByUserAndDiscount(user.id, discount.id);
// if (usageCount > 0) {
// throw new BadRequestException(DISCOUNT_ERROR_MESSAGES.ALREADY_USED);
// }
// const updatedDiscount = await this.discountRepository.save(discount);
// // Check if product is valid for this discount
// if (productId && discount.discountServices && discount.discountServices.length > 0) {
// const hasProduct = await this.discountServicesRepository.hasProductForDiscount(discount.id, productId);
// if (!hasProduct) {
// throw new BadRequestException(DISCOUNT_ERROR_MESSAGES.INVALID_PRODUCT);
// }
// }
// return {
// message: CommonMessage.UPDATE_SUCCESS,
// updatedDiscount,
// };
// return discount;
// }
// /******************************************** */
// async applyDiscount(amount: number, discountId: string, productId?: string): Promise<number> {
// const discount = await this.findById(discountId);
// async generateUniqueCouponCode(): Promise<string> {
// const code = this.generateCouponCode();
// const exists = await this.discountRepository.findOne({ where: { code } });
// if (exists) return this.generateUniqueCouponCode();
// return code;
// if (!discount.isValid) {
// throw new BadRequestException(DISCOUNT_ERROR_MESSAGES.INVALID);
// }
// // Check if product is valid for this discount
// if (productId && discount.discountServices && discount.discountServices.length > 0) {
// const hasProduct = await this.discountServicesRepository.hasProductForDiscount(discount.id, productId);
// if (!hasProduct) {
// throw new BadRequestException(DISCOUNT_ERROR_MESSAGES.INVALID_PRODUCT);
// }
// }
// let discountAmount = 0;
// if (discount.type === DiscountType.PERCENTAGE) {
// discountAmount = (amount * discount.value) / 100;
// } else if (discount.type === DiscountType.FIXED_AMOUNT) {
// discountAmount = discount.value;
// }
// // Ensure discount doesn't exceed the original amount
// if (discountAmount > amount) {
// discountAmount = amount;
// }
// return discountAmount;
// }
// /******************************************** */
// async recordDiscountUsage(userId: string, discountId: string, appliedAmount: number): Promise<void> {
// const discount = await this.findById(discountId);
// private generateCouponCode(length = 8) {
// return randomBytes(length).toString("hex").slice(0, length).toUpperCase();
// // Increment usage count
// await this.discountRepository.update(discount.id, {
// usedCount: discount.usedCount + 1,
// });
// // Record usage
// await this.usageDiscountRepository.create({
// user: { id: userId } as User,
// discount: { id: discountId } as Discount,
// appliedAmount: new Decimal(appliedAmount),
// usedAt: new Date(),
// });
// }
// async getProductsForDiscount(discountId: string): Promise<string[]> {
// const discountServices = await this.discountServicesRepository.findByDiscountId(discountId);
// return discountServices.map((service) => service.danakService.id);
// }
// }