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.

This commit is contained in:
barsa 2025-09-29 13:40:08 +09:00
parent 14b0b75c9a
commit b9b814bf71
6 changed files with 33 additions and 27 deletions

View File

@ -68,7 +68,7 @@ export class WhmcsCurrencyService implements OnModuleInit {
*/
private async loadCurrencies(): Promise<void> {
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;

View File

@ -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;
}

View File

@ -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
*/

View File

@ -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) {
<div className="flex items-center justify-between">
<h3 className="text-lg font-semibold text-slate-900">Items & Services</h3>
<div className="flex items-center gap-4 text-xs text-slate-500">
<div className="flex items-center gap-1">
<div className="w-2 h-2 bg-green-500 rounded-full"></div>
<span>Linked to service</span>
</div>
<div className="flex items-center gap-1">
<div className="w-2 h-2 bg-slate-400 rounded-full"></div>
<span>One-time item</span>
</div>
{hasLinkedItems && (
<div className="flex items-center gap-1">
<div className="w-2 h-2 bg-green-500 rounded-full"></div>
<span>Linked to service</span>
</div>
)}
{hasOneTimeItems && (
<div className="flex items-center gap-1">
<div className="w-2 h-2 bg-slate-400 rounded-full"></div>
<span>One-time item</span>
</div>
)}
</div>
</div>
</div>

View File

@ -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) {

View File

@ -142,7 +142,10 @@ export function SubscriptionsListContainer() {
render: (s: Subscription) => (
<div>
<span className="text-sm font-medium text-gray-900">
{formatCurrency(s.amount, { currency: s.currency, locale: getCurrencyLocale(s.currency) })}
{formatCurrency(s.amount, {
currency: s.currency,
locale: getCurrencyLocale(s.currency),
})}
</span>
<div className="text-xs text-gray-500">
{s.cycle === "Monthly"