calculateTotals()
Calculates the net, exempt, IVA and total amounts in integer CLP for a document or a list of line items.
Try it#
Try it — build a document
toXml() preview — unsigned, no TED
<DTE version="1.0">
<Documento ID="F1024T33">
<Encabezado>
<IdDoc>
<TipoDTE>33</TipoDTE>
<Folio>1024</Folio>
<FchEmis>2026-10-30</FchEmis>
</IdDoc>
<Emisor>
<RUTEmisor>76123456-0</RUTEmisor>
<RznSoc>Arrow Software SpA</RznSoc>
</Emisor>
<Receptor>
<RUTRecep>77654321-7</RUTRecep>
</Receptor>
<Totales>
<MntNeto>120000</MntNeto>
<TasaIVA>19</TasaIVA>
<IVA>22800</IVA>
<MntTotal>142800</MntTotal>
</Totales>
</Encabezado>
<Detalle>
<NroLinDet>1</NroLinDet>
<NmbItem>Licencia anual</NmbItem>
<QtyItem>1</QtyItem>
<PrcItem>120000</PrcItem>
<MontoItem>120000</MontoItem>
</Detalle>
</Documento>
</DTE>Basic Usage#
import { calculateTotals } from 'dte-sdk'
calculateTotals([{ name: 'Licencia anual', quantity: 1, unitPrice: 120000 }])
// { net: 120000, exempt: 0, vatRate: 19, vat: 22800, total: 142800 }Type Signature#
function calculateTotals(dte: Dte): Totals
function calculateTotals(
items: LineItem[],
options?: { type?: DteType; vatRate?: number; grossPrices?: boolean },
): Totals
interface Totals {
net: number
exempt: number
vatRate: number
vat: number
total: number
}Parameters#
dte(Dte) - A document fromcreateDte(). Its type and items are used, and the result equalsdte.totals.items(LineItem[]) - The detail lines to total, same shape as increateDte().options(optional, only withitems)type(DteType) - Applies the rules of that document type. Without it, items are totaled as a regular taxable document: net prices, IVA on top.vatRate(number, default:VAT_RATE, which is19) - IVA rate as a percentage.grossPrices(boolean) - Whether unit prices already include IVA. Defaults totruefor receipts (type 39) andfalsefor everything else.
Return Value#
Returns a Totals object. Every amount is an integer in CLP:
net- Sum of the taxable lines (before IVA)exempt- Sum of the exempt linesvatRate- The rate applied, as a percentagevat- The IVA amounttotal-net + vat + exempt
Invalid lines throw a DteError with code INVALID_AMOUNT, with the same rules as createDte().
Rounding Rules#
CLP has no decimals, so every amount is rounded half-up to the nearest peso. The order of operations matters:
- Each line is rounded on its own. A line amount is
round(quantity × unitPrice × (1 − discountPercent / 100)), rounded before the lines are added up. - IVA is calculated once, over the summed net:
vat = round(net × vatRate / 100). - Exempt lines (
exempt: true) add toexemptand never carry IVA. - Exempt documents (types 34 and 41) treat every line as exempt:
netandvatare0. - Receipts (type 39) use gross prices by default. Prices already include IVA, so the total is the sum of the lines and the IVA is backed out of it:
net = round(total / 1.19)andvat = total − net. Net plus IVA always equals what the customer paid.
Per-line Rounding#
Two lines of 1.5 × 999 each come to 1498.5, and each one rounds up to 1499 before they are added:
import { calculateTotals } from 'dte-sdk'
calculateTotals([
{ name: 'Cable UTP (m)', quantity: 1.5, unitPrice: 999 },
{ name: 'Cable HDMI (m)', quantity: 1.5, unitPrice: 999 },
])
// each line: 1.5 × 999 = 1498.5 → 1499
// net: 1499 + 1499 = 2998 (rounding the sum instead would give 2997)
// vat: round(2998 × 0.19) = round(569.62) = 570
// { net: 2998, exempt: 0, vatRate: 19, vat: 570, total: 3568 }Discounts#
import { calculateTotals } from 'dte-sdk'
calculateTotals([
{ name: 'Soporte mensual', quantity: 3, unitPrice: 9990, discountPercent: 15 },
])
// line: 3 × 9990 × 0.85 = 25474.5 → 25475 (half-up)
// vat: round(25475 × 0.19) = round(4840.25) = 4840
// { net: 25475, exempt: 0, vatRate: 19, vat: 4840, total: 30315 }Exempt Lines#
import { calculateTotals } from 'dte-sdk'
calculateTotals([
{ name: 'Licencia anual', quantity: 1, unitPrice: 120000 },
{ name: 'Soporte mensual', quantity: 3, unitPrice: 9990, discountPercent: 15 },
{ name: 'Curso de capacitación', quantity: 2, unitPrice: 45000, exempt: true },
])
// net: 120000 + 25475 = 145475
// vat: round(145475 × 0.19) = round(27640.25) = 27640
// exempt: 2 × 45000 = 90000
// { net: 145475, exempt: 90000, vatRate: 19, vat: 27640, total: 263115 }Exempt Documents (34 and 41)#
import { calculateTotals } from 'dte-sdk'
const items = [{ name: 'Licencia anual', quantity: 1, unitPrice: 120000 }]
const totals = calculateTotals(items, { type: 34 })
totals.net // 0
totals.exempt // 120000
totals.vat // 0
totals.total // 120000Receipts (39)#
On a receipt you enter the price the customer sees, IVA included:
import { calculateTotals } from 'dte-sdk'
calculateTotals([{ name: 'Licencia anual', quantity: 1, unitPrice: 142800 }], { type: 39 })
// net: round(142800 / 1.19) = 120000, vat: 142800 − 120000 = 22800
// { net: 120000, exempt: 0, vatRate: 19, vat: 22800, total: 142800 }
calculateTotals([{ name: 'Café de grano 250 g', quantity: 2, unitPrice: 4990 }], { type: 39 })
// total: 9980, net: round(8386.55) = 8387, vat: 9980 − 8387 = 1593
// { net: 8387, exempt: 0, vatRate: 19, vat: 1593, total: 9980 }If your catalog stores net prices, turn gross pricing off:
calculateTotals([{ name: 'Licencia anual', quantity: 1, unitPrice: 120000 }], {
type: 39,
grossPrices: false,
})
// { net: 120000, exempt: 0, vatRate: 19, vat: 22800, total: 142800 }From a Document#
import { calculateTotals, createDte } from 'dte-sdk'
const dte = createDte(input)
calculateTotals(dte) // same values as dte.totalsPassing a Dte is handy in tests. To show a breakdown before the document exists, such as a cart or a quote, pass the items directly.
Related Functions#
createDte()- Builds a document and calculates its totals with these rulestoXml()- See the totals as they appear in the XML