# voiced.invoice.v1 A neutral export of issued invoices for software Voiced has no direct integration with. Choose invoices in the History list (checkboxes) or open one, then use "Export selected (voiced.invoice.v1 JSON)" or "(line items CSV)". The code is `src/lib/invoiceExportV1.ts`; `src/lib/__golden__/invoice-v1.golden.json` is a full example. ## Rules - **Money is exact.** Every amount appears twice: `_paise` (an integer) and `` (a decimal string with two places, e.g. `"7310.10"`). Nothing is a float. Rates (percent) are decimal strings such as `"9"` or `"6.25"`. - **Deterministic.** The same invoices give the same bytes: fixed key order, no timestamps, input order kept. - **JSON file** is an array with one object per invoice; each object carries `"schema": "voiced.invoice.v1"`. - Cancelled invoices are included with `"cancelled": true` (their figures are kept; filter them out of sums). - An unregistered supplier's plain "Invoice" has `document_type: "invoice"`, all tax heads zero and no supplier GSTIN. ## Invoice object | Key | Meaning | | --- | --- | | `schema`, `number`, `issue_date`, `due_date` | `YYYY-MM-DD` dates; `due_date` is null when unset | | `document_type` | `tax_invoice` or `invoice` | | `status`, `cancelled`, `cancelled_at`, `cancel_reason` | `status` is `issued` or `cancelled` | | `currency`, `po_number` | always `INR` | | `supplier` | `name`, `address`, `gstin` (null if none), `pan`, `gst_registration`, `state {code, name}`; frozen at issue | | `client` | `name`, `gstin`, `gst_category`, `address {text, line1, line2, city, pincode, state}`, `place_of_supply {code, name}` | | `items[]` | `line`, `description`, `hsn_sac`, `quantity` (decimal string), `unit`, `rate`, `taxable_value` (each with `_paise`) | | `tax` | `cgst`, `sgst`, `utgst`, `igst`, each `{rate, amount_paise, amount}`; heads that do not apply are zero | | `totals` | `subtotal`, `discount`, `taxable_value`, `tax`, `total` (each with `_paise`), `amount_in_words` | | `reverse_charge`, `notes` | | | `payments[]` | `date`, `amount` (cash), `tds`, `mode`, `reference` (amounts with `_paise`) | Notes on the fields: - **Items.** `taxable_value` of a line is the line amount before the invoice-level discount. `totals.taxable_value` is `subtotal - discount`, the base the tax is charged on. A fixed-amount line has `quantity "1"` and `unit null`. - **UTGST.** When the supplier is in a union territory without a legislature (state codes 04, 26, 31, 35, 38) the second head is reported under `utgst` and `sgst` is zero. - **Client details.** The name, GSTIN, printed address and place of supply are frozen on the invoice. The structured address parts and `gst_category` come from the client's saved record at export time (null or derived from the GSTIN when the invoice has no saved client). - **Supplier snapshot.** Only name, address, GSTIN, PAN, registration and state are exported; logo paths, e-mail and phone are not. ## Line-items CSV One row per line item, UTF-8 with a byte order mark and CRLF line ends; text cells that a spreadsheet would read as a formula get a leading apostrophe. Columns: `invoice_number, issue_date, due_date, document_type, status, cancelled, currency, supplier_name, supplier_gstin, client_name, client_gstin, client_gst_category, place_of_supply_code, place_of_supply, reverse_charge, line, description, hsn_sac, quantity, unit, rate, taxable_value, invoice_discount, invoice_cgst, invoice_sgst, invoice_utgst, invoice_igst, invoice_total`. The `invoice_*` amounts are filled on the first row of each invoice only, so summing a column never counts an invoice twice.