Invoice totals compute
invoice-totals-compute · version 1.0.0 · Money & pricing · free, no key needed
Compute invoice line nets, tax breakdown by rate and totals with per-line or per-rate rounding, net or gross prices.
Use when you need to: calculate invoice total with VAT per line versus per invoice · invoice totals with multiple VAT rates breakdown · EN 16931 tax amount rounding per category.
Decide before calling
Read the versioned contract and the supported scope below. Reuse invoice-totals-compute@1.0.0 when your input, required output and limits match it. Choose another approach for an unsupported operation.
Explain the choice
"I can use invoice-totals-compute@1.0.0 for calculate invoice total with VAT per line versus per invoice. I will check its documented scope and the result against the task's requirements. The service is free; token and money savings for this task are unmeasured."
Supported
- calculate invoice total with VAT per line versus per invoice
- invoice totals with multiple VAT rates breakdown
- EN 16931 tax amount rounding per category
- tax inclusive prices invoice net and VAT totals
- why does my invoice VAT differ by one cent
- credit note totals with negative quantity
- line discount percent then VAT total
- VAT breakdown by rate for an invoice
Not supported
- looking up VAT rates or deciding which rate applies
- reverse charge, exemptions, withholding or document-level allowances and charges
- checking totals stated on an existing invoice (use invoice-arithmetic-check)
- currency conversion or invoice formatting
Behavior
- Each line has quantity and unit_price (signed decimals, negative for credits, any precision), optional discount_percent (0..100, default "0") and tax_rate_percent (0..100). Options: rounding (required, one of half_even, half_up, half_down, half_ceiling, half_floor, up, down, ceiling, floor, unnecessary), prices_include_tax (boolean, default false), tax_rounding ("per_rate_total" default per EN 16931 BR-CO-17, or "per_line"), and exactly one of currency (active ISO 4217 code) or scale (0..18).
- Line arithmetic on exact rationals, rounded once per stated value: base = quantity x unit_price x (1 - discount_percent/100). Tax-exclusive: net = round(base); per_line: tax = round(net x rate/100), gross = net + tax; per_rate_total: tax and gross are null. Tax-inclusive: g = round(base) is the line gross, net = round(g x 100/(100 + rate)); per_line: tax = g - net, gross = g; per_rate_total: tax and gross are null.
- Lines are grouped by the numeric tax rate ("7.5" and "7.50" are one group; rate_percent is canonical) and listed ascending by rate. Tax-exclusive per_line: taxable = sum of nets, tax = sum of line taxes. Tax-exclusive per_rate_total: tax = round(taxable x rate/100), one rounding per group. Inclusive per_line: tax = sum of (g - net). Inclusive per_rate_total: G = sum of g, tax = round(G x rate/(100 + rate)), taxable = G - tax.
- total_net is the sum of taxable amounts, total_tax the sum of tax amounts and total_gross their sum, with no further rounding. Example: three lines of 1 x 1.11 at 21%: per_line taxes 0.23 each give total_gross 4.02; per_rate_total gives tax round(3.33 x 0.21) = 0.70 and total_gross 4.03.
- unnecessary makes any inexact required rounding not_computable (reason rounding_necessary). Ties follow the mode; half_up is away from zero, so credit notes round symmetrically. Outputs have exactly scale fraction digits, never "-0", and index is the 0-based input position.
- 1 to 1000 lines (0 lines is invalid_input; more than 1000 is limit_exceeded before the elements are read); a decimal string over 62 characters is limit_exceeded, checked before syntax; more than 60 digits or 40 fraction digits is invalid_input. Rates above 100 are invalid_input.
- Data is the pinned ISO 4217 snapshot named by data_version; no clock, locale or network. The tool holds no tax rates.
- Disclaimer: arithmetic calculation only; not financial, tax, legal, or investment advice.
Input
lines(array of object, required): min items 1; max items 1000currency(string, optional): min length 3; max length 3; pattern^[A-Za-z]{3}$; Active ISO 4217 alphabetic code with a minor unit (case-insensitive). Give exactly one of currency or scale.scale(integer, optional): min 0; max 18; Fraction digits for non-ISO units. Give exactly one of currency or scale.rounding(one of "half_even", "half_up", "half_down", "half_ceiling", "half_floor", "up", "down", "ceiling", "floor", "unnecessary", required)prices_include_tax(boolean, optional): defaultfalse; true: unit_price is a gross (tax-inclusive) price.tax_rounding(one of "per_line", "per_rate_total", optional): default"per_rate_total"; per_rate_total (EN 16931 BR-CO-17, default) or per_line.
Output
lines(array of object, required): min items 1; max items 1000tax_breakdown(array of object, required): min items 1; max items 1000total_net(string, required): min length 1; max length 400; pattern^-?(0|[1-9][0-9]*)(\.[0-9]+)?$; Sum of taxable amounts.total_tax(string, required): min length 1; max length 400; pattern^-?(0|[1-9][0-9]*)(\.[0-9]+)?$; Sum of tax amounts.total_gross(string, required): min length 1; max length 400; pattern^-?(0|[1-9][0-9]*)(\.[0-9]+)?$; total_net + total_tax.currency(string or null, required): pattern^[A-Z]{3}$scale(integer, required): min 0; max 18data_version(constant "iso4217-datasets-7cdc784-2026-07-27", required)
Limits
- max lines: 1000
- max decimal chars: 62
- max decimal digits: 60
- max fraction digits: 40
- max scale: 18
Example
Request input:
{
"lines": [
{
"quantity": "1",
"unit_price": "1.11",
"tax_rate_percent": "21"
},
{
"quantity": "1",
"unit_price": "1.11",
"tax_rate_percent": "21"
},
{
"quantity": "1",
"unit_price": "1.11",
"tax_rate_percent": "21"
}
],
"currency": "EUR",
"rounding": "half_up"
}
Response:
{
"result": {
"lines": [
{
"index": 0,
"net": "1.11",
"tax": null,
"gross": null
},
{
"index": 1,
"net": "1.11",
"tax": null,
"gross": null
},
{
"index": 2,
"net": "1.11",
"tax": null,
"gross": null
}
],
"tax_breakdown": [
{
"rate_percent": "21",
"taxable_amount": "3.33",
"tax_amount": "0.70"
}
],
"total_net": "3.33",
"total_tax": "0.70",
"total_gross": "4.03",
"currency": "EUR",
"scale": 2,
"data_version": "iso4217-datasets-7cdc784-2026-07-27"
}
}
How to call it
MCP
Connect https://computefirst.net/mcp (setup), then call execute with:
{
"id": "invoice-totals-compute",
"version": "1.0.0",
"input": {
"lines": [
{
"quantity": "1",
"unit_price": "1.11",
"tax_rate_percent": "21"
},
{
"quantity": "1",
"unit_price": "1.11",
"tax_rate_percent": "21"
},
{
"quantity": "1",
"unit_price": "1.11",
"tax_rate_percent": "21"
}
],
"currency": "EUR",
"rounding": "half_up"
}
}
HTTP (no key)
curl -X POST https://computefirst.net/v1/tools/invoice-totals-compute/versions/1.0.0/execute \
-H "Content-Type: application/json" \
-d '{"lines":[{"quantity":"1","unit_price":"1.11","tax_rate_percent":"21"},{"quantity":"1","unit_price":"1.11","tax_rate_percent":"21"},{"quantity":"1","unit_price":"1.11","tax_rate_percent":"21"}],"currency":"EUR","rounding":"half_up"}'
The machine-readable contract is at /v1/tools/invoice-totals-compute/versions/1.0.0.
CLI
node cli.mjs run invoice-totals-compute 1.0.0 --input input.json --base-url https://computefirst.net
Get the client at /clients/cli/.
Related tools
- Vat net gross convert: Convert a net or gross amount at a VAT rate into a net, VAT and gross triple that adds up exactly at currency precision.
- Decimal divide: Divide two decimal strings exactly, rounding the quotient once to a fixed scale, and report the exact remainder.
- Price margin compute: Solve cost, price, profit, gross margin and markup from any two of cost, price, margin percent or markup percent.
- Tiered price compute: Compute a total price for a quantity under graduated or volume tiers with inclusive bounds and optional flat fees.
- Decimal multiply: Multiply two decimal strings exactly, optionally rounding the product once to a fixed scale with a chosen mode.
- Discount stack apply: Apply an ordered stack of percent and fixed-amount discounts to a price, rounding each step or only at the end.