Browse Source

Add logic to detect when converting between a derived currency and its root currency, and apply the fixed mathematical factor directly (0.01 for GBp→GBP, 100 for GBP→GBp) instead of trying to fetch exchange rates.

pull/5961/head
Sven Günther 1 month ago
parent
commit
5e7dd96510
  1. 146
      apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts

146
apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts

@ -271,56 +271,65 @@ export class ExchangeRateDataService {
if (aFromCurrency === aToCurrency) { if (aFromCurrency === aToCurrency) {
factor = 1; factor = 1;
} else { } else {
const dataSource = const derivedCurrencyFactor = this.getDerivedCurrencyFactor(
this.dataProviderService.getDataSourceForExchangeRates(); aFromCurrency,
const symbol = `${aFromCurrency}${aToCurrency}`; aToCurrency
);
const marketData = await this.marketDataService.get({
dataSource,
symbol,
date: aDate
});
if (marketData?.marketPrice) { if (derivedCurrencyFactor !== null) {
factor = marketData?.marketPrice; factor = derivedCurrencyFactor;
} else { } else {
// Calculate indirectly via base currency const dataSource =
this.dataProviderService.getDataSourceForExchangeRates();
const symbol = `${aFromCurrency}${aToCurrency}`;
const marketData = await this.marketDataService.get({
dataSource,
symbol,
date: aDate
});
let marketPriceBaseCurrencyFromCurrency: number; if (marketData?.marketPrice) {
let marketPriceBaseCurrencyToCurrency: number; factor = marketData?.marketPrice;
} else {
// Calculate indirectly via base currency
try { let marketPriceBaseCurrencyFromCurrency: number;
if (aFromCurrency === DEFAULT_CURRENCY) { let marketPriceBaseCurrencyToCurrency: number;
marketPriceBaseCurrencyFromCurrency = 1;
} else {
marketPriceBaseCurrencyFromCurrency = (
await this.marketDataService.get({
dataSource,
date: aDate,
symbol: `${DEFAULT_CURRENCY}${aFromCurrency}`
})
)?.marketPrice;
}
} catch {}
try { try {
if (aToCurrency === DEFAULT_CURRENCY) { if (aFromCurrency === DEFAULT_CURRENCY) {
marketPriceBaseCurrencyToCurrency = 1; marketPriceBaseCurrencyFromCurrency = 1;
} else { } else {
marketPriceBaseCurrencyToCurrency = ( marketPriceBaseCurrencyFromCurrency = (
await this.marketDataService.get({ await this.marketDataService.get({
dataSource, dataSource,
date: aDate, date: aDate,
symbol: `${DEFAULT_CURRENCY}${aToCurrency}` symbol: `${DEFAULT_CURRENCY}${aFromCurrency}`
}) })
)?.marketPrice; )?.marketPrice;
} }
} catch {} } catch {}
// Calculate the opposite direction try {
factor = if (aToCurrency === DEFAULT_CURRENCY) {
(1 / marketPriceBaseCurrencyFromCurrency) * marketPriceBaseCurrencyToCurrency = 1;
marketPriceBaseCurrencyToCurrency; } else {
marketPriceBaseCurrencyToCurrency = (
await this.marketDataService.get({
dataSource,
date: aDate,
symbol: `${DEFAULT_CURRENCY}${aToCurrency}`
})
)?.marketPrice;
}
} catch {}
// Calculate the opposite direction
factor =
(1 / marketPriceBaseCurrencyFromCurrency) *
marketPriceBaseCurrencyToCurrency;
}
} }
} }
@ -357,7 +366,25 @@ export class ExchangeRateDataService {
for (const date of dates) { for (const date of dates) {
factors[format(date, DATE_FORMAT)] = 1; factors[format(date, DATE_FORMAT)] = 1;
} }
} else { return factors;
}
// Check if this is a conversion between a derived currency and its root currency
const derivedCurrencyFactor = this.getDerivedCurrencyFactor(
currencyFrom,
currencyTo
);
if (derivedCurrencyFactor !== null) {
// Use the fixed mathematical factor for derived currencies
for (const date of dates) {
factors[format(date, DATE_FORMAT)] = derivedCurrencyFactor;
}
return factors;
}
// Continue with standard exchange rate logic
{
const dataSource = const dataSource =
this.dataProviderService.getDataSourceForExchangeRates(); this.dataProviderService.getDataSourceForExchangeRates();
const symbol = `${currencyFrom}${currencyTo}`; const symbol = `${currencyFrom}${currencyTo}`;
@ -469,6 +496,35 @@ export class ExchangeRateDataService {
return factors; return factors;
} }
private getDerivedCurrencyFactor(
currencyFrom: string,
currencyTo: string
): number | null {
// Check if currencyFrom is a derived currency of currencyTo
const derivedFrom = DERIVED_CURRENCIES.find(
({ currency, rootCurrency }) =>
currency === currencyFrom && rootCurrency === currencyTo
);
if (derivedFrom) {
// e.g., GBp → GBP: factor = 1/100 = 0.01
return 1 / derivedFrom.factor;
}
// Check if currencyTo is a derived currency of currencyFrom
const derivedTo = DERIVED_CURRENCIES.find(
({ currency, rootCurrency }) =>
currency === currencyTo && rootCurrency === currencyFrom
);
if (derivedTo) {
// e.g., GBP → GBp: factor = 100
return derivedTo.factor;
}
return null;
}
private async prepareCurrencies(): Promise<string[]> { private async prepareCurrencies(): Promise<string[]> {
let currencies: string[] = [DEFAULT_CURRENCY]; let currencies: string[] = [DEFAULT_CURRENCY];

Loading…
Cancel
Save