Rule reference

BR-CL-19 The document level allowance at allowances[0] carries the reason code "FC", which is not in UNCL 5189, the list BR-CL-19 admits for allowance reason codes

The document level allowance at allowances[0] carries the reason code "FC", which is not in UNCL 5189, the list BR-CL-19 admits for allowance reason codes. It *is* in the charge list — and that is the trap this rule exists to catch. EN 16931 uses two different code lists for the two directions: allowance reason codes come from UNCL 5189, charge reason codes from UNCL 7161. Moving an entry between the allowances and charges arrays without changing its code turns a valid document into a rejected one, because the same string means something else in the other list. The whole list is short enough to read: "41", "42", "60", "62", "63", "64", "65", "66", "67", "68", "70", "71", "88", "95", "100", "102", "103", "104", "105" — nineteen codes, and none of them is a free-text escape hatch.

This rule is implemented and its error payload below is real, but the long-form write-up — normative text, worked example, divergence note — is not written yet. Everything the library knows about this rule is on this page. Ask and we will prioritise it.

Business term
BT-98
Severity
fatal

What the library returns

The exact object in result.errors when this rule fires. Generated by running @attestwire/en16931, not transcribed:

TeachingError
{
  "rule": "BR-CL-19",
  "field": "BT-98",
  "severity": "fatal",
  "message": "The document level allowance at allowances[0] carries the reason code \"FC\", which is not in UNCL 5189, the list BR-CL-19 admits for allowance reason codes. It *is* in the charge list — and that is the trap this rule exists to catch. EN 16931 uses two different code lists for the two directions: allowance reason codes come from UNCL 5189, charge reason codes from UNCL 7161. Moving an entry between the allowances and charges arrays without changing its code turns a valid document into a rejected one, because the same string means something else in the other list. The whole list is short enough to read: \"41\", \"42\", \"60\", \"62\", \"63\", \"64\", \"65\", \"66\", \"67\", \"68\", \"70\", \"71\", \"88\", \"95\", \"100\", \"102\", \"103\", \"104\", \"105\" — nineteen codes, and none of them is a free-text escape hatch.",
  "fix": "Either set allowances[0].reasonCode to a UNCL 5189 code, or remove it and describe the allowance in allowances[0].reason instead — free text on its own satisfies BR-33 and BR-CO-21, and is better than a code that means the wrong thing.",
  "example": "\"allowances\": [{ \"amount\": 15.00, \"vatCategory\": \"S\", \"vatRate\": 19, \"reasonCode\": \"95\", \"reason\": \"Discount\" }]",
  "xpath": "/ubl:Invoice/cac:AllowanceCharge[1]/cbc:AllowanceChargeReasonCode",
  "docsUrl": "https://attestwire.com/rules/BR-CL-19"
}

xpath locates the element in the generated UBL document, which is where a KoSIT or Peppol validator will report the same problem.

A passing value

the shape this field expects
"allowances": [{ "amount": 15.00, "vatCategory": "S", "vatRate": 19, "reasonCode": "95", "reason": "Discount" }]

The fix

Either set allowances[0].reasonCode to a UNCL 5189 code, or remove it and describe the allowance in allowances[0].reason instead — free text on its own satisfies BR-33 and BR-CO-21, and is better than a code that means the wrong thing.

Arrived from a stack trace? The docsUrl on every error links straight here. Something wrong on this page — tell us.