Skip to content

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

receiver RUT validtrue
totals.net$120.000
totals.exempt$0
totals.vat (19%)$22.800
totals.total$142.800

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#

TypeScript
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#

TypeScript
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 from createDte(). Its type and items are used, and the result equals dte.totals.
  • items (LineItem[]) - The detail lines to total, same shape as in createDte().
  • options (optional, only with items)
    • 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 is 19) - IVA rate as a percentage.
    • grossPrices (boolean) - Whether unit prices already include IVA. Defaults to true for receipts (type 39) and false for 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 lines
  • vatRate - The rate applied, as a percentage
  • vat - The IVA amount
  • total - 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:

  1. Each line is rounded on its own. A line amount is round(quantity × unitPrice × (1 − discountPercent / 100)), rounded before the lines are added up.
  2. IVA is calculated once, over the summed net: vat = round(net × vatRate / 100).
  3. Exempt lines (exempt: true) add to exempt and never carry IVA.
  4. Exempt documents (types 34 and 41) treat every line as exempt: net and vat are 0.
  5. 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) and vat = 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:

TypeScript
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#

TypeScript
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#

TypeScript
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)#

TypeScript
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  // 120000

Receipts (39)#

On a receipt you enter the price the customer sees, IVA included:

TypeScript
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:

TypeScript
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#

TypeScript
import { calculateTotals, createDte } from 'dte-sdk'
 
const dte = createDte(input)
 
calculateTotals(dte) // same values as dte.totals

Passing 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.

  • createDte() - Builds a document and calculates its totals with these rules
  • toXml() - See the totals as they appear in the XML