From 21ff7c20ede6ba160c457b97e609d86d3c0556ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20G=C3=BCnther?= Date: Fri, 21 Nov 2025 15:18:25 +0100 Subject: [PATCH] use map for derivedCurrencies to improve efficiency --- CHANGELOG.md | 6 ++++ .../exchange-rate-data.service.ts | 33 +++++++------------ 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ca25a5a1..3458ab630 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fixed exchange rate conversion errors when converting between derived currencies (e.g., GBp) and their root currencies (e.g., GBP) by using fixed mathematical factors instead of fetching from external data sources + ## 2.218.0 - 2025-11-20 ### Added diff --git a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts index 2b108cd5d..1b677005d 100644 --- a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts +++ b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts @@ -30,6 +30,7 @@ import ms from 'ms'; export class ExchangeRateDataService { private currencies: string[] = []; private currencyPairs: DataGatheringItem[] = []; + private derivedCurrencyFactors = new Map(); private exchangeRates: { [currencyPair: string]: number } = {}; public constructor( @@ -136,6 +137,13 @@ export class ExchangeRateDataService { this.currencies = await this.prepareCurrencies(); this.currencyPairs = []; this.exchangeRates = {}; + this.derivedCurrencyFactors = new Map(); + + // Initialize derived currencies factor map in both directions + for (const { currency, factor, rootCurrency } of DERIVED_CURRENCIES) { + this.derivedCurrencyFactors.set(`${currency}${rootCurrency}`, 1 / factor); + this.derivedCurrencyFactors.set(`${rootCurrency}${currency}`, factor); + } for (const { currency1, @@ -500,29 +508,10 @@ export class ExchangeRateDataService { 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 + const factor = this.derivedCurrencyFactors.get( + `${currencyFrom}${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; + return factor ?? null; } private async prepareCurrencies(): Promise {