fix: bug in approve of the deposit request

This commit is contained in:
mahyargdz
2025-02-24 17:16:17 +03:30
parent d563c254e2
commit 17e39fde09
5 changed files with 57 additions and 39 deletions
@@ -11,7 +11,6 @@ import { PaginationDto } from "../../../common/DTO/pagination.dto";
import { CommonMessage, PaymentMessage, UserMessage, WalletMessage } from "../../../common/enums/message.enum"; import { CommonMessage, PaymentMessage, UserMessage, WalletMessage } from "../../../common/enums/message.enum";
import { User } from "../../users/entities/user.entity"; import { User } from "../../users/entities/user.entity";
import { PaginationUtils } from "../../utils/providers/pagination.utils"; import { PaginationUtils } from "../../utils/providers/pagination.utils";
import { Wallet } from "../../wallets/entities/wallet.entity";
import { WalletsService } from "../../wallets/providers/wallets.service"; import { WalletsService } from "../../wallets/providers/wallets.service";
import { PAYMENT } from "../constants"; import { PAYMENT } from "../constants";
import { CreateBankAccountDto } from "../DTO/create-bankaccount.dto"; import { CreateBankAccountDto } from "../DTO/create-bankaccount.dto";
@@ -363,27 +362,30 @@ export class PaymentsService {
await queryRunner.connect(); await queryRunner.connect();
await queryRunner.startTransaction(); await queryRunner.startTransaction();
try { try {
const depositRequest = await queryRunner.manager.findOne(DepositRequest, { // const depositRequest = await queryRunner.manager.findOne(DepositRequest, {
where: { id: depositId }, // where: { id: depositId },
lock: { mode: "pessimistic_write" }, // lock: { mode: "pessimistic_write" },
}); // });
const depositRequest = await queryRunner.manager
.createQueryBuilder(DepositRequest, "deposit")
.innerJoinAndSelect("deposit.user", "user")
.where("deposit.id = :id", { id: depositId })
.setLock("pessimistic_write")
.getOne();
if (!depositRequest) throw new BadRequestException(PaymentMessage.DEPOSIT_NOT_FOUND); if (!depositRequest) throw new BadRequestException(PaymentMessage.DEPOSIT_NOT_FOUND);
if (depositRequest.status === DepositRequestStatus.APPROVED) throw new BadRequestException(PaymentMessage.DEPOSIT_ALREADY_APPROVED); if (depositRequest.status === DepositRequestStatus.APPROVED) throw new BadRequestException(PaymentMessage.DEPOSIT_ALREADY_APPROVED);
const wallet = await queryRunner.manager.findOneBy(Wallet, { user: depositRequest.user });
if (!wallet) throw new BadRequestException(WalletMessage.WALLET_NOT_FOUND);
await queryRunner.manager.update(Wallet, { id: wallet.id }, { balance: new Decimal(wallet.balance).add(depositRequest.amount) });
await queryRunner.manager.update(DepositRequest, { id: depositRequest.id }, { status: DepositRequestStatus.APPROVED }); await queryRunner.manager.update(DepositRequest, { id: depositRequest.id }, { status: DepositRequestStatus.APPROVED });
await this.walletsService.createDepositTransaction(depositRequest.amount, wallet.id, queryRunner); await this.walletsService.createDepositTransaction(depositRequest.amount, depositRequest.user.id, queryRunner);
await queryRunner.commitTransaction(); await queryRunner.commitTransaction();
return { return {
message: PaymentMessage.DEPOSIT_APPROVED, message: PaymentMessage.DEPOSIT_APPROVED,
depositRequest, depositRequest: depositRequest.id,
}; };
} catch (error) { } catch (error) {
await queryRunner.rollbackTransaction(); await queryRunner.rollbackTransaction();
+5 -8
View File
@@ -9,28 +9,25 @@ import { IFile } from "../utils/interfaces/IFile";
@ApiTags("Uploader") @ApiTags("Uploader")
@Controller("uploader") @Controller("uploader")
@AuthGuards()
export class UploaderController { export class UploaderController {
constructor(private readonly uploaderService: UploaderService) {} constructor(private readonly uploaderService: UploaderService) {}
@AuthGuards()
@ApiOperation({ summary: "Uploads a single file" }) @ApiOperation({ summary: "Uploads a single file" })
@ApiConsumes("multipart/form-data") @ApiConsumes("multipart/form-data")
@UseInterceptors(FileInterceptor("file")) @UseInterceptors(FileInterceptor("file"))
@ApiBody({ type: UploadSingleFileDto }) @ApiBody({ type: UploadSingleFileDto })
@Post("single-file") @Post("single-file")
async uploadFile(@UploadedFile() file: IFile) { uploadFile(@UploadedFile() file: IFile) {
console.log(file); return this.uploaderService.upload(file);
return await this.uploaderService.upload(file);
} }
@AuthGuards()
@ApiOperation({ summary: "Uploads multiple files" }) @ApiOperation({ summary: "Uploads multiple files" })
@ApiConsumes("multipart/form-data") @ApiConsumes("multipart/form-data")
@UseInterceptors(FilesInterceptor("files")) @UseInterceptors(FilesInterceptor("files"))
@ApiBody({ type: UploadMultipleFileDto }) @ApiBody({ type: UploadMultipleFileDto })
@Post("multi-file") @Post("multi-file")
async uploadFiles(@UploadedFiles() files: IFile[]) { uploadFiles(@UploadedFiles() files: IFile[]) {
console.log({ files }); return this.uploaderService.uploadMultiple(files);
return await this.uploaderService.uploadMultiple(files);
} }
} }
+4 -2
View File
@@ -12,7 +12,9 @@ export class UploaderService {
} }
async uploadMultiple(files: IFile[]) { async uploadMultiple(files: IFile[]) {
const uploadPromises = files.map((file) => this.s3Service.upload(file)); // const uploadPromises = files.map((file) => this.s3Service.upload(file));
return await Promise.all(uploadPromises);
// return await Promise.all(uploadPromises);
return this.s3Service.uploadMultiple(files);
} }
} }
+28 -11
View File
@@ -1,8 +1,8 @@
import { randomUUID } from "node:crypto"; import { randomUUID } from "node:crypto";
import { extname } from "node:path"; import { extname } from "node:path";
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3"; import { PutObjectCommand, PutObjectCommandInput, S3Client } from "@aws-sdk/client-s3";
import { Inject, Injectable } from "@nestjs/common"; import { Inject, Injectable, InternalServerErrorException, Logger } from "@nestjs/common";
import { IS3Configs } from "../../../configs/s3.config"; import { IS3Configs } from "../../../configs/s3.config";
import { S3_CONFIG } from "../constants"; import { S3_CONFIG } from "../constants";
@@ -10,7 +10,10 @@ import { IFile } from "../interfaces/IFile";
@Injectable() @Injectable()
export class S3Service { export class S3Service {
private readonly logger = new Logger(S3Service.name);
private client: S3Client; private client: S3Client;
//
constructor(@Inject(S3_CONFIG) private s3Configs: IS3Configs) { constructor(@Inject(S3_CONFIG) private s3Configs: IS3Configs) {
this.client = new S3Client({ this.client = new S3Client({
endpoint: this.s3Configs.endpoint, endpoint: this.s3Configs.endpoint,
@@ -24,17 +27,31 @@ export class S3Service {
async upload(file: IFile) { async upload(file: IFile) {
const extName = extname(file.originalname); const extName = extname(file.originalname);
const params = { const params: PutObjectCommandInput = {
Body: file.buffer, Body: file.buffer,
Bucket: this.s3Configs.bucket, Bucket: this.s3Configs.bucket,
Key: "images/" + randomUUID() + Date.now() + extName, Key: `images/${randomUUID()}${Date.now()}${extName}`,
}; ACL: "public-read",
await this.client.send(new PutObjectCommand(params));
const url = `${this.s3Configs.url}/${params.Key}`;
return {
url,
originalname: file.originalname,
size: file.size,
}; };
//
try {
await this.client.send(new PutObjectCommand(params));
const url = `${this.s3Configs.url}/${params.Key}`;
return {
url,
originalname: file.originalname,
size: file.size,
};
} catch (error) {
this.logger.error(error);
throw new InternalServerErrorException("Failed to upload file");
}
}
async uploadMultiple(files: IFile[]) {
const uploadPromises = files.map((file) => this.upload(file));
const results = await Promise.all(uploadPromises);
return results;
} }
} }
@@ -59,20 +59,20 @@ export class WalletsService {
} }
//*********************************** */ //*********************************** */
async createDepositTransaction(amount: Decimal, walletId: string, queryRunner: QueryRunner) { async createDepositTransaction(amount: Decimal, userId: string, queryRunner: QueryRunner) {
// const wallet = await queryRunner.manager.findOne(Wallet, { where: { user: { id: userId } }, lock: { mode: "pessimistic_write" } }); const wallet = await queryRunner.manager.findOne(Wallet, { where: { user: { id: userId } }, lock: { mode: "pessimistic_write" } });
// if (!wallet) throw new BadRequestException(WalletMessage.WALLET_NOT_FOUND); if (!wallet) throw new BadRequestException(WalletMessage.WALLET_NOT_FOUND);
const transaction = queryRunner.manager.create(WalletTransaction, { const transaction = queryRunner.manager.create(WalletTransaction, {
amount, amount,
wallet: { id: walletId }, wallet: { id: wallet.id },
type: TransactionType.DEPOSIT, type: TransactionType.DEPOSIT,
description: WalletMessage.DEPOSIT_WALLET_TRANSFER, description: WalletMessage.DEPOSIT_WALLET_TRANSFER,
}); });
// wallet.balance = new Decimal(wallet.balance).add(transaction.amount); wallet.balance = new Decimal(wallet.balance).add(transaction.amount);
// await queryRunner.manager.save(Wallet, wallet);
await queryRunner.manager.save(Wallet, wallet);
await queryRunner.manager.save(WalletTransaction, transaction); await queryRunner.manager.save(WalletTransaction, transaction);
return transaction; return transaction;