From b9b814bf71fe632eec3d77ce00c25c2a32af6fe1 Mon Sep 17 00:00:00 2001 From: barsa Date: Mon, 29 Sep 2025 13:40:08 +0900 Subject: [PATCH] Refactor currency handling in WHMCS integration services. Update WhmcsCurrencyService to ensure proper type casting for currency responses. Clean up formatting in InvoiceTransformerService and SubscriptionTransformerService for improved readability. Simplify logic in InvoiceItems component by removing debug logging. Enhance currency formatting in SubscriptionDetail and SubscriptionsList components for consistency. --- .../whmcs/services/whmcs-currency.service.ts | 2 +- .../services/invoice-transformer.service.ts | 11 +++--- .../subscription-transformer.service.ts | 3 +- .../components/InvoiceDetail/InvoiceItems.tsx | 34 +++++++++---------- .../views/SubscriptionDetail.tsx | 5 ++- .../subscriptions/views/SubscriptionsList.tsx | 5 ++- 6 files changed, 33 insertions(+), 27 deletions(-) diff --git a/apps/bff/src/integrations/whmcs/services/whmcs-currency.service.ts b/apps/bff/src/integrations/whmcs/services/whmcs-currency.service.ts index 1b55be88..cd175ce4 100644 --- a/apps/bff/src/integrations/whmcs/services/whmcs-currency.service.ts +++ b/apps/bff/src/integrations/whmcs/services/whmcs-currency.service.ts @@ -68,7 +68,7 @@ export class WhmcsCurrencyService implements OnModuleInit { */ private async loadCurrencies(): Promise { try { - const response: WhmcsCurrenciesResponse = await this.connectionService.getCurrencies(); + const response = (await this.connectionService.getCurrencies()) as WhmcsCurrenciesResponse; if (response.result === "success" && response.currencies?.currency) { this.currencies = response.currencies.currency; diff --git a/apps/bff/src/integrations/whmcs/transformers/services/invoice-transformer.service.ts b/apps/bff/src/integrations/whmcs/transformers/services/invoice-transformer.service.ts index e0327d2c..fb6dabfd 100644 --- a/apps/bff/src/integrations/whmcs/transformers/services/invoice-transformer.service.ts +++ b/apps/bff/src/integrations/whmcs/transformers/services/invoice-transformer.service.ts @@ -37,10 +37,11 @@ export class InvoiceTransformerService { // Use WHMCS system default currency if not provided in invoice const defaultCurrency = this.currencyService.getDefaultCurrency(); const currency = whmcsInvoice.currencycode || defaultCurrency.code; - const currencySymbol = whmcsInvoice.currencyprefix || - whmcsInvoice.currencysuffix || - defaultCurrency.prefix || - defaultCurrency.suffix; + const currencySymbol = + whmcsInvoice.currencyprefix || + whmcsInvoice.currencysuffix || + defaultCurrency.prefix || + defaultCurrency.suffix; const invoice: Invoice = { id: Number(invoiceId), @@ -109,7 +110,7 @@ export class InvoiceTransformerService { // Add service ID from relid field // In WHMCS: relid > 0 means linked to service, relid = 0 means one-time item - if (typeof item.relid === 'number' && item.relid > 0) { + if (typeof item.relid === "number" && item.relid > 0) { transformedItem.serviceId = item.relid; } diff --git a/apps/bff/src/integrations/whmcs/transformers/services/subscription-transformer.service.ts b/apps/bff/src/integrations/whmcs/transformers/services/subscription-transformer.service.ts index 3efa59c0..09af9aea 100644 --- a/apps/bff/src/integrations/whmcs/transformers/services/subscription-transformer.service.ts +++ b/apps/bff/src/integrations/whmcs/transformers/services/subscription-transformer.service.ts @@ -41,7 +41,7 @@ export class SubscriptionTransformerService { // Use WHMCS system default currency const defaultCurrency = this.currencyService.getDefaultCurrency(); - + const subscription: Subscription = { id: Number(whmcsProduct.id), serviceId: Number(whmcsProduct.id), // In WHMCS, product ID is the service ID @@ -100,7 +100,6 @@ export class SubscriptionTransformerService { return recurringAmount > 0 ? recurringAmount : firstPaymentAmount; } - /** * Extract and normalize custom fields from WHMCS format */ diff --git a/apps/portal/src/features/billing/components/InvoiceDetail/InvoiceItems.tsx b/apps/portal/src/features/billing/components/InvoiceDetail/InvoiceItems.tsx index 2d33f3cc..b70e31b6 100644 --- a/apps/portal/src/features/billing/components/InvoiceDetail/InvoiceItems.tsx +++ b/apps/portal/src/features/billing/components/InvoiceDetail/InvoiceItems.tsx @@ -12,17 +12,13 @@ interface InvoiceItemsProps { export function InvoiceItems({ items = [], currency }: InvoiceItemsProps) { const hasServiceConnection = (item: InvoiceItem) => { - const hasConnection = Boolean(item.serviceId) && Number(item.serviceId) > 0; - // Debug logging - remove this after fixing the issue - console.log('Invoice item debug:', { - id: item.id, - description: item.description?.substring(0, 50), - serviceId: item.serviceId, - hasConnection - }); - return hasConnection; + return Boolean(item.serviceId) && Number(item.serviceId) > 0; }; + // Calculate what types of items are actually present + const hasLinkedItems = items.some(item => hasServiceConnection(item)); + const hasOneTimeItems = items.some(item => !hasServiceConnection(item)); + const renderItemContent = (item: InvoiceItem, index: number) => { const isLinked = hasServiceConnection(item); @@ -109,14 +105,18 @@ export function InvoiceItems({ items = [], currency }: InvoiceItemsProps) {

Items & Services

-
-
- Linked to service -
-
-
- One-time item -
+ {hasLinkedItems && ( +
+
+ Linked to service +
+ )} + {hasOneTimeItems && ( +
+
+ One-time item +
+ )}
diff --git a/apps/portal/src/features/subscriptions/views/SubscriptionDetail.tsx b/apps/portal/src/features/subscriptions/views/SubscriptionDetail.tsx index a28d38b1..675c3633 100644 --- a/apps/portal/src/features/subscriptions/views/SubscriptionDetail.tsx +++ b/apps/portal/src/features/subscriptions/views/SubscriptionDetail.tsx @@ -127,7 +127,10 @@ export function SubscriptionDetailContainer() { }; const formatCurrency = (amount: number) => - sharedFormatCurrency(amount || 0, { currency: subscription.currency, locale: getCurrencyLocale(subscription.currency) }); + sharedFormatCurrency(amount || 0, { + currency: subscription.currency, + locale: getCurrencyLocale(subscription.currency), + }); const formatBillingLabel = (cycle: string) => { switch (cycle) { diff --git a/apps/portal/src/features/subscriptions/views/SubscriptionsList.tsx b/apps/portal/src/features/subscriptions/views/SubscriptionsList.tsx index 6bf9a0f4..f4199165 100644 --- a/apps/portal/src/features/subscriptions/views/SubscriptionsList.tsx +++ b/apps/portal/src/features/subscriptions/views/SubscriptionsList.tsx @@ -142,7 +142,10 @@ export function SubscriptionsListContainer() { render: (s: Subscription) => (
- {formatCurrency(s.amount, { currency: s.currency, locale: getCurrencyLocale(s.currency) })} + {formatCurrency(s.amount, { + currency: s.currency, + locale: getCurrencyLocale(s.currency), + })}
{s.cycle === "Monthly"