import { Injectable, UnprocessableEntityException } from '@nestjs/common'; import { CreateApplicationResponse } from '~/common/modules/neoleap/dtos/response'; import { Account } from '../entities/account.entity'; import { AccountRepository } from '../repositories/account.repository'; @Injectable() export class AccountService { constructor(private readonly accountRepository: AccountRepository) {} createAccount(data: CreateApplicationResponse): Promise { return this.accountRepository.createAccount(data); } async getAccountByReferenceNumber(accountReference: string): Promise { const account = await this.accountRepository.getAccountByReferenceNumber(accountReference); if (!account) { throw new UnprocessableEntityException('ACCOUNT.NOT_FOUND'); } return account; } async getAccountByAccountNumber(accountNumber: string): Promise { const account = await this.accountRepository.getAccountByAccountNumber(accountNumber); if (!account) { throw new UnprocessableEntityException('ACCOUNT.NOT_FOUND'); } return account; } async getAccountByIban(iban: string): Promise { const account = await this.accountRepository.getAccountByIban(iban); if (!account) { throw new UnprocessableEntityException('ACCOUNT.NOT_FOUND'); } return account; } creditAccountBalance(accountReference: string, amount: number) { return this.accountRepository.topUpAccountBalance(accountReference, amount); } async getAccountByCustomerId(customerId: string): Promise { const account = await this.accountRepository.getAccountByCustomerId(customerId); if (!account) { throw new UnprocessableEntityException('ACCOUNT.NOT_FOUND'); } return account; } async decreaseAccountBalance(accountReference: string, amount: number) { const account = await this.getAccountByReferenceNumber(accountReference); /** * * While there is no need to check for insufficient balance because this is a webhook handler, * I just added this check to ensure we don't have corruption in our data. */ if (account.balance < amount) { throw new UnprocessableEntityException('ACCOUNT.INSUFFICIENT_BALANCE'); } return this.accountRepository.decreaseAccountBalance(accountReference, amount); } increaseReservedBalance(account: Account, amount: number) { // Balance check is performed by the caller (e.g., transferToChild) // to ensure correct account (guardian vs child) is validated return this.accountRepository.increaseReservedBalance(account.id, amount); } decrementReservedBalance(account: Account, amount: number) { return this.accountRepository.decreaseReservedBalance(account.id, amount); } //THIS IS A MOCK FUNCTION FOR TESTING PURPOSES ONLY async fundIban(iban: string, amount: number) { const account = await this.getAccountByIban(iban); return this.accountRepository.topUpAccountBalance(account.accountReference, amount); } }