fix: bug in approve of the deposit request
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user