File

apps/recallassess/recallassess-api/src/api/client/promo-code/promo-code.service.ts

Index

Methods

Constructor

constructor(prisma: BNestPrismaService)
Parameters :
Name Type Optional
prisma BNestPrismaService No

Methods

calculateDiscount
calculateDiscount(originalAmount: number, discountPercentage: number)

Calculate discount amount based on promo code and original amount

Parameters :
Name Type Optional
originalAmount number No
discountPercentage number No
Returns : number
Async getPromoCodeDetails
getPromoCodeDetails(code: string)

Get detailed info about a valid promo code (Only returns data if code is valid)

Parameters :
Name Type Optional
code string No
Async incrementUsage
incrementUsage(code: string)

Increment usage count when a promo code is applied This should be called after a successful purchase/subscription

Parameters :
Name Type Optional
code string No
Returns : Promise<void>
Async validatePromoCode
validatePromoCode(code: string)

Validate a promo code Checks if code exists, is active, not expired, and not sold out

Parameters :
Name Type Optional
code string No
import { bnestPlainToDto } from "@bish-nest/core";
import { BNestPrismaService } from "@bish-nest/core/services/database/prisma/prisma.service";
import { Injectable } from "@nestjs/common";
import { PromoCodeValidationDto, ValidPromoCodeDto } from "./dto";

@Injectable()
export class CLPromoCodeService {
  constructor(private readonly prisma: BNestPrismaService) {}

  /**
   * Validate a promo code
   * Checks if code exists, is active, not expired, and not sold out
   */
  async validatePromoCode(code: string): Promise<PromoCodeValidationDto> {
    const promoCode = await this.prisma.client.promoCode.findUnique({
      where: { promo_code: code.toUpperCase() },
    });

    // Code doesn't exist
    if (!promoCode) {
      return bnestPlainToDto(
        {
          is_valid: false,
          message: "Promo code not found",
          error_code: "NOT_FOUND",
        },
        PromoCodeValidationDto,
      );
    }

    // Code is inactive
    if (!promoCode.is_active) {
      return bnestPlainToDto(
        {
          is_valid: false,
          promo_code: promoCode.promo_code,
          message: "This promo code is no longer active",
          error_code: "INACTIVE",
        },
        PromoCodeValidationDto,
      );
    }

    const now = new Date();

    // Code hasn't started yet
    if (promoCode.valid_from && new Date(promoCode.valid_from) > now) {
      return bnestPlainToDto(
        {
          is_valid: false,
          promo_code: promoCode.promo_code,
          message: "This promo code is not yet valid",
          error_code: "NOT_STARTED",
        },
        PromoCodeValidationDto,
      );
    }

    // Code has expired
    if (promoCode.valid_until && new Date(promoCode.valid_until) < now) {
      return bnestPlainToDto(
        {
          is_valid: false,
          promo_code: promoCode.promo_code,
          message: "This promo code has expired",
          error_code: "EXPIRED",
        },
        PromoCodeValidationDto,
      );
    }

    // Code usage limit reached (sold out)
    if (promoCode.usage_limit && promoCode.usage_count >= promoCode.usage_limit) {
      return bnestPlainToDto(
        {
          is_valid: false,
          promo_code: promoCode.promo_code,
          message: "This promo code has reached its usage limit",
          error_code: "SOLD_OUT",
        },
        PromoCodeValidationDto,
      );
    }

    // Code is valid!
    return bnestPlainToDto(
      {
        is_valid: true,
        promo_code: promoCode.promo_code,
        discount_percentage: Number(promoCode.discount_percentage),
        message: "Promo code is valid",
      },
      PromoCodeValidationDto,
    );
  }

  /**
   * Get detailed info about a valid promo code
   * (Only returns data if code is valid)
   */
  async getPromoCodeDetails(code: string): Promise<ValidPromoCodeDto | null> {
    const validation = await this.validatePromoCode(code);

    if (!validation.is_valid) {
      return null;
    }

    const promoCode = await this.prisma.client.promoCode.findUnique({
      where: { promo_code: code.toUpperCase() },
    });

    if (!promoCode) {
      return null;
    }

    const remaining_uses = promoCode.usage_limit
      ? Math.max(0, promoCode.usage_limit - promoCode.usage_count)
      : null;

    return bnestPlainToDto(
      {
        promo_code: promoCode.promo_code,
        title: promoCode.title,
        discount_percentage: Number(promoCode.discount_percentage),
        valid_until: promoCode.valid_until,
        remaining_uses,
      },
      ValidPromoCodeDto,
    );
  }

  /**
   * Increment usage count when a promo code is applied
   * This should be called after a successful purchase/subscription
   */
  async incrementUsage(code: string): Promise<void> {
    await this.prisma.client.promoCode.update({
      where: { promo_code: code.toUpperCase() },
      data: {
        usage_count: {
          increment: 1,
        },
      },
    });
  }

  /**
   * Calculate discount amount based on promo code and original amount
   */
  calculateDiscount(originalAmount: number, discountPercentage: number): number {
    return (originalAmount * discountPercentage) / 100;
  }
}

results matching ""

    No results matching ""