Exchange rates: convert for a form or a report
Updated
Books stay in two columns: contract Amount and legal-entity AmountFunc.
A form, a print layout or a turnover script that must show the same money in
a third currency calls ICurrencyRateService.ConvertMoneyAsync. It does not
write registers.
For the analyst: exchange differences.
Two doors on the same service#
| Method | Returns | Use |
|---|---|---|
ConvertAsync(amount, from, to, date) |
decimal? |
posting: AmountFunc, a journal factor |
FactorAsync(from, to, date) |
decimal? |
a tx script that only multiplies |
ConvertMoneyAsync(amount, from, to, date) |
{ Amount, Currency, Code, Symbol } or null |
form, print, report |
DisplayAsync(currency) |
{ Code, Symbol } or null |
glyph without converting |
ConvertMoneyAsync is ConvertAsync rounded to AmountScale (default 2,
MidpointRounding.AwayFromZero) plus the target currency's Code and
Symbol. Empty Symbol on the currency card is lawful: the dictionary
value in the result is then Code.
No rate window on that date → null, never 1. Identity (from == to)
returns the amount and does not read ExchangeRate.
Do not put a DTO in the contract: the composite is Dictionary<string, object?>.
Call from a form, a print layout, a test#
var money = await GetService<ICurrencyRateService>()
.ConvertMoneyAsync(amount, fromCurrency, toCurrency, onDate);
if (money is null) return; // no window — the caller decides whether to refuse
var shown = money["Amount"]; // decimal, already scaled
var glyph = (string)money["Symbol"]!;
A custom form HTML node with allowServices: ["CurrencyRateService"] reaches
the same method through callService.
The date has no default. A turnover for June uses 30 June (or the day the
reader picked), not DateTime.UtcNow.
What not to convert#
Do not sum mixed-currency Amount and then convert the total. Convert a slice
that is already one currency:
- one contract's
Receivable.Amount, or AmountFunc(already the legal entity's currency), then to the reporting currency.
The register totals tab does not pick a reporting currency. A layout that needs
one calls the service per row (or once on AmountFunc of the whole report).
Same topic for other readers: Analyst · User