Error codes / 1304
EFRIS error 1304 — summary.itemCount does not match the product lines
URA rejected the document because summary.itemCount is not equal to the number of
product lines in goodsDetails. A discount is its own entry in
goodsDetails, marked discountFlag: "0", and it is not a product line. Set
summary.itemCount to len(goodsDetails) minus the number of entries whose
discountFlag is "0".
One-line fix. An invoice with three products and one discount has four
goodsDetails entries and "itemCount": "3".
What URA returns
The rejection arrives in the response envelope with the code in returnStateInfo.returnCode:
{
"returnStateInfo": {
"returnCode": "1304",
"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 == "1304":
... # recompute summary.itemCount, then resubmit
raise
A batch can also be partly accepted. When that happens the envelope still says
returnCode "00" and the per-item status sits inside the decrypted payload, surfaced as
EfrisValidationError.failures. Treating HTTP 200 plus 00 as success silently loses
invoices.
What it actually means
EFRIS models a discount as a line, not as a field on the line it discounts. The discount occupies its own
entry in the goodsDetails array, carrying discountFlag: "0", so that the reduction
is attributable to a specific product. It is an adjustment to the line above it, not something sold.
URA recomputes the item count from goodsDetails, counting product lines only, and rejects the
document if your summary.itemCount disagrees. Sending len(goodsDetails) — the
obvious thing to send — is therefore wrong on every invoice that carries a discount, and correct on every
invoice that does not. That is why 1304 usually appears late, on the first discounted sale in production,
after the integration has been working for weeks.
The fix
Compute itemCount from the goodsDetails array you are about to transmit,
immediately before building the summary. Any entry whose discountFlag is absent, or is any value
other than "0", counts as a product line.
def summary_item_count(goods_details):
"""Number of product lines, for summary.itemCount (EFRIS error 1304).
A discount line carries discountFlag "0". It is an adjustment to the line
above it, not a product, and URA does not count it.
"""
discount_lines = sum(
1 for g in goods_details
if str(g.get("discountFlag", "2")) == "0"
)
return len(goods_details) - discount_lines
document["summary"]["itemCount"] = str(summary_item_count(document["goodsDetails"]))
Serialise the result as a string. EFRIS transmits numeric fields as JSON strings, so
"itemCount": "3" is correct and "itemCount": 3 is not.
Credit notes inherit the problem. A credit note mirrors the lines of the invoice it
reverses, so a credit note against a discounted invoice carries the discount line too, and needs the same
subtraction. Quantities and amounts on a credit note are negative; itemCount is a count of lines
and stays positive.
Why this happens
summary is not data URA stores on trust. URA recomputes every field in it from
goodsDetails and taxDetails and rejects any disagreement — that recomputation is
the single largest source of first-integration rejections. itemCount is the count half of that
check; 1343, 1344 and
1345 are the arithmetic half.
The count is of items sold, which is why the discount line is excluded: it reduces the value of a product line that has already been counted. Once you see the summary as a checksum over the lines rather than as a header you fill in, the rule stops being arbitrary — and the general habit follows, which is to derive every summary field from the transmitted arrays at the last possible moment, rather than carrying totals down from your own order model.
Related errors
- 1343 netAmount mismatch —
netAmountmust equalgrossAmount − taxAmount, derived from the convertedtaxDetails. - 1344 taxAmount mismatch —
summary.taxAmountmust include excise duty, tax category05. - 1345 grossAmount mismatch —
summary.grossAmountmust exclude tax category05. The mirror of 1344.
The full list, with the fix for each, is at /docs/errors/.
If you would rather not maintain this
The EFRIS API Kit computes summary.itemCount from the transmitted
goodsDetails on invoices and credit notes, so 1304 does not occur. The rule above is correct
whether or not you use it.