mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-08-25 21:59:40 +00:00
63 lines
2.4 KiB
TypeScript
63 lines
2.4 KiB
TypeScript
import { Injectable, UnprocessableEntityException } from '@nestjs/common';
|
|
import Decimal from 'decimal.js';
|
|
import { Transactional } from 'typeorm-transactional';
|
|
import {
|
|
AccountTransactionWebhookRequest,
|
|
CardTransactionWebhookRequest,
|
|
} from '~/common/modules/neoleap/dtos/requests';
|
|
import { Transaction } from '../entities/transaction.entity';
|
|
import { TransactionRepository } from '../repositories/transaction.repository';
|
|
import { AccountService } from './account.service';
|
|
import { CardService } from './card.service';
|
|
|
|
@Injectable()
|
|
export class TransactionService {
|
|
constructor(
|
|
private readonly transactionRepository: TransactionRepository,
|
|
private readonly accountService: AccountService,
|
|
private readonly cardService: CardService,
|
|
) {}
|
|
|
|
@Transactional()
|
|
async createCardTransaction(body: CardTransactionWebhookRequest) {
|
|
const card = await this.cardService.getCardByVpan(body.cardId);
|
|
const existingTransaction = await this.findExistingTransaction(body.transactionId, card.account.accountReference);
|
|
|
|
if (existingTransaction) {
|
|
throw new UnprocessableEntityException('TRANSACTION.ALREADY_EXISTS');
|
|
}
|
|
|
|
const transaction = await this.transactionRepository.createCardTransaction(card, body);
|
|
const total = new Decimal(body.transactionAmount).plus(body.billingAmount).plus(body.fees).plus(body.vatOnFees);
|
|
|
|
await this.accountService.decreaseAccountBalance(card.account.accountReference, total.toNumber());
|
|
|
|
return transaction;
|
|
}
|
|
|
|
@Transactional()
|
|
async createAccountTransaction(body: AccountTransactionWebhookRequest) {
|
|
const account = await this.accountService.getAccountByAccountNumber(body.accountId);
|
|
|
|
const existingTransaction = await this.findExistingTransaction(body.transactionId, account.accountReference);
|
|
|
|
if (existingTransaction) {
|
|
throw new UnprocessableEntityException('TRANSACTION.ALREADY_EXISTS');
|
|
}
|
|
|
|
const transaction = await this.transactionRepository.createAccountTransaction(account, body);
|
|
await this.accountService.creditAccountBalance(account.accountReference, body.amount);
|
|
|
|
return transaction;
|
|
}
|
|
|
|
private async findExistingTransaction(transactionId: string, accountReference: string): Promise<Transaction | null> {
|
|
const existingTransaction = await this.transactionRepository.findTransactionByReference(
|
|
transactionId,
|
|
accountReference,
|
|
);
|
|
|
|
return existingTransaction;
|
|
}
|
|
}
|