mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2026-03-10 17:11:44 +00:00
feat: improve transaction notification listener for accurate balance retrieval
- Enhanced TransactionNotificationListener to fetch updated balances for child and parent accounts by bypassing entity cache. - Implemented error handling and fallback mechanisms to ensure reliable balance notifications. - Updated logging for better traceability of balance fetching processes.
This commit is contained in:
@ -105,11 +105,40 @@ export class TransactionNotificationListener {
|
||||
const amount = transaction.transactionAmount;
|
||||
const merchant = transaction.merchantName || 'merchant';
|
||||
|
||||
// Reload card to get the latest account balance after transaction
|
||||
const cardWithUpdatedBalance = await this.cardService.getCardById(card.id);
|
||||
const balance = cardWithUpdatedBalance.account?.balance || card.account?.balance || 0;
|
||||
// Fetch account by reference number to get fresh balance (bypasses entity cache)
|
||||
// This ensures we get the updated balance after the transaction
|
||||
let balance = 0;
|
||||
let accountCurrency: string | undefined;
|
||||
|
||||
const accountCurrency = cardWithUpdatedBalance.account?.currency || card.account?.currency;
|
||||
try {
|
||||
// Reload card to get account reference
|
||||
const cardWithUpdatedBalance = await this.cardService.getCardById(card.id);
|
||||
if (cardWithUpdatedBalance?.account?.accountReference) {
|
||||
// Fetch by reference number to get fresh balance from database
|
||||
const account = await this.accountService.getAccountByReferenceNumber(
|
||||
cardWithUpdatedBalance.account.accountReference
|
||||
);
|
||||
balance = account.balance;
|
||||
accountCurrency = account.currency;
|
||||
this.logger.debug(
|
||||
`[Child Notification] Fetched account by reference - balance: ${balance} ${accountCurrency}`
|
||||
);
|
||||
} else {
|
||||
// Fallback: use card's account balance
|
||||
balance = cardWithUpdatedBalance.account?.balance || card.account?.balance || 0;
|
||||
accountCurrency = cardWithUpdatedBalance.account?.currency || card.account?.currency;
|
||||
this.logger.debug(
|
||||
`[Child Notification] Using card account balance - balance: ${balance} ${accountCurrency}`
|
||||
);
|
||||
}
|
||||
} catch (error: any) {
|
||||
this.logger.warn(
|
||||
`[Child Notification] Could not fetch account by reference: ${error?.message}. Using card account balance.`
|
||||
);
|
||||
// Fallback: use card's account balance
|
||||
balance = card.account?.balance || 0;
|
||||
accountCurrency = card.account?.currency;
|
||||
}
|
||||
const currency = getCurrency(
|
||||
accountCurrency,
|
||||
transaction.transactionCurrency,
|
||||
@ -332,39 +361,86 @@ export class TransactionNotificationListener {
|
||||
const childName = childUser?.firstName || defaultChildName;
|
||||
const amount = transaction.transactionAmount;
|
||||
|
||||
// Always reload parent account to get updated balance after transfer
|
||||
let parentAccount: any = null;
|
||||
// Fetch parent account by reference number to get fresh balance (bypasses entity cache)
|
||||
// This ensures we get the updated balance after the transfer
|
||||
let parentAccountBalance = 0;
|
||||
let parentAccountCurrency: string | undefined;
|
||||
|
||||
if (card.parentId) {
|
||||
try {
|
||||
parentAccount = await this.accountService.getAccountByCustomerId(card.parentId);
|
||||
this.logger.debug(`Fetched parent account for top-up notification - balance: ${parentAccount.balance}, currency: ${parentAccount.currency}`);
|
||||
// Get parent's card to access their account reference
|
||||
const parentCard = await this.cardService.getCardByCustomerId(card.parentId);
|
||||
if (parentCard?.account?.accountReference) {
|
||||
// Fetch by reference number to get fresh balance from database
|
||||
const parentAccount = await this.accountService.getAccountByReferenceNumber(
|
||||
parentCard.account.accountReference
|
||||
);
|
||||
parentAccountBalance = parentAccount.balance;
|
||||
parentAccountCurrency = parentAccount.currency;
|
||||
this.logger.debug(
|
||||
`[Parent Top-Up] Fetched parent account by reference - balance: ${parentAccountBalance} ${parentAccountCurrency}`
|
||||
);
|
||||
} else {
|
||||
// Fallback: try by customer ID
|
||||
const parentAccount = await this.accountService.getAccountByCustomerId(card.parentId);
|
||||
parentAccountBalance = parentAccount.balance;
|
||||
parentAccountCurrency = parentAccount.currency;
|
||||
this.logger.debug(
|
||||
`[Parent Top-Up] Fetched parent account by customer ID - balance: ${parentAccountBalance} ${parentAccountCurrency}`
|
||||
);
|
||||
}
|
||||
} catch (error: any) {
|
||||
this.logger.warn(`Could not fetch parent account for customer ${card.parentId}: ${error?.message}, using child account balance`);
|
||||
this.logger.warn(
|
||||
`[Parent Top-Up] Could not fetch parent account for customer ${card.parentId}: ${error?.message}. Using child account balance as fallback.`
|
||||
);
|
||||
parentAccountBalance = card.account?.balance || 0;
|
||||
parentAccountCurrency = card.account?.currency;
|
||||
}
|
||||
}
|
||||
|
||||
// If parent account not found, try via customer relation
|
||||
if (!parentAccount) {
|
||||
} else {
|
||||
// If no parentId, try via customer relation
|
||||
const parentCustomer = customer?.junior?.guardian?.customer;
|
||||
if (parentCustomer?.id) {
|
||||
try {
|
||||
parentAccount = await this.accountService.getAccountByCustomerId(parentCustomer.id);
|
||||
this.logger.debug(`Fetched parent account via customer relation - balance: ${parentAccount.balance}, currency: ${parentAccount.currency}`);
|
||||
} catch (error: any) {
|
||||
this.logger.warn(`Could not fetch parent account via customer: ${error?.message}`);
|
||||
const parentCard = await this.cardService.getCardByCustomerId(parentCustomer.id);
|
||||
if (parentCard?.account?.accountReference) {
|
||||
const parentAccount = await this.accountService.getAccountByReferenceNumber(
|
||||
parentCard.account.accountReference
|
||||
);
|
||||
parentAccountBalance = parentAccount.balance;
|
||||
parentAccountCurrency = parentAccount.currency;
|
||||
this.logger.debug(
|
||||
`[Parent Top-Up] Fetched parent account via customer relation (by reference) - balance: ${parentAccountBalance} ${parentAccountCurrency}`
|
||||
);
|
||||
} else {
|
||||
const parentAccount = await this.accountService.getAccountByCustomerId(parentCustomer.id);
|
||||
parentAccountBalance = parentAccount.balance;
|
||||
parentAccountCurrency = parentAccount.currency;
|
||||
this.logger.debug(
|
||||
`[Parent Top-Up] Fetched parent account via customer relation - balance: ${parentAccountBalance} ${parentAccountCurrency}`
|
||||
);
|
||||
}
|
||||
} catch (error: any) {
|
||||
this.logger.warn(
|
||||
`[Parent Top-Up] Could not fetch parent account via customer: ${error?.message}. Using child account balance as fallback.`
|
||||
);
|
||||
parentAccountBalance = card.account?.balance || 0;
|
||||
parentAccountCurrency = card.account?.currency;
|
||||
}
|
||||
} else {
|
||||
parentAccountBalance = card.account?.balance || 0;
|
||||
parentAccountCurrency = card.account?.currency;
|
||||
}
|
||||
}
|
||||
|
||||
const balance = parentAccount?.balance || card.account?.balance || 0;
|
||||
const accountCurrency = parentAccount?.currency || card.account?.currency;
|
||||
const balance = parentAccountBalance;
|
||||
const accountCurrency = parentAccountCurrency;
|
||||
const currency = getCurrency(
|
||||
accountCurrency,
|
||||
transaction.transactionCurrency,
|
||||
);
|
||||
|
||||
this.logger.debug(
|
||||
`[Parent Top-Up Notification] Parent account currency: ${parentAccount?.currency}, Account currency: ${accountCurrency}, Transaction currency: ${transaction.transactionCurrency}, Final currency: ${currency}, Parent balance: ${balance}, Amount: ${amount}`
|
||||
`[Parent Top-Up Notification] Parent account currency: ${parentAccountCurrency}, Account currency: ${accountCurrency}, Transaction currency: ${transaction.transactionCurrency}, Final currency: ${currency}, Parent balance: ${balance}, Amount: ${amount}`
|
||||
);
|
||||
|
||||
const formattedAmount = formatCurrencyAmount(amount, currency);
|
||||
|
||||
Reference in New Issue
Block a user