The invoice module is the most complex part of Arsinous V8 Sales. Each invoice (or credit note) is stored in MySQL across two tables —Documentation Index
Fetch the complete documentation index at: https://mintlify.com/arsinousltd-sudo/Arsinous-V8-Sales/llms.txt
Use this file to discover all available pages before exploring further.
invoices and invoices_items — and simultaneously reflected in a dedicated Google Sheets file copied from a master template and filed inside the customer’s Drive folder. The save flow adjusts lot-level stock quantities in irs_items, runs all database writes inside a single transaction, and then updates the Sheets invoice document with customer, date, and line-item data. Deletion reverses stock changes before removing the database records. The functions below cover the full lifecycle from dialog display through spreadsheet hydration.
showInvoice(id, type)
Opens a 1000 × 600 modal dialog rendered from the invoice/index HTML template.
The invoice ID to edit. When provided, the dialog titles itself “Edit invoice” (or “Edit credit note”) and loads the existing record via
getInvoice(id) on the front-end. When null or omitted, the dialog titles itself “Create New invoice” and initialises with an empty form.The document type. Accepted values are
"invoice" (default) and "credit note". This value is passed directly into the template and affects how the invoice spreadsheet labels itself (see updateInvoiceSs).getNextId()
Queries the MySQL AUTO_INCREMENT counter for the invoices table so the front-end can display a preview of the next invoice number before the record is saved.
AUTO_INCREMENT is 42, the return value is "\"000042\"".
This value is a preview only. The actual ID assigned on INSERT may differ if another invoice is saved concurrently between the call to
getNextId and the subsequent saveInvoice.saveInvoice(data)
The central write function for invoices. Accepts a JSON-encoded invoice object, adjusts inventory lot quantities, persists the invoice header and line items in a transaction, creates or reuses a Google Sheets invoice file, and finally hydrates that file with the full invoice data.
A JSON-encoded invoice object. Key fields:
Each element of
| Field | Type | Description |
|---|---|---|
id | string | null | null for a new invoice; an existing invoice ID for an update. |
type | string | "invoice" or "credit note". |
customer_id | string | MySQL customer ID. |
date | string | Invoice date in YYYY-MM-DD format. |
sp_id | string | Salesperson ID. |
name | string | Invoice name / reference. |
total | number | Net total (before VAT). |
vat | number | VAT amount. |
ss_id | string | Google Sheets file ID of the existing invoice spreadsheet (for updates). |
comments | string | Optional free-text comments. |
cost | number | Total cost for margin tracking. |
items | array | Line items — see below. |
customer | object | { folder, code, details } — used for Drive filing and spreadsheet population. |
products | object | Keyed by product ID; provides name and retail for updateInvoiceSs. |
discounts | object | Keyed by item index; provides discount and VAT breakdown for updateInvoiceSs. |
lots | object | Keyed by lot ID; provides exp_date for updateInvoiceSs. |
items must include: id (product id), lot (lot id), qty, price, discount, fixed_discount, manual_discount, code, cost, priceAfterDiscount.- Aggregate new lot quantities — sums
qtyperlotacross all items into alotsmap. - Edit mode — reverse prior quantities — if
data.idis set, readslot_id, qtyfrominvoices_itemsfor the existing invoice and subtracts those quantities from thelotsmap (net delta). Then deletes all existinginvoices_itemsfor the invoice. - Update stock — batch-executes
UPDATE irs_items SET in_stock = in_stock - ? WHERE id = ?for every lot in the map. - INSERT or UPDATE the
invoicesrecord — new invoices useRETURN_GENERATED_KEYSto capture the assigned ID; updates rewritename,customer_id,date,total,vat,ss_id,comments, andcost. - Create or reuse the invoice Sheets file — calls
createInvoiceSs(data.ss_id, data). - Batch-INSERT
invoices_items— one row per item withinvoice_id,product_id,lot_id,qty,price,discount,fixed_discount,manual_discount,code,cost,priceAfterDiscount. - Persist
ss_id— writes the spreadsheet file ID back toinvoices.ss_id. - Commit transaction —
conn.commit()is called; the connection is then closed. - Hydrate the invoice spreadsheet — calls
updateInvoiceSs(data.ss_id, data)outside the transaction.
getInvoice(id)
Fetches a single invoice with its line items from the database.
The invoice primary key to retrieve.
{ invoice: { ...invoices row }, items: [ ...invoices_items rows ] }. Both invoice and each element of items are plain objects with MySQL column names as keys and string values (as returned by JDBC’s getString).
The error message in the source contains a typo:
"Ther is no Ivoice with id =". This is the literal string thrown, so any client-side error handling that matches this message should account for the spelling.updateInvoices(ss, sh)
Refreshes the Invoices sheet with all invoices within the current date range, adds a computed “Total with Vat” column, and generates spreadsheet link formulas in the final column.
The Google Sheets spreadsheet object. Defaults to
SpreadsheetApp.getActive().The sheet to write into. Defaults to the sheet named
"Invoices" within ss.- Clears the entire Invoices sheet before writing.
- Fetches the date range from
getDates()(driven by user properties set in the sidebar). - Joins
invoiceswithcustomersto include the customer name. - Sorts the output by invoice ID ascending (despite the query ordering by date descending — the sort is applied in Apps Script after fetch).
- Inserts a “Total with Vat” column at position 8 (index 7) computed as
total + vatfor each row. - Writes
=HYPERLINK("https://docs.google.com/spreadsheets/d/<ss_id>","Link")formulas in column 10 for every data row.
deleteInvoice(id)
Reverses inventory lot quantities for all items on the invoice, deletes the invoice and its items from the database in a transaction, and triggers sheet refreshes for Inventory and Invoices.
The invoice primary key to delete.
(lot_id, qty) pair from invoices_items for the given invoice and batch-executes UPDATE irs_items SET in_stock = in_stock + ? WHERE id = ?, adding the quantities back to stock before removing the invoice records.
createInvoiceSs(ssId, data)
Creates a new Google Sheets invoice file by copying the master InvoiceTemplate, or reuses an existing file if it can be found by ID. Places a shortcut to the file in the customer’s Drive folder for new files.
The Google Drive file ID of an existing invoice spreadsheet. Pass
null or undefined for new invoices. If the file cannot be found by this ID (e.g., it was deleted from Drive), a new copy is created automatically.The invoice data object. Must include:
data.customer.folder— Drive folder ID of the customer (for shortcut placement).data.id— Invoice ID, used as the file name (zero-padded to 6 digits).
New invoice files are placed in the shared
InvoiceFolder (configured in Constants.gs). A shortcut is then created inside the customer’s personal folder (data.customer.folder). This keeps all invoice files in one central location while making them discoverable from each customer’s folder.updateInvoiceSs(ssId, data)
Writes invoice header and line-item data into the Google Sheets invoice file. This is called after the database transaction commits and is the step that makes the invoice spreadsheet human-readable.
The Google Drive file ID of the invoice spreadsheet to update.
The full invoice data object (same object passed through
saveInvoice).| Cell | Value |
|---|---|
K6 | Customer code |
K7 | Invoice date |
K8 | Zero-padded invoice number (6 digits) |
J1 | Customer details (address block) |
B8 | Salesperson code |
A11 | "CREDIT NOTE" label (credit notes only) |
| Column | Content |
|---|---|
| A | Product code |
| B | Product name |
| C–E | (blank) |
| F | Quantity |
| G | Unit price |
| H | Subtotal (qty × price) |
| I | Discount % (as decimal, e.g. 0.10) |
| J | Total after discount |
| K | VAT code |
| L | VAT amount |
| M | Total with VAT |
| N | Retail price |
| O | Lot expiry date |
The sheet template has space for 40 line items (rows 15–54).
A15:O54 is cleared before writing, so any items beyond 40 rows would silently overflow without error. Ensure invoices do not exceed 40 line items.