efrisapi.com

Error codes / 1344

EFRIS error 1344 — summary.taxAmount must include excise duty

summary.taxAmount must equal the sum of every taxDetails[].taxAmount, with no group excluded — and that includes excise duty, which is tax category 05. Leaving excise out of the summary tax returns 1344. The mirror rule is 1345: summary.grossAmount must exclude category 05.

The two rules point in opposite directions. Tax includes excise; gross excludes it. Applying either rule to both fields produces the other error.

Summary fieldRule for tax category 05Code if violated
summary.taxAmountIncludes excise — must equal the sum of every taxDetails.taxAmount1344
summary.grossAmountExcludes category 05 — the excise is already embedded in the standard-rate gross1345
summary.netAmountDerived: grossAmount − taxAmount1343

What URA returns

The rejection arrives in the response envelope with the code in returnStateInfo.returnCode:

{
  "returnStateInfo": {
    "returnCode": "1344",
    "returnMessage": "..."
  }
}

URA rewords returnMessage between releases and some messages come back in mixed language, so branch on returnCode and never on the message text:

from efris import EfrisError

try:
    client.upload_invoice(document)
except EfrisError as exc:
    if exc.code == "1344":
        ...   # add the "05" group's tax back into summary.taxAmount
    raise

Getting either of the excise rules wrong returns only a number, with no indication of which field URA disagreed with, so log the whole decrypted payload on failure and compare your summary against a recomputation from taxDetails.

What it actually means

URA recomputes the summary block from the taxDetails array and rejects any disagreement. 1344 says the tax total does not match. On a document with no excise this is usually an ordinary rounding or double-count bug. On an excisable product it is almost always deliberate: excise was filtered out of the summary tax because it is "not VAT".

The excise group is a real tax group. Its taxAmount is a tax that no other group in taxDetails reports, so if it is not added to summary.taxAmount, the document understates the tax collected and URA refuses it.

The second way to arrive at 1344 is having already fixed 1345. A developer reads that category 05 must be excluded from grossAmount, applies the exclusion to the whole summary calculation in one filter, and turns a gross error into a tax error.

The fix

Filter category 05 out of the gross sum only. Sum the tax across every group.

def summary_amounts(tax_details):
    """Summary amounts for an EFRIS document that may carry excise duty.

    taxAmount   - every group, category "05" INCLUDED   (else 1344)
    grossAmount - every group EXCEPT category "05"      (else 1345)
    netAmount   - derived from those two                (else 1343)
    """
    tax_amount = sum(float(td["taxAmount"]) for td in tax_details)

    gross_amount = sum(
        float(td["grossAmount"])
        for td in tax_details
        if str(td.get("taxCategoryCode", "")) != "05"
    )

    net_amount = gross_amount - tax_amount

    return {
        "netAmount": f"{net_amount:.2f}",
        "taxAmount": f"{tax_amount:.2f}",
        "grossAmount": f"{gross_amount:.2f}",
    }


document["summary"].update(summary_amounts(document["taxDetails"]))

Note that the 05 filter appears exactly once, on the gross sum. Amounts are transmitted as JSON strings, so format them to two decimal places.

On a credit note the same arithmetic applies with every amount negated: qty, total, tax, all taxDetails amounts and all summary amounts are negative, while unitPrice and payWay.paymentAmount stay positive. A credit note against an excisable product must also mirror the invoice's excise fields (1462) and carry a non-empty taxRateName on the 05 group (2831).

Why this happens

Excise duty is charged on the product itself, and the resulting amount is already contained in the value the standard-rate group reports as its gross. The 05 group exists to declare that duty separately, not to add value to the document.

That single fact explains both rules at once. Because the duty is a tax that only the 05 group reports, it must be added into summary.taxAmount — otherwise the tax total is short by the excise. Because the value it sits inside has already been counted by the standard-rate group, its grossAmount must not be added into summary.grossAmount — otherwise the excisable value is counted twice. summary.netAmount is then derived from those two figures, so the net = gross − tax identity behind 1343 continues to hold on an excise document even though the per-group nets no longer sum to it.

If your excise duty code carries a unit rate — shillings per litre, for example — rather than a percentage, the goods line has extra requirements of its own; see 676.

Related errors

The full list, with the fix for each, is at /docs/errors/.

If you would rather not maintain this

The EFRIS API Kit applies both excise rules when it builds the summary, on invoices and credit notes, so 1344 and 1345 do not occur. The arithmetic above is correct whether or not you use it.