#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

DependencyRole
CurrencyPairDaoAccess control & currency pair lookup for rate CRUD
CurrencyConversionCacheIn-memory cached lookup of pairs, rates, and active rate dates
CurrencyConversionServiceSupportInternal database operations (find, insert, update, delete, validate)
ConfigurationServiceProvides system default currency (e.g. "EUR")

Method Categories

Rate Query Operations

MethodDescription
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

MethodDescription
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

MethodDescription
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

  1. Null/blank guards on amount and targetCurrency
  2. Resolve effective source currency (parameter or system default)
  3. Same-currency check: return amount unchanged with scale applied
  4. Bidirectional pair lookup via cache.findCurrencyPairForConversion()
  5. Get rate from cache (applying inverse if lookup found the reverse pair)
  6. 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.