invoice.currency.exchange
Foreign-currency documents need a complete <Currency> block
When a document declares a non-EUR currency, CurrencyCode + CurrencyAmount + ExchangeRate must all be present.
What this checks
A document issued in a currency other than the euro carries a <Currency> block inside its <DocumentTotals>. The block has three children, all required:
CurrencyCode: the ISO 4217 code of the original currency (for exampleUSD,GBP,BRL).CurrencyAmount: the document's gross total in that currency.ExchangeRate: the rate used to convert the document to euros.
SAFTCheck checks invoices (Invoice), working documents (WorkDocument) and receipts (Payment). The rule fires when any of the three is missing or empty, or when ExchangeRate is not a number greater than zero.
A correct example
An invoice of 1,000.00 USD converted at 0.92, so the totals in euros are 920.00:
<DocumentTotals>
<TaxPayable>0.00</TaxPayable>
<NetTotal>920.00</NetTotal>
<GrossTotal>920.00</GrossTotal>
<Currency>
<CurrencyCode>USD</CurrencyCode>
<CurrencyAmount>1000.00</CurrencyAmount>
<ExchangeRate>0.92</ExchangeRate>
</Currency>
</DocumentTotals>
All amounts elsewhere in the document (lines, NetTotal, GrossTotal) stay in euros. Only CurrencyAmount is in the original currency.
Why it matters
AT works in euros: VAT and the SAF-T totals are all in EUR, and the rate is how a foreign-currency document is tied back to them. The official schema already requires all three children whenever the block is present, so a missing element also shows up as a schema error. That error is hard to read, though, and the schema accepts an ExchangeRate of 0, which can never be right. This rule names the document and the missing field instead.
Examples
| Currency block | Verdict |
|---|---|
USD / 1000.00 / 0.92 | ✓ |
USD / 1000.00 / 0 | ✗ ExchangeRate must be greater than 0 |
USD / 1000.00 / (missing) | ✗ ExchangeRate missing |
USD / (empty) / 0.92 | ✗ CurrencyAmount missing |
EUR / 920.00 / 1 | ✗ Schema error: EUR is not an allowed code, because euro documents must not have a Currency block |
| (no Currency block) | ✓ Euro document, the rule doesn't apply |
Common causes
- The ERP writes a Currency block for every document, including euro ones, with
EURand a rate of 1. The schema only allows foreign currency codes here, so the block has to go. - The rate wasn't recorded when the document was issued (often for manually created invoices or documents imported from another system), so the export writes an empty or zero rate.
- Customer currency confused with document currency: a foreign customer billed in euros does not need a Currency block.
How to fix
- If the document really is in a foreign currency, record the exchange rate on the document in your ERP (the Banco de Portugal publishes daily reference rates) and export again.
- If the document is in euros, change the ERP's export setting so it doesn't write a
<Currency>block for euro documents.
On the result page, the finding shows which document it is (for example Invoice[12].Currency) and which fields are missing or invalid.
Related
- Totals reconciliation: block totals are compared in euros.
- AT SAF-T error messages explained: "Ficheiro inválido", "Rejeitado" and cvc- errors