#911: CurrencyConversionService.kt
projectforge-business/src/main/kotlin/org/projectforge/business/fibu/CurrencyConversionService.kt
Type: Spring Service
Package: org.projectforge.business.fibu
Path: projectforge-business/src/main/kotlin/org/projectforge/business/fibu/CurrencyConversionService.kt
Author: Kai Reinhard (k.reinhard@micromata.de)
254 lines · 129 code · 102 comments · 23 blank
The public-facing service for currency conversion operations. Delegates database read/write operations to CurrencyConversionServiceSupport and caching to CurrencyConversionCache. Provides a high-level convert() method that handles same-currency no-op, bidirectional pair lookup, rate retrieval, and multiplication in a single call. Exposes a static singleton via the companion object.
Architecture
Dependencies
| Dependency | Role |
CurrencyPairDao | Access control & currency pair lookup for rate CRUD |
CurrencyConversionCache | In-memory cached lookup of pairs, rates, and active rate dates |
CurrencyConversionServiceSupport | Internal database operations (find, insert, update, delete, validate) |
ConfigurationService | Provides system default currency (e.g. "EUR") |
Method Categories
Rate Query Operations
| Method | Description |
findRate(id) | Find a single rate by id, delegates to support class |
selectAllRates(pairId) | List rates; uses cache for active, DB for deleted rates |
getConversionRate(pair, date) | Get the numeric rate factor for a pair at a date |
getConversionRateDate(pair, date) | Get the validFrom date of the active rate |
Conversion
| Method | Description |
convert(amount, target, source?, date?, scale?, rounding?) | Core method. Converts an amount between currencies. Same-currency returns unchanged. Uses default system currency when sourceCurrency is null. Supports configurable scale and rounding mode. Optionally falls back to oldest rate (with compliance caveats). |
Rate CRUD Operations
| Method | Description |
validateRate(rate) | Validates uniqueness; returns error message string or null |
insertRate(pairId, rate) | Insert a new rate for a currency pair |
updateRate(pairId, rate) | Update an existing rate |
markRateAsDeleted(pairId, rateId) | Soft-delete a rate |
Conversion Flow
- Null/blank guards on
amount and targetCurrency
- Resolve effective source currency (parameter or system default)
- Same-currency check: return amount unchanged with scale applied
- Bidirectional pair lookup via
cache.findCurrencyPairForConversion()
- Get rate from cache (applying inverse if lookup found the reverse pair)
amount * rate → scale with rounding mode
Lifecycle
@PostConstruct stores the singleton in Companion.instance for static access by other services (e.g., statistical calculations).
Git History
868d6abb7 2025 -> 2026
f4a839e3a CurrencyConversion: Show date of active rates in list view.
472fbc977 WIP: currency conversion with Claude Code.
75ea9dc1a WIP: currency conversion with Claude Code.
abdac2e1b WIP: currency conversion with Claude Code.
07edc85de WIP: currency conversion with Claude Code.
e1323795d WIP: currency conversion with Claude Code.
2d79ded16 WIP: currency conversion with Claude Code.
357ebee61 WIP: currency conversion with Claude Code.
bd69407de Initial revision with Claude Code.