Skip to content

NEW Show the exchange difference and allow re-aligning the invoice rate (option MULTICURRENCY_PAYMENT_USE_REAL_AMOUNTS) - #39667

Open
Pichinov-Jose wants to merge 1 commit into
Dolibarr:developfrom
Pichinov-Jose:feat/multicurrency-exchange-difference
Open

NEW Show the exchange difference and allow re-aligning the invoice rate (option MULTICURRENCY_PAYMENT_USE_REAL_AMOUNTS)#39667
Pichinov-Jose wants to merge 1 commit into
Dolibarr:developfrom
Pichinov-Jose:feat/multicurrency-exchange-difference

Conversation

@Pichinov-Jose

@Pichinov-Jose Pichinov-Jose commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Third part of the real-amounts series (builds on #39665 and #39666; independent code paths, reviewable on its own).

What this solves

An invoice in a foreign currency settled at the real amounts (#39665) keeps a residual in the company currency: the difference between the invoice-rate conversion and what was really paid — the realised exchange gain or loss. Today Dolibarr neither shows it nor offers anything to deal with it.

What it adds

Gated by option MULTICURRENCY_PAYMENT_USE_REAL_AMOUNTS (off by default), on the supplier invoice card:

  • next to the exchange rate, the realised exchange difference (foreign amount settled ÷ invoice rate − real company amount paid);
  • an exchange gain/loss line in the totals block, right after "Remainder to pay, original currency" (red on loss, orange on gain, hidden when zero);
  • an opt-in Align button that re-rates the invoice multicurrency_tx to the realised effective rate via setMulticurrencyRate(), so the difference is absorbed — guarded by a confirm dialog and write permission, refused once the invoice is recorded in accountancy; recorded payments and bank entries are left unchanged. A Restore button reverts to the rate before the alignment.
  • No mutation by default: standard accounting settles the foreign debt at face value and books the delta as an FX result. The accounting booking of the difference is deliberately out of scope here.

A generic $morehtmlmulticurrencyrate slot is added to core/tpl/object_currency_amount.tpl.php to host content next to the rate (empty for other callers, no change for them).

NOTE for reviewers: the pre-alignment rate is currently backed up in a per-invoice constant (provisional — an extrafield or a column can replace it if preferred).

Accounting follow-up — input welcome from @eldy and @aspangaro

This PR deliberately stops at measuring and displaying the realised exchange difference (plus the opt-in Align convenience). The proper accounting treatment is a planned follow-up we would like to design with the accountancy maintainers rather than improvise here:

  • booking the realised difference as a financial expense/income (accounts 666/766 in the French chart, or the equivalent per chart) instead of absorbing it into the rate;
  • the timing question: book at payment time, or at period closing / revaluation;
  • the lettering of the company-currency residual on the supplier account.

Our position so far: the invoice keeps its face value in the foreign currency, the payments record the real amounts (#39665), and the company-currency residual is an FX result that belongs to the accountancy module — not to the invoice. The Align button is only an opt-in for users who prefer to absorb the difference before the transfer to accountancy (it is refused after). Scope and design of the booking part are open — happy to adjust or split as you prefer.

Tested

USD/TWD supplier invoices paid at real amounts: difference displayed next to the rate and in the totals, Align absorbs it (foreign balance unchanged, payments untouched), Restore brings the previous rate back, both refused after transfer to accountancy.

Here is a screenshot:
pr39667_exchange_loss_align

…te (option MULTICURRENCY_PAYMENT_USE_REAL_AMOUNTS)

On a supplier invoice in a foreign currency settled at the real amounts,
the company-currency value of what was paid differs from the invoice-rate
conversion: that gap is the realised exchange gain or loss.

- next to the exchange rate, show the realised exchange difference
  (foreign settled / invoice rate - real company amount paid);
- an opt-in 'Align' button re-rates the invoice multicurrency_tx to the
  realised effective rate via setMulticurrencyRate() so the difference is
  absorbed; guarded by a confirm dialog, write permission, and refused
  once the invoice is recorded in accountancy; recorded payments and bank
  entries are left unchanged; a 'Restore' button reverts to the rate
  before the alignment;
- an exchange gain/loss line is shown after 'Remainder to pay, original
  currency' in the totals block (red on loss, orange on gain);
- a generic $morehtmlmulticurrencyrate slot is added to
  core/tpl/object_currency_amount.tpl.php to host content next to the
  rate (empty for other callers, no change);
- no mutation by default: standard accounting settles the foreign debt at
  face value, the delta is an FX result. The accounting booking of the
  difference is out of scope here.

NOTE for reviewers: the pre-alignment rate is currently backed up in a
per-invoice constant (provisional, to be replaced by an extrafield or a
column if preferred).
@Pichinov-Jose
Pichinov-Jose force-pushed the feat/multicurrency-exchange-difference branch from 33537e9 to aa4b977 Compare August 22, 2026 19:01
@Pichinov-Jose
Pichinov-Jose marked this pull request as ready for review August 22, 2026 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant