Sales Invoices
Create, read, update and delete customer sales invoices (facturas emitidas)
📄️ Get sales invoice by ID
Returns a single customer sales invoice by its primary key. The response carries a strong `ETag` header with the current version for optimistic concurrency control. Returns 404 when the requested ID belongs to a purchase (issued=false) document. Honours `If-None-Match`: when the supplied ETag matches the current version on the server, the endpoint returns `304 Not Modified` without loading the full invoice detail graph.
📄️ Update sales invoice
Full replacement of an existing customer sales invoice. Send the `If-Match` header with the current ETag for optimistic concurrency control. The `issued` flag is forced to `true` server-side. Returns 404 when the requested ID belongs to a purchase document.
📄️ Delete sales invoice
Deletes a customer sales invoice. Send the `If-Match` header with the current ETag for optimistic concurrency control.
📄️ Merge-patch sales invoice
RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control.
📄️ List sales invoices
Returns a paginated list of customer sales invoices with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. Limit is capped at 200; skip is clamped to >= 0. The constraint `issued==true` is always enforced server-side.
📄️ Create sales invoice
Creates a new customer sales invoice with the provided data and optional line items and payments. Business logic (accounting, stock, DTE) runs in the legacy WAR via the internal commands gateway. The `issued` flag is forced to `true` server-side regardless of the request payload.
📄️ Prototype sales invoice for a creation form
Returns a NON-PERSISTED sales invoice pre-populated with the backend defaults the legacy form applies on 'new invoice': currencies and daily exchange rate of the branch's company, default accounting ledger, automatic document/accounting dates per company configuration, loyalty point value, Verifactu draft state (lifecycle BOR + series BORRADOR) when the company has Verifactu active, a PROVISIONAL series/number pair (re-derived at persist time) and the authenticated user's employee as agent or optometrist. The response carries no `id`, `version` or audit fields. The optional JSON body supplies initialisation hints: `warehouseId` (defaults to the user's current branch) and `counterpartyId`. Caller must follow up with `POST /api/v2/sales-invoices` to actually persist the invoice.
📄️ Get sales invoice editability matrix
Returns the server-resolved editability matrix for the invoice: which field groups (header, counterparty, amounts, unit prices, manual discounts, products, quantities, accounting, payments, insurer amounts, cost centers) and actions (edit, delete) are allowed for the current document state and the authenticated user's permissions, with a stable `code` and human-readable `reason` for every denied entry. Mirrors the legacy JSF lock/permission rules (TipoBloqueo, Verifactu lifecycle, OLA mode, Venezuelan fiscal printer, credit-note types). Purely informative: the server re-validates every write regardless.