mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2026-03-10 15:11:46 +00:00
Merge pull request #87 from Zod-Alkhair/feature/notification-system-fcm-registration
fix the messages
This commit is contained in:
@ -139,14 +139,39 @@ export class MoneyRequestNotificationListener {
|
||||
const currency = getCurrency(accountCurrency, null, 'SAR');
|
||||
const formattedAmount = formatCurrencyAmount(amount, currency);
|
||||
|
||||
const locale = this.getUserLocale(parentUser);
|
||||
|
||||
this.logger.debug(
|
||||
`Notifying parent (user ${parentUser.id}): ${childName} requested ${formattedAmount} ${currency} - ${reason}`
|
||||
`Notifying parent (user ${parentUser.id}): ${childName} requested ${formattedAmount} ${currency} for ${reason}`
|
||||
);
|
||||
|
||||
let title: string;
|
||||
let message: string;
|
||||
|
||||
try {
|
||||
title = this.i18n.t('app.NOTIFICATION.MONEY_REQUEST_CREATED_TITLE', { lang: locale });
|
||||
message = this.i18n.t('app.NOTIFICATION.MONEY_REQUEST_CREATED_MESSAGE', {
|
||||
lang: locale,
|
||||
args: {
|
||||
childName: childName,
|
||||
amount: formattedAmount,
|
||||
currency: currency,
|
||||
reason: reason,
|
||||
},
|
||||
});
|
||||
} catch (i18nError: any) {
|
||||
this.logger.error(
|
||||
`[MoneyRequestNotificationListener] i18n error for parent ${parentUser.id}: ${i18nError?.message || 'Unknown i18n error'}. Falling back to English.`,
|
||||
i18nError?.stack
|
||||
);
|
||||
title = 'Money Request';
|
||||
message = `${childName} has requested ${formattedAmount} ${currency} for ${reason}.`;
|
||||
}
|
||||
|
||||
await this.notificationFactory.send({
|
||||
userId: parentUser.id,
|
||||
title: 'Money Request',
|
||||
message: `${childName} requested ${formattedAmount} ${currency}. Reason: ${reason}`,
|
||||
title,
|
||||
message,
|
||||
scope: NotificationScope.MONEY_REQUEST_CREATED,
|
||||
preferences: this.getUserPreferences(parentUser),
|
||||
data: {
|
||||
|
||||
@ -180,32 +180,31 @@ export class TransactionNotificationListener {
|
||||
? this.i18n.t('app.NOTIFICATION.CHILD_TOP_UP_TITLE', { lang: locale })
|
||||
: this.i18n.t('app.NOTIFICATION.CHILD_SPENDING_TITLE', { lang: locale });
|
||||
|
||||
message = isTopUp
|
||||
? this.i18n.t('app.NOTIFICATION.CHILD_TOP_UP_MESSAGE', {
|
||||
lang: locale,
|
||||
args: {
|
||||
amount: formattedAmount,
|
||||
currency: currency,
|
||||
balance: formattedBalance,
|
||||
},
|
||||
})
|
||||
: this.i18n.t('app.NOTIFICATION.CHILD_SPENDING_MESSAGE', {
|
||||
lang: locale,
|
||||
args: {
|
||||
amount: formattedAmount,
|
||||
currency: currency,
|
||||
merchant: merchant,
|
||||
balance: formattedBalance,
|
||||
},
|
||||
});
|
||||
message = isTopUp
|
||||
? this.i18n.t('app.NOTIFICATION.CHILD_TOP_UP_MESSAGE', {
|
||||
lang: locale,
|
||||
args: {
|
||||
amount: formattedAmount,
|
||||
currency: currency,
|
||||
balance: formattedBalance,
|
||||
},
|
||||
})
|
||||
: this.i18n.t('app.NOTIFICATION.CHILD_SPENDING_MESSAGE', {
|
||||
lang: locale,
|
||||
args: {
|
||||
amount: formattedAmount,
|
||||
currency: currency,
|
||||
merchant: merchant,
|
||||
},
|
||||
});
|
||||
} catch (i18nError: any) {
|
||||
console.error(`[TransactionNotificationListener] i18n error:`, i18nError);
|
||||
this.logger.error(`i18n translation failed: ${i18nError?.message}`, i18nError?.stack);
|
||||
// Fallback to English without i18n
|
||||
title = isTopUp ? 'Card Topped Up' : 'Purchase Successful';
|
||||
message = isTopUp
|
||||
? `You received ${formattedAmount} ${currency}. Total balance: ${formattedBalance} ${currency}`
|
||||
: `You spent ${formattedAmount} ${currency} at ${merchant}. Balance: ${formattedBalance} ${currency}`;
|
||||
title = isTopUp ? 'Funds Credited' : 'Purchase Successful';
|
||||
message = isTopUp
|
||||
? `${formattedAmount} ${currency} has been added to your card. Total balance: ${formattedBalance} ${currency}`
|
||||
: `You spent ${formattedAmount} ${currency} at ${merchant}`;
|
||||
}
|
||||
|
||||
this.logger.debug(
|
||||
@ -263,29 +262,80 @@ export class TransactionNotificationListener {
|
||||
const amount = transaction.transactionAmount;
|
||||
const merchant = transaction.merchantName || 'a merchant';
|
||||
|
||||
// Get parent's account balance (not child's balance) - reload to get fresh balance
|
||||
// Get parent's available balance (balance - reserved_balance) - reload to get fresh balance
|
||||
let parentAccountBalance = 0;
|
||||
let parentAccountReservedBalance = 0;
|
||||
let parentAccountCurrency: string | undefined;
|
||||
let availableBalance = 0;
|
||||
|
||||
try {
|
||||
if (card.parentId) {
|
||||
// Always reload parent account to get fresh balance after transaction
|
||||
const parentAccount = await this.accountService.getAccountByCustomerId(card.parentId);
|
||||
parentAccountBalance = parentAccount.balance;
|
||||
parentAccountCurrency = parentAccount.currency;
|
||||
this.logger.debug(`Fetched parent account balance: ${parentAccountBalance}, currency: ${parentAccountCurrency}`);
|
||||
// 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;
|
||||
parentAccountReservedBalance = parentAccount.reservedBalance;
|
||||
availableBalance = parentAccountBalance - parentAccountReservedBalance;
|
||||
parentAccountCurrency = parentAccount.currency;
|
||||
this.logger.debug(
|
||||
`[Parent Spending] Fetched parent account by reference - balance: ${parentAccountBalance}, reserved: ${parentAccountReservedBalance}, available: ${availableBalance} ${parentAccountCurrency}`
|
||||
);
|
||||
} else {
|
||||
// Fallback: try by customer ID
|
||||
const parentAccount = await this.accountService.getAccountByCustomerId(card.parentId);
|
||||
parentAccountBalance = parentAccount.balance;
|
||||
parentAccountReservedBalance = parentAccount.reservedBalance;
|
||||
availableBalance = parentAccountBalance - parentAccountReservedBalance;
|
||||
parentAccountCurrency = parentAccount.currency;
|
||||
this.logger.debug(
|
||||
`[Parent Spending] Fetched parent account by customer ID - balance: ${parentAccountBalance}, reserved: ${parentAccountReservedBalance}, available: ${availableBalance} ${parentAccountCurrency}`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const parentCustomer = customer?.junior?.guardian?.customer;
|
||||
if (parentCustomer?.cards?.[0]?.account) {
|
||||
// Reload to get fresh balance
|
||||
const parentAccount = await this.accountService.getAccountByCustomerId(parentCustomer.id);
|
||||
parentAccountBalance = parentAccount.balance;
|
||||
parentAccountCurrency = parentAccount.currency;
|
||||
this.logger.debug(`Fetched parent account balance via customer: ${parentAccountBalance}, currency: ${parentAccountCurrency}`);
|
||||
if (parentCustomer?.id) {
|
||||
try {
|
||||
const parentCard = await this.cardService.getCardByCustomerId(parentCustomer.id);
|
||||
if (parentCard?.account?.accountReference) {
|
||||
const parentAccount = await this.accountService.getAccountByReferenceNumber(
|
||||
parentCard.account.accountReference
|
||||
);
|
||||
parentAccountBalance = parentAccount.balance;
|
||||
parentAccountReservedBalance = parentAccount.reservedBalance;
|
||||
availableBalance = parentAccountBalance - parentAccountReservedBalance;
|
||||
parentAccountCurrency = parentAccount.currency;
|
||||
this.logger.debug(
|
||||
`[Parent Spending] Fetched parent account via customer relation (by reference) - balance: ${parentAccountBalance}, reserved: ${parentAccountReservedBalance}, available: ${availableBalance} ${parentAccountCurrency}`
|
||||
);
|
||||
} else {
|
||||
const parentAccount = await this.accountService.getAccountByCustomerId(parentCustomer.id);
|
||||
parentAccountBalance = parentAccount.balance;
|
||||
parentAccountReservedBalance = parentAccount.reservedBalance;
|
||||
availableBalance = parentAccountBalance - parentAccountReservedBalance;
|
||||
parentAccountCurrency = parentAccount.currency;
|
||||
this.logger.debug(
|
||||
`[Parent Spending] Fetched parent account via customer relation - balance: ${parentAccountBalance}, reserved: ${parentAccountReservedBalance}, available: ${availableBalance} ${parentAccountCurrency}`
|
||||
);
|
||||
}
|
||||
} catch (error: any) {
|
||||
this.logger.warn(
|
||||
`[Parent Spending] Could not fetch parent account via customer: ${error?.message}. Using child account balance as fallback.`
|
||||
);
|
||||
availableBalance = card.account?.balance || 0;
|
||||
parentAccountCurrency = card.account?.currency;
|
||||
}
|
||||
} else {
|
||||
availableBalance = card.account?.balance || 0;
|
||||
parentAccountCurrency = card.account?.currency;
|
||||
}
|
||||
}
|
||||
} catch (error: any) {
|
||||
this.logger.warn(`Could not fetch parent account for parent notification: ${error?.message}, using child account balance as fallback`);
|
||||
parentAccountBalance = card.account?.balance || 0;
|
||||
this.logger.warn(`[Parent Spending] Could not fetch parent account: ${error?.message}, using child account balance as fallback`);
|
||||
availableBalance = card.account?.balance || 0;
|
||||
parentAccountCurrency = card.account?.currency;
|
||||
}
|
||||
|
||||
@ -297,11 +347,12 @@ export class TransactionNotificationListener {
|
||||
);
|
||||
|
||||
this.logger.debug(
|
||||
`[Parent Spending Notification] Parent account currency: ${parentAccountCurrency}, Account currency: ${accountCurrency}, Transaction currency: ${transaction.transactionCurrency}, Final currency: ${currency}, Parent balance: ${parentAccountBalance}, Amount: ${amount}`
|
||||
`[Parent Spending Notification] Parent account currency: ${parentAccountCurrency}, Account currency: ${accountCurrency}, Transaction currency: ${transaction.transactionCurrency}, Final currency: ${currency}, Parent available balance: ${availableBalance}, Amount: ${amount}`
|
||||
);
|
||||
|
||||
const formattedAmount = formatCurrencyAmount(amount, currency);
|
||||
const formattedBalance = formatCurrencyAmount(parentAccountBalance, currency);
|
||||
// Use available balance for parent spending notification
|
||||
const formattedBalance = formatCurrencyAmount(availableBalance, currency);
|
||||
|
||||
this.logger.debug(
|
||||
`Notifying parent (user ${parentUser.id}): ${childName} spent ${formattedAmount} ${currency} at ${merchant}`
|
||||
@ -325,8 +376,8 @@ export class TransactionNotificationListener {
|
||||
} catch (i18nError: any) {
|
||||
console.error(`[TransactionNotificationListener] i18n error in parent spending:`, i18nError);
|
||||
this.logger.error(`i18n translation failed: ${i18nError?.message}`, i18nError?.stack);
|
||||
title = 'Child Spending Alert';
|
||||
message = `${childName} spent ${formattedAmount} ${currency} at ${merchant}. Balance: ${formattedBalance} ${currency}`;
|
||||
title = 'Spending Alert';
|
||||
message = `${childName} spent ${formattedAmount} ${currency} at ${merchant}. Remaining balance: ${formattedBalance} ${currency}`;
|
||||
}
|
||||
|
||||
await this.notificationFactory.send({
|
||||
@ -479,7 +530,7 @@ export class TransactionNotificationListener {
|
||||
const formattedBalance = formatCurrencyAmount(balance, currency);
|
||||
|
||||
this.logger.debug(
|
||||
`Notifying parent (user ${parentUser.id}): Transferred ${formattedAmount} ${currency} to ${childName}, parent balance: ${formattedBalance} ${currency}`
|
||||
`Notifying parent (user ${parentUser.id}): Transferred ${formattedAmount} ${currency} to ${childName}, child balance: ${formattedBalance} ${currency}`
|
||||
);
|
||||
|
||||
let title: string;
|
||||
@ -499,8 +550,8 @@ export class TransactionNotificationListener {
|
||||
} catch (i18nError: any) {
|
||||
console.error(`[TransactionNotificationListener] i18n error in parent top-up:`, i18nError);
|
||||
this.logger.error(`i18n translation failed: ${i18nError?.message}`, i18nError?.stack);
|
||||
title = 'Top-Up Confirmation';
|
||||
message = `You transferred ${formattedAmount} ${currency} to ${childName}. Balance: ${formattedBalance} ${currency}`;
|
||||
title = 'Transfer Completed';
|
||||
message = `${formattedAmount} ${currency} has been transferred to ${childName}'s card. ${childName}'s balance is ${formattedBalance} ${currency}`;
|
||||
}
|
||||
|
||||
await this.notificationFactory.send({
|
||||
|
||||
@ -112,17 +112,17 @@
|
||||
"NOT_FOUND": "لم يتم العثور على البطاقة."
|
||||
},
|
||||
"NOTIFICATION": {
|
||||
"CHILD_TOP_UP_TITLE": "تم شحن البطاقة",
|
||||
"CHILD_TOP_UP_MESSAGE": "لقد استلمت {amount} {currency}. الرصيد الإجمالي: {balance} {currency}",
|
||||
"CHILD_TOP_UP_TITLE": "تم إضافة الأموال",
|
||||
"CHILD_TOP_UP_MESSAGE": "تم إضافة {amount} {currency} إلى بطاقتك. الرصيد الإجمالي: {balance} {currency}",
|
||||
"CHILD_SPENDING_TITLE": "تمت العملية بنجاح",
|
||||
"CHILD_SPENDING_MESSAGE": "لقد أنفقت {amount} {currency} في {merchant}. الرصيد: {balance} {currency}",
|
||||
"PARENT_TOP_UP_TITLE": "تأكيد الشحن",
|
||||
"PARENT_TOP_UP_MESSAGE": "لقد قمت بتحويل {amount} {currency} إلى {childName}. الرصيد: {balance} {currency}",
|
||||
"PARENT_SPENDING_TITLE": "تنبيه إنفاق الطفل",
|
||||
"PARENT_SPENDING_MESSAGE": "أنفق {childName} {amount} {currency} في {merchant}. الرصيد: {balance} {currency}",
|
||||
"CHILD_SPENDING_MESSAGE": "لقد أنفقت {amount} {currency} في {merchant}",
|
||||
"PARENT_TOP_UP_TITLE": "اكتمل التحويل",
|
||||
"PARENT_TOP_UP_MESSAGE": "تم تحويل {amount} {currency} إلى بطاقة {childName}. رصيد {childName} هو {balance} {currency}",
|
||||
"PARENT_SPENDING_TITLE": "تنبيه الإنفاق",
|
||||
"PARENT_SPENDING_MESSAGE": "أنفق {childName} {amount} {currency} في {merchant}. الرصيد المتبقي: {balance} {currency}",
|
||||
"YOUR_CHILD": "طفلك",
|
||||
"MONEY_REQUEST_CREATED_TITLE": "طلب مال",
|
||||
"MONEY_REQUEST_CREATED_MESSAGE": "طلب {childName} مبلغ {amount} {currency}. السبب: {reason}",
|
||||
"MONEY_REQUEST_CREATED_MESSAGE": "طلب {childName} مبلغ {amount} {currency} لـ {reason}.",
|
||||
"MONEY_REQUEST_APPROVED_TITLE": "تمت الموافقة على طلب المال",
|
||||
"MONEY_REQUEST_APPROVED_MESSAGE": "تمت الموافقة على طلبك بمبلغ {amount} {currency}. تمت إضافة المال إلى حسابك.",
|
||||
"MONEY_REQUEST_DECLINED_TITLE": "تم رفض طلب المال",
|
||||
|
||||
@ -111,17 +111,17 @@
|
||||
"NOT_FOUND": "The card was not found."
|
||||
},
|
||||
"NOTIFICATION": {
|
||||
"CHILD_TOP_UP_TITLE": "Card Topped Up",
|
||||
"CHILD_TOP_UP_MESSAGE": "You received {amount} {currency}. Total balance: {balance} {currency}",
|
||||
"CHILD_TOP_UP_TITLE": "Funds Credited",
|
||||
"CHILD_TOP_UP_MESSAGE": "{amount} {currency} has been added to your card. Total balance: {balance} {currency}",
|
||||
"CHILD_SPENDING_TITLE": "Purchase Successful",
|
||||
"CHILD_SPENDING_MESSAGE": "You spent {amount} {currency} at {merchant}. Balance: {balance} {currency}",
|
||||
"PARENT_TOP_UP_TITLE": "Top-Up Confirmation",
|
||||
"PARENT_TOP_UP_MESSAGE": "You transferred {amount} {currency} to {childName}. Balance: {balance} {currency}",
|
||||
"PARENT_SPENDING_TITLE": "Child Spending Alert",
|
||||
"PARENT_SPENDING_MESSAGE": "{childName} spent {amount} {currency} at {merchant}. Balance: {balance} {currency}",
|
||||
"CHILD_SPENDING_MESSAGE": "You spent {amount} {currency} at {merchant}",
|
||||
"PARENT_TOP_UP_TITLE": "Transfer Completed",
|
||||
"PARENT_TOP_UP_MESSAGE": "{amount} {currency} has been transferred to {childName}'s card. {childName}'s balance is {balance} {currency}",
|
||||
"PARENT_SPENDING_TITLE": "Spending Alert",
|
||||
"PARENT_SPENDING_MESSAGE": "{childName} spent {amount} {currency} at {merchant}. Remaining balance: {balance} {currency}",
|
||||
"YOUR_CHILD": "Your child",
|
||||
"MONEY_REQUEST_CREATED_TITLE": "Money Request",
|
||||
"MONEY_REQUEST_CREATED_MESSAGE": "{childName} requested {amount} {currency}. Reason: {reason}",
|
||||
"MONEY_REQUEST_CREATED_MESSAGE": "{childName} has requested {amount} {currency} for {reason}.",
|
||||
"MONEY_REQUEST_APPROVED_TITLE": "Money Request Approved",
|
||||
"MONEY_REQUEST_APPROVED_MESSAGE": "Your request for {amount} {currency} has been approved. The money has been added to your account.",
|
||||
"MONEY_REQUEST_DECLINED_TITLE": "Money Request Declined",
|
||||
|
||||
Reference in New Issue
Block a user