withdraw request
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { IsNotEmpty, IsString, Length } from "class-validator";
|
||||
|
||||
|
||||
export class ConfirmwithdrawRequestDto {
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
@Length(2, 50,)
|
||||
@ApiProperty({ description: "name", example: "mahyar" })
|
||||
transactionId: string;
|
||||
|
||||
}
|
||||
@@ -1,20 +1,24 @@
|
||||
import Decimal from "decimal.js";
|
||||
import { Column, Entity, ManyToOne } from "typeorm";
|
||||
import { Column, Entity, ManyToOne, OneToMany } from "typeorm";
|
||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||
import { DecimalTransformer } from "../../../common/transformers/decimal.transformer";
|
||||
import { User } from "../../users/entities/user.entity";
|
||||
import { WalletTransaction } from "../../wallets/entities/transaction.entity";
|
||||
|
||||
@Entity()
|
||||
export class RewardWithdrawRequest extends BaseEntity {
|
||||
@ManyToOne(() => User, (user) => user.referralRewards)
|
||||
user: User;
|
||||
|
||||
@Column({ type: "decimal", precision: 10, scale: 2, nullable: true, transformer: new DecimalTransformer() })
|
||||
requestedAmount?: Decimal;
|
||||
@Column({ type: "decimal", precision: 10, scale: 2, transformer: new DecimalTransformer() })
|
||||
requestedAmount: Decimal;
|
||||
|
||||
@Column({ type: "timestamp", nullable: true })
|
||||
paidAt: Date;
|
||||
|
||||
@Column({ type: "varchar", length: 255, nullable: true })
|
||||
transactionId?: string;
|
||||
|
||||
@OneToMany(() => WalletTransaction, (walletTransaction) => walletTransaction.withdrawRequest)
|
||||
transactions: WalletTransaction[]
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Controller, Get, Post, Body, Delete, Param, Query } from '@nestjs/common';
|
||||
import { Controller, Get, Post, Body, Delete, Param, Query, Patch } from '@nestjs/common';
|
||||
import { ResellerService } from './reseller.service';
|
||||
import { ApiOperation } from '@nestjs/swagger';
|
||||
import { PermissionsDec } from '../../common/decorators/permission.decorator';
|
||||
@@ -17,6 +17,7 @@ import { WalletsService } from '../wallets/providers/wallets.service';
|
||||
import { CreateWithdrawRequestDto } from './dto/create-withdraw-request.dto';
|
||||
import { CreateUserBankAccountDto } from './dto/create-user-bank-account.dto';
|
||||
import { ResellerType } from '../auth/DTO/verify-reseller-otp.dto';
|
||||
import { ConfirmwithdrawRequestDto } from './dto/confirm-withdraw-request.dto';
|
||||
|
||||
@Controller('reseller')
|
||||
@AuthGuards()
|
||||
@@ -45,12 +46,20 @@ export class ResellerController {
|
||||
|
||||
//=========== Reward Requests =========
|
||||
|
||||
@ApiOperation({ summary: "get reseller reward requests ==> admin route" })
|
||||
@ApiOperation({ summary: "get withdraw requests ==> admin route" })
|
||||
@AdminRoute()
|
||||
@PermissionsDec(PermissionEnum.RESELLER)
|
||||
@Get('reward/request')
|
||||
getRewardRequests() {
|
||||
return this.resellerService.findAll()
|
||||
@Get('withdraw-request/admin')
|
||||
getRewardRequests(@Query() query: SearchWithdrawRequestQueryDto) {
|
||||
return this.resellerService.getwithdrawRequestsForAdmin(query)
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "get withdraw requests ==> admin route" })
|
||||
@AdminRoute()
|
||||
@PermissionsDec(PermissionEnum.RESELLER)
|
||||
@Patch('withdraw-request/:id')
|
||||
confirmWithdrawRequests(@Param('id') requestId: string, @Body() dto: ConfirmwithdrawRequestDto) {
|
||||
return this.resellerService.confirmWithdrawRequest(requestId, dto.transactionId)
|
||||
}
|
||||
|
||||
// ************** Reseller Panel Endpoints ***********
|
||||
@@ -148,7 +157,7 @@ export class ResellerController {
|
||||
@ResellerRoute([ResellerType.agent, ResellerType.reseller])
|
||||
@Get('withdraw-request')
|
||||
getPayments(@UserDec("id") userId: string, @Body() dto: SearchWithdrawRequestQueryDto) {
|
||||
return this.resellerService.getRewrdsRequests(userId, dto)
|
||||
return this.resellerService.getWithdrawRequests(userId, dto)
|
||||
}
|
||||
|
||||
// ============ Create Bank Account =============
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { BadRequestException, Injectable, Logger, NotFoundException } from '@nestjs/common';
|
||||
import { UsersService } from '../users/providers/users.service';
|
||||
import { CreateResellerDto } from './dto/create-reseller.dto';
|
||||
import { ResellerRepository } from './repositories/reseller.repository';
|
||||
@@ -15,10 +15,12 @@ import { ResellerType } from '../auth/DTO/verify-reseller-otp.dto';
|
||||
import { PaginationDto } from '../../common/DTO/pagination.dto';
|
||||
import { WalletsService } from '../wallets/providers/wallets.service';
|
||||
import Decimal from 'decimal.js';
|
||||
import { IsNull } from 'typeorm';
|
||||
import { DataSource, IsNull } from 'typeorm';
|
||||
|
||||
@Injectable()
|
||||
export class ResellerService {
|
||||
protected readonly logger = new Logger(ResellerService.name);
|
||||
|
||||
constructor(
|
||||
private readonly usersService: UsersService,
|
||||
private readonly referralService: ReferralsService,
|
||||
@@ -27,6 +29,7 @@ export class ResellerService {
|
||||
private readonly withdrawRequestRepository: WithdrawRequestRepository,
|
||||
private readonly userBankAccountRepository: UserBankAccountRepository,
|
||||
private readonly walletsService: WalletsService,
|
||||
private readonly dataSource: DataSource,
|
||||
) { }
|
||||
|
||||
async create(dto: CreateResellerDto) {
|
||||
@@ -111,6 +114,7 @@ export class ResellerService {
|
||||
|
||||
return this.referralService.findPaginatedReferedUsers(agentIds, query)
|
||||
}
|
||||
|
||||
// *************** Invoice ***************
|
||||
async findInvoices(userId: string, type: ResellerType, query: SearchResellerInvoicesQueryDto) {
|
||||
if (type == ResellerType.agent) {
|
||||
@@ -167,14 +171,14 @@ export class ResellerService {
|
||||
}
|
||||
|
||||
//************* withdraw request ***********/
|
||||
async getRewrdsRequestsForAdmin(queryDto: SearchWithdrawRequestQueryDto) {
|
||||
async getwithdrawRequestsForAdmin(queryDto: SearchWithdrawRequestQueryDto) {
|
||||
|
||||
const [requests, count] = await this.withdrawRequestRepository.findPaginatedListForAdmin(queryDto);
|
||||
|
||||
return { requests, count, paginate: true };
|
||||
}
|
||||
|
||||
async getRewrdsRequests(userId: string, queryDto: SearchWithdrawRequestQueryDto) {
|
||||
async getWithdrawRequests(userId: string, queryDto: SearchWithdrawRequestQueryDto) {
|
||||
|
||||
const [requests, count] = await this.withdrawRequestRepository.findPaginatedList(userId, queryDto);
|
||||
|
||||
@@ -197,7 +201,7 @@ export class ResellerService {
|
||||
if (pendingWithdrawRequest) {
|
||||
throw new BadRequestException("امکان ایجاد درخواست برداشت جدید نیست")
|
||||
}
|
||||
|
||||
|
||||
const { balance } = await this.walletsService.getBalance(userId)
|
||||
|
||||
if (new Decimal(balance).lessThan(requestedAmount)) {
|
||||
@@ -230,6 +234,44 @@ export class ResellerService {
|
||||
return this.withdrawRequestRepository.remove(request)
|
||||
}
|
||||
|
||||
async confirmWithdrawRequest(requestId: string,transactionId:string) {
|
||||
const request = await this.withdrawRequestRepository.findOne({ where: { id: requestId }, relations: ['user'] })
|
||||
if (!request) {
|
||||
throw new BadRequestException("درخواست برداشت یافت نشد .")
|
||||
}
|
||||
|
||||
if (request.paidAt) {
|
||||
throw new BadRequestException("قبلا تایید شده است")
|
||||
}
|
||||
|
||||
this.logger.log(`confirm withdraw request for request id ${requestId} `);
|
||||
|
||||
const queryRunner = this.dataSource.createQueryRunner();
|
||||
|
||||
try {
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
|
||||
const amount = new Decimal(request.requestedAmount)
|
||||
|
||||
await this.walletsService.createWithdrawTransaction(request.user.id, amount, request, queryRunner)
|
||||
|
||||
request.paidAt = new Date()
|
||||
request.transactionId = transactionId
|
||||
|
||||
await queryRunner.manager.save(request)
|
||||
|
||||
await queryRunner.commitTransaction();
|
||||
return true;
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to send announcement:`, error);
|
||||
await queryRunner.rollbackTransaction();
|
||||
throw error;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
}
|
||||
|
||||
//********* Bank Account ***********/
|
||||
async getUserBankAccount(userId: string) {
|
||||
|
||||
@@ -242,6 +284,16 @@ export class ResellerService {
|
||||
async createUserBankAccount(userId: string, dto: CreateUserBankAccountDto) {
|
||||
const { user } = await this.usersService.findOneById(userId)
|
||||
|
||||
const exitingBankAccount = await this.userBankAccountRepository.findOne({
|
||||
where: {
|
||||
IBan: dto.IBan
|
||||
}
|
||||
})
|
||||
|
||||
if (exitingBankAccount) {
|
||||
throw new BadRequestException("شماره شبا موجود می باشد .")
|
||||
}
|
||||
|
||||
const account = this.userBankAccountRepository.create({
|
||||
user,
|
||||
...dto
|
||||
|
||||
Reference in New Issue
Block a user