Mapping guide

A profile is a TOML file that tells einvoice build which source column feeds which e-invoice field. The source is a flat table, one row per invoice line, with invoice-level columns repeated on each line (the usual ERP export shape). CSV (UTF-8, BOM tolerated) and XLSX (first sheet, or sheet in [source]) are supported. Fully blank rows are skipped.

See examples/profile.toml for a complete profile.

Sections

[profile]
name = "erp-flat-export"
compute = true      # default true
round_off = true    # default true

[source]
invoice_key = "Invoice No"            # a column, or a list such as ["Seller GSTIN", "Invoice No"]
date_formats = ["%d-%b-%Y", "%Y-%m-%d"]
sheet = "Invoices"                    # XLSX only

[defaults]                            # constants for header fields
"TranDtls.TaxSch" = "GST"

[header]                              # header fields from columns
"DocDtls.No" = "Invoice No"
"DocDtls.Typ" = { column = "Doc Type", default = "INV", map = { Invoice = "INV", "Credit Note" = "CRN" } }

[line_defaults]                       # constants for every item
IsServc = "N"

[lines]                               # item fields, paths relative to one ItemList entry
HsnCd = "HSN"
Unit = { column = "Unit", default = "NOS" }

Coercion

Types come from the schema, not from the profile.

Schema type Treatment
number / integer Commas and a trailing % are stripped; "1,000" becomes 1000, "18%" becomes 18
date (DD/MM/YYYY) Parsed with date_formats in order; real Excel dates are accepted
state code Zero-padded to two digits (7 becomes 07)
GSTIN, enums, Y/N Upper-cased
other strings Trimmed; whole-number floats from Excel lose the .0

A bad value fails only its own invoice: build writes the others, prints FAILED <key>: <field>: <reason> and exits 1.

Computation (compute = true)

Only missing values are filled, so amounts supplied by the ERP are kept as given (and then checked by validate).

  1. Seller Stcd from the GSTIN prefix; buyer Stcd from its GSTIN; Pos from buyer Stcd.
  2. For EXPWP/EXPWOP: buyer Gstin URP, Stcd/Pos 96, Pin 999999 unless mapped.
  3. Item: SlNo; TotAmt = Qty x UnitPrice; AssAmt = TotAmt - Discount.
  4. Tax regime: zero for SEZWOP/EXPWOP, IGST for SEZ/exports, otherwise CGST+SGST when seller state equals Pos (and IgstOnIntra is not Y), else IGST. Amounts are AssAmt x rate / 100 (or / 200 per half), rounded half-up to paise. Cess and state cess use CesRt / StateCesRt.
  5. TotItemVal = AssAmt + taxes + cess + OthChrg.
  6. ValDtls: sums for AssVal, CgstVal, SgstVal, IgstVal, CesVal, StCesVal; then TotInvVal = sum(TotItemVal) + OthChrg - Discount (the ValDtls ones) + RndOffAmt, where RndOffAmt rounds the total to a whole rupee when round_off = true and is omitted otherwise.

Set compute = false to emit exactly what the profile maps.

Output

Keys follow schema order, so files diff cleanly. Numbers are JSON floats, rounded to two decimals.