bank account

This commit is contained in:
2026-04-15 10:42:16 +03:30
parent 6f1217f063
commit 2b44b3cb2f
9 changed files with 147 additions and 14 deletions
@@ -10,16 +10,14 @@ import { SearchRewardsRequestQueryDto } from "../../reseller/dto/search-reward-r
export class ReferralRewardsRepository extends Repository<ReferralReward> {
constructor(@InjectRepository(ReferralReward) repository: Repository<ReferralReward>) {
super(repository.target, repository.manager, repository.queryRunner);
}
}
async findPaginatedList(userIds: string[], queryDto: SearchRewardsRequestQueryDto) {
const { limit, skip } = PaginationUtils(queryDto);
const qb = this.createQueryBuilder("referral")
.where("referral.referrerId IN (:...userIds)", { userIds })
.leftJoinAndSelect("referral.referrer", "referrer")
.leftJoinAndSelect("referral.referredUser", "referred")
.orderBy("referral.createdAt", "DESC")
const qb = this.createQueryBuilder("rr")
.where("rr.userId IN (:...userIds)", { userIds })
.leftJoinAndSelect("rr.user", "user")
.orderBy("rr.createdAt", "DESC")
.skip(skip)
.take(limit);
+32
View File
@@ -0,0 +1,32 @@
import { ApiProperty } from "@nestjs/swagger";
import { IsNotEmpty, IsNumberString, IsString, Length } from "class-validator";
import { PaymentMessage } from "../../../common/enums/message.enum";
export class CreateUserBankAccountDto {
@IsNotEmpty({ message: PaymentMessage.CARD_NUMBER_REQUIRED })
@IsNumberString({ no_symbols: true }, { message: PaymentMessage.CARD_NUMBER_NUMBER_STRING })
@Length(16, 16, { message: PaymentMessage.CARD_NUMBER_LENGTH })
@ApiProperty({ description: "card number", example: "1234567812345678" })
cardNumber: string;
@IsNotEmpty({ message: PaymentMessage.IBAN_REQUIRED })
@IsNumberString({ no_symbols: true }, { message: PaymentMessage.IBAN_NUMBER_STRING })
// @IsIBAN({ message: PaymentMessage.IBAN_INVALID })
@Length(24, 24, { message: PaymentMessage.IBAN_INVALID })
@ApiProperty({ description: "IBAN number", example: "123456789012345678901234" })
IBan: string;
@IsNotEmpty({ message: PaymentMessage.BANK_NAME_REQUIRED })
@IsString({ message: PaymentMessage.BANK_NAME_STRING })
@Length(2, 100, { message: PaymentMessage.BANK_NAME_LENGTH })
@ApiProperty({ description: "bank name", example: "Example Bank" })
bankName: string;
@IsNotEmpty({ message: PaymentMessage.ACCOUNT_OWNER_NAME_REQUIRED })
@IsString({ message: PaymentMessage.ACCOUNT_OWNER_NAME_STRING })
@Length(3, 150, { message: PaymentMessage.ACCOUNT_OWNER_NAME_LENGTH })
@ApiProperty({ description: "account owner name", example: "John Doe" })
accountOwnerName: string;
}
+25
View File
@@ -0,0 +1,25 @@
import { Column, Entity, JoinColumn, OneToOne } from "typeorm";
import { BaseEntity } from "../../../common/entities/base.entity";
import { User } from "../../users/entities/user.entity";
@Entity()
export class UserBankAccount extends BaseEntity {
@Column({ type: "varchar", length: 100, unique: true, nullable: true })
cardNumber?: string;
@Column({ type: "varchar", length: 100, unique: true, nullable: true })
IBan?: string;
@Column({ type: "varchar", length: 100, nullable: false })
bankName: string;
@Column({ type: "varchar", length: 150, nullable: false })
accountOwnerName: string;
//----------------------
@OneToOne(() => User, (user) => user.bankAckount)
@JoinColumn()
user?: User
}
@@ -0,0 +1,12 @@
import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { UserBankAccount } from "../entities/user-bank-account.entity";
@Injectable()
export class UserBankAccountRepository extends Repository<UserBankAccount> {
constructor(@InjectRepository(UserBankAccount) repository: Repository<UserBankAccount>) {
super(repository.target, repository.manager, repository.queryRunner);
}
}
+19 -2
View File
@@ -15,6 +15,7 @@ import { SearchResellerInvoicesQueryDto } from './dto/search-reseller-invoices.d
import { PaginationDto } from '../../common/DTO/pagination.dto';
import { WalletsService } from '../wallets/providers/wallets.service';
import { CreateWithdrawRequestDto } from './dto/create-withdraw-request.dto';
import { CreateUserBankAccountDto } from './dto/create-user-bank-account.dto';
@Controller('reseller')
@AuthGuards()
@@ -127,8 +128,24 @@ export class ResellerController {
@ApiOperation({ summary: "remove Reseller/Agent withdraw request ==> reseller route" })
@ResellerRoute()
@Delete('wallet/withdraw/:id')
removeWithdrawRequest(@UserDec("id") userId: string) {
return this.walletsService.getBalance(userId)
removeWithdrawRequest(@UserDec("id") userId: string, @Param('id') id: string) {
return this.resellerService.removeWithdrawRequest(userId, id)
}
// ============ Bank Account =============
@ApiOperation({ summary: "Create Bank Account ==> reseller route" })
@ResellerRoute()
@Post('bank-account')
createBankAccount(@UserDec("id") userId: string, @Body() dto: CreateUserBankAccountDto) {
return this.resellerService.createUserBankAccount(userId, dto)
}
// ============ Remove Bank Account =============
@ApiOperation({ summary: "remove User Bank account ==> reseller route" })
@ResellerRoute()
@Delete('bank-account/:id')
removeBankAccount(@UserDec("id") userId: string, @Param('id') id: string) {
return this.resellerService.deleteUserBankAccount(userId, id)
}
}
+4 -2
View File
@@ -10,15 +10,17 @@ import { InvoicesModule } from '../invoices/invoices.module';
import { RewardWithdrawRequest } from "../reseller/entities/rewards-withdraw-request.entity";
import { WithdrawRequestRepository } from './repositories/withdraw-request.repository';
import { WalletsModule } from '../wallets/wallets.module';
import { UserBankAccount } from './entities/user-bank-account.entity';
import { UserBankAccountRepository } from './repositories/user-bank-account.repository';
@Module({
imports: [TypeOrmModule.forFeature([Reseller, RewardWithdrawRequest]),
imports: [TypeOrmModule.forFeature([Reseller, RewardWithdrawRequest, UserBankAccount]),
UsersModule,
ReferralsModule,
InvoicesModule,
WalletsModule
],
controllers: [ResellerController],
providers: [ResellerService, ResellerRepository, WithdrawRequestRepository],
providers: [ResellerService, ResellerRepository, WithdrawRequestRepository, UserBankAccountRepository],
})
export class ResellerModule { }
+28 -3
View File
@@ -9,6 +9,8 @@ import { SearchRewardsRequestQueryDto } from './dto/search-reward-requests.dto';
import { WithdrawRequestRepository } from './repositories/withdraw-request.repository';
import { SearchCustomersQueryDto } from './dto/search-customers.dto';
import { SearchResellerInvoicesQueryDto } from './dto/search-reseller-invoices.dto';
import { CreateUserBankAccountDto } from './dto/create-user-bank-account.dto';
import { UserBankAccountRepository } from './repositories/user-bank-account.repository';
@Injectable()
export class ResellerService {
@@ -18,6 +20,7 @@ export class ResellerService {
private readonly resellerRepository: ResellerRepository,
private readonly invoicesService: InvoicesService,
private readonly withdrawRequestRepository: WithdrawRequestRepository,
private readonly userBankAccountRepository: UserBankAccountRepository,
) { }
async create(dto: CreateResellerDto) {
@@ -148,20 +151,42 @@ export class ResellerService {
async removeWithdrawRequest(userId: string, withdrawRequestId: string) {
const request =await this.withdrawRequestRepository.findOne({
const request = await this.withdrawRequestRepository.findOne({
where: {
id: withdrawRequestId,
user: { id: userId }
}
})
if(!request){
if (!request) {
throw new NotFoundException()
}
if(request.paidAt){
if (request.paidAt) {
throw new BadRequestException("درخواست پرداخت شده قابل حذف نیست")
}
return this.withdrawRequestRepository.remove(request)
}
//********* Bank Account ***********/
async createUserBankAccount(userId: string, dto: CreateUserBankAccountDto) {
const { user } = await this.usersService.findOneById(userId)
const account = this.userBankAccountRepository.create({
user,
...dto
})
return this.userBankAccountRepository.save(account)
}
//********* Remove Bank Account ***********/
async deleteUserBankAccount(userId: string, bankAccountId: string) {
return this.userBankAccountRepository.delete({
user: { id: userId },
id: bankAccountId
})
}
}
@@ -31,6 +31,7 @@ import { Ticket } from "../../tickets/entities/ticket.entity";
import { Wallet } from "../../wallets/entities/wallet.entity";
import { FinancialType } from "../enums/financial-type.enum";
import { Reseller } from "../../reseller/entities/reseller.entity";
import { UserBankAccount } from "../../reseller/entities/user-bank-account.entity";
@Entity()
export class User extends BaseEntity {
@@ -171,4 +172,9 @@ export class User extends BaseEntity {
@OneToOne(() => Reseller, reseller => reseller.owner, { nullable: true })
ownedReseller?: Reseller
//------------------------
@OneToOne(() => UserBankAccount, (account) => account.user, { nullable: true })
bankAckount: UserBankAccount
}