mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2026-03-10 18:41:46 +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 amount = transaction.transactionAmount;
|
||||||
const merchant = transaction.merchantName || 'merchant';
|
const merchant = transaction.merchantName || 'merchant';
|
||||||
|
|
||||||
// Reload card to get the latest account balance after transaction
|
// Fetch account by reference number to get fresh balance (bypasses entity cache)
|
||||||
const cardWithUpdatedBalance = await this.cardService.getCardById(card.id);
|
// This ensures we get the updated balance after the transaction
|
||||||
const balance = cardWithUpdatedBalance.account?.balance || card.account?.balance || 0;
|
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(
|
const currency = getCurrency(
|
||||||
accountCurrency,
|
accountCurrency,
|
||||||
transaction.transactionCurrency,
|
transaction.transactionCurrency,
|
||||||
@ -332,39 +361,86 @@ export class TransactionNotificationListener {
|
|||||||
const childName = childUser?.firstName || defaultChildName;
|
const childName = childUser?.firstName || defaultChildName;
|
||||||
const amount = transaction.transactionAmount;
|
const amount = transaction.transactionAmount;
|
||||||
|
|
||||||
// Always reload parent account to get updated balance after transfer
|
// Fetch parent account by reference number to get fresh balance (bypasses entity cache)
|
||||||
let parentAccount: any = null;
|
// This ensures we get the updated balance after the transfer
|
||||||
|
let parentAccountBalance = 0;
|
||||||
|
let parentAccountCurrency: string | undefined;
|
||||||
|
|
||||||
if (card.parentId) {
|
if (card.parentId) {
|
||||||
try {
|
try {
|
||||||
parentAccount = await this.accountService.getAccountByCustomerId(card.parentId);
|
// Get parent's card to access their account reference
|
||||||
this.logger.debug(`Fetched parent account for top-up notification - balance: ${parentAccount.balance}, currency: ${parentAccount.currency}`);
|
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) {
|
} 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;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
// If no parentId, try via customer relation
|
||||||
// If parent account not found, try via customer relation
|
|
||||||
if (!parentAccount) {
|
|
||||||
const parentCustomer = customer?.junior?.guardian?.customer;
|
const parentCustomer = customer?.junior?.guardian?.customer;
|
||||||
if (parentCustomer?.id) {
|
if (parentCustomer?.id) {
|
||||||
try {
|
try {
|
||||||
parentAccount = await this.accountService.getAccountByCustomerId(parentCustomer.id);
|
const parentCard = await this.cardService.getCardByCustomerId(parentCustomer.id);
|
||||||
this.logger.debug(`Fetched parent account via customer relation - balance: ${parentAccount.balance}, currency: ${parentAccount.currency}`);
|
if (parentCard?.account?.accountReference) {
|
||||||
} catch (error: any) {
|
const parentAccount = await this.accountService.getAccountByReferenceNumber(
|
||||||
this.logger.warn(`Could not fetch parent account via customer: ${error?.message}`);
|
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 balance = parentAccountBalance;
|
||||||
const accountCurrency = parentAccount?.currency || card.account?.currency;
|
const accountCurrency = parentAccountCurrency;
|
||||||
const currency = getCurrency(
|
const currency = getCurrency(
|
||||||
accountCurrency,
|
accountCurrency,
|
||||||
transaction.transactionCurrency,
|
transaction.transactionCurrency,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.logger.debug(
|
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);
|
const formattedAmount = formatCurrencyAmount(amount, currency);
|
||||||
|
|||||||
Reference in New Issue
Block a user