chore: update referral logic
This commit is contained in:
@@ -3,13 +3,11 @@ import { randomBytes } from "node:crypto";
|
||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
import Decimal from "decimal.js";
|
||||
import { DataSource, QueryRunner } from "typeorm";
|
||||
import { QueryRunner } from "typeorm";
|
||||
|
||||
import { ReferralMessage, UserMessage } from "../../../common/enums/message.enum";
|
||||
import { User } from "../../users/entities/user.entity";
|
||||
import { WalletsService } from "../../wallets/providers/wallets.service";
|
||||
import { UseReferralCodeDto } from "../DTO/use-referral-code.dto";
|
||||
import { ReferralRewardStatus } from "../enums/referral-reward-status.enum";
|
||||
import { ReferralStatus } from "../enums/referral-status.enum";
|
||||
import { ReferralCodesRepository } from "../repositories/referral-codes.repository";
|
||||
import { ReferralRewardsRepository } from "../repositories/referral-rewards.repository";
|
||||
@@ -20,8 +18,6 @@ export class ReferralsService {
|
||||
private readonly referralsRepository: ReferralsRepository,
|
||||
private readonly referralCodesRepository: ReferralCodesRepository,
|
||||
private readonly referralRewardsRepository: ReferralRewardsRepository,
|
||||
private readonly walletsService: WalletsService,
|
||||
private readonly dataSource: DataSource,
|
||||
) {}
|
||||
|
||||
async generateReferralCode(userId: string, queryRunner: QueryRunner) {
|
||||
@@ -54,75 +50,76 @@ export class ReferralsService {
|
||||
}
|
||||
|
||||
//*********************************** */
|
||||
async useReferralCode(dto: UseReferralCodeDto) {
|
||||
const queryRunner = this.dataSource.createQueryRunner();
|
||||
async useReferralCode(dto: UseReferralCodeDto, queryRunner: QueryRunner) {
|
||||
const referredUser = await queryRunner.manager.findOne(User, { where: { id: dto.userId } });
|
||||
if (!referredUser) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||
|
||||
try {
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
const referralCode = await queryRunner.manager.findOne(this.referralCodesRepository.target, {
|
||||
where: { code: dto.referralCode, isActive: true },
|
||||
relations: { user: true },
|
||||
});
|
||||
if (!referralCode || !referralCode.user) throw new BadRequestException(ReferralMessage.INVALID_OR_INACTIVE_REFERRAL_CODE);
|
||||
|
||||
const referredUser = await queryRunner.manager.findOne(User, { where: { id: dto.userId } });
|
||||
if (!referredUser) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||
const existingReferral = await queryRunner.manager.findOne(this.referralsRepository.target, {
|
||||
where: { referredUser: { id: referredUser.id } },
|
||||
});
|
||||
if (existingReferral) throw new BadRequestException(ReferralMessage.USER_ALREADY_REFERRED);
|
||||
|
||||
const referralCode = await queryRunner.manager.findOne(this.referralCodesRepository.target, {
|
||||
where: { code: dto.referralCode, isActive: true },
|
||||
relations: { user: true },
|
||||
});
|
||||
if (!referralCode || !referralCode.user) throw new BadRequestException(ReferralMessage.INVALID_OR_INACTIVE_REFERRAL_CODE);
|
||||
const referral = queryRunner.manager.create(this.referralsRepository.target, {
|
||||
referrer: { id: referralCode.user.id },
|
||||
referredUser: { id: referredUser.id },
|
||||
referralCode: { id: referralCode.id },
|
||||
});
|
||||
|
||||
// Check if user has already been referred
|
||||
const existingReferral = await queryRunner.manager.findOne(this.referralsRepository.target, {
|
||||
where: { referredUser: { id: referredUser.id } },
|
||||
});
|
||||
if (existingReferral) throw new BadRequestException(ReferralMessage.USER_ALREADY_REFERRED);
|
||||
await queryRunner.manager.save(referral);
|
||||
|
||||
// Create referral record
|
||||
const referral = queryRunner.manager.create(this.referralsRepository.target, {
|
||||
referrer: { id: referralCode.user.id },
|
||||
referredUser: { id: referredUser.id },
|
||||
referralCode: { id: referralCode.id },
|
||||
status: ReferralStatus.PENDING,
|
||||
});
|
||||
referralCode.usedCount += 1;
|
||||
await queryRunner.manager.save(referralCode);
|
||||
|
||||
await queryRunner.manager.save(referral);
|
||||
// const reward = queryRunner.manager.create(this.referralRewardsRepository.target, {
|
||||
// user: { id: referralCode.user.id },
|
||||
// referral: { id: referral.id },
|
||||
// });
|
||||
|
||||
// Increment usedCount
|
||||
referralCode.usedCount += 1;
|
||||
await queryRunner.manager.save(referralCode);
|
||||
// await queryRunner.manager.save(reward);
|
||||
|
||||
// Create pending reward
|
||||
const reward = queryRunner.manager.create(this.referralRewardsRepository.target, {
|
||||
user: { id: referralCode.user.id },
|
||||
referral: { id: referral.id },
|
||||
amount: 100, // Set your reward amount here
|
||||
status: ReferralRewardStatus.PENDING,
|
||||
});
|
||||
|
||||
await queryRunner.manager.save(reward);
|
||||
|
||||
// Charge the referred user's wallet
|
||||
const chargeAmount = new Decimal(100);
|
||||
await this.walletsService.createReferralRewardTransaction(referredUser.id, chargeAmount, queryRunner);
|
||||
|
||||
// Update referral status to COMPLETED
|
||||
referral.status = ReferralStatus.COMPLETED;
|
||||
await queryRunner.manager.save(referral);
|
||||
|
||||
// Update reward status to PAID
|
||||
reward.status = ReferralRewardStatus.PAID;
|
||||
reward.paidAt = new Date();
|
||||
await queryRunner.manager.save(reward);
|
||||
|
||||
await queryRunner.commitTransaction();
|
||||
return { referral, reward };
|
||||
} catch (error) {
|
||||
await queryRunner.rollbackTransaction();
|
||||
throw error;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
return referral;
|
||||
}
|
||||
|
||||
//*********************************** */
|
||||
async getPendingReferral(userId: string, queryRunner: QueryRunner) {
|
||||
return queryRunner.manager.findOne(this.referralsRepository.target, {
|
||||
where: {
|
||||
referredUser: { id: userId },
|
||||
status: ReferralStatus.PENDING,
|
||||
},
|
||||
relations: { referrer: true },
|
||||
});
|
||||
}
|
||||
//*********************************** */
|
||||
|
||||
async createReferral(userId: string, queryRunner: QueryRunner) {
|
||||
const referral = queryRunner.manager.create(this.referralsRepository.target, {
|
||||
referrer: { id: userId },
|
||||
referredUser: { id: userId },
|
||||
});
|
||||
await queryRunner.manager.save(referral);
|
||||
}
|
||||
|
||||
//*********************************** */
|
||||
|
||||
async createReferralReward(userId: string, referralId: string, amount: Decimal, queryRunner: QueryRunner) {
|
||||
const reward = queryRunner.manager.create(this.referralRewardsRepository.target, {
|
||||
user: { id: userId },
|
||||
referral: { id: referralId },
|
||||
amount,
|
||||
});
|
||||
await queryRunner.manager.save(reward);
|
||||
|
||||
return reward;
|
||||
}
|
||||
|
||||
//*********************************** */
|
||||
private generateRandomCode(): string {
|
||||
return randomBytes(6).toString("hex");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user