Invoices are the centrepiece of Arsinous V8 Sales. When you create an invoice, the system does much more than record a sale — it decrements the specific inventory lots you’re selling from, writes the transaction into MySQL inside a database transaction, generates a formatted Google Sheets invoice document from a template, places a shortcut to that document in the customer’s Drive folder, and writes a hyperlink back into the Invoices sheet. The same machinery runs for credit notes, with stock adjustments reversed to reflect returned goods.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.
Document Types
Two document types share the same underlying data model and UI:| Type | type field value | Stock effect |
|---|---|---|
| Invoice | "invoice" | Decrements irs_items.in_stock for each lot used |
| Credit Note | "credit note" | Decrements with negative quantities (effectively restoring stock) |
The Invoices Sheet
updateInvoices(ss, sh) populates the Invoices sheet with a filtered, sorted view of the invoices table joined to customer names. The date range comes from getDates(), which reads the active time-period preference from user properties.
| Column | Source | Description |
|---|---|---|
| A | invoices.id | Invoice ID |
| B | invoices.type | "invoice" or "credit note" |
| C | invoices.name | Invoice number (zero-padded 6-digit string) |
| D | customers.name | Customer name (from JOIN) |
| E | invoices.date | Invoice date |
| F | invoices.total | Total before VAT |
| G | invoices.vat | VAT amount |
| H | (calculated) | Total with VAT (sum of F + G, inserted by the sync function) |
| I | invoices.comments | Comments |
| J | (generated) | HYPERLINK formula linking to the invoice Google Sheets file |
date DESC from MySQL, then re-sorted by id ASC in Apps Script before writing to the sheet.
Creating an Invoice
Open the invoice dialog
Go to Arsinous menu → Create Invoice or click New Invoice in the sidebar. This calls
showInvoice(null, "invoice"), which opens a 1000 × 600 px Vue.js/Buefy modal. On load, the modal fetches all customers, products, in-stock inventory lots (irs_items WHERE in_stock > 0), salesperson records, and customer discounts from MySQL in parallel.Select a customer and date
Use the Customer autocomplete (top-left) to search and select a customer. Only customers with
status = "active" appear. Set the Date using the date-picker (defaults to today). The Invoice # field is auto-populated from getNextId() — a zero-padded 6-digit string based on the AUTO_INCREMENT value of the invoices table.Add line items
Click the + button to add a row. For each line item:
- Select a Product from the autocomplete — the list shows available stock in parentheses.
- Choose a Lot (expiry date selector) — defaults to the earliest-expiring lot.
- Enter a Qty — capped at the available stock for the chosen lot.
- Adjust the Price if needed (defaults to the product’s
pricefield). - Open the Discounts dialog to override the quantity-break discount, fixed discount, or enter a manual discount percentage.
Optionally add a salesperson and comments
Select a S/P (salesperson) from the dropdown if applicable. Add any Comments in the text area at the bottom.
Create the document
Click Create. The button is disabled until a customer is selected and the total is non-zero. This triggers
saveInvoice(data) on the backend.How saveInvoice Works
saveInvoice(data) wraps all database operations in a single JDBC transaction (conn.setAutoCommit(false) … conn.commit()). If any step fails, the entire operation is rolled back, leaving inventory and invoice records in a consistent state.lot_id → net_qty_change.
2. Adjust inventory lots
invoices with fields: type, customer_id, date, sp_id, name, total, vat, ss_id, comments, cost. The generated id is captured via RETURN_GENERATED_KEYS.
For existing invoices, updates the header fields and removes old line items before re-inserting.
4. Create or reuse the invoice spreadsheet
createInvoiceSs(ssId, data) looks up the Drive file by ssId. If it doesn’t exist yet, it copies InvoiceTemplate into InvoiceFolder (named as the zero-padded invoice number) and creates a shortcut in the customer’s Drive folder.
invoices_items with fields: invoice_id, product_id, lot_id, qty, price, discount, fixed_discount, manual_discount, code, cost, priceAfterDiscount.
6. Persist the spreadsheet ID and commit
Executes UPDATE invoices SET ss_id = '...' WHERE id = '...' to store the Drive file ID back on the invoice record, then calls conn.commit() to finalise all database changes atomically. The connection is then closed.
7. Update the invoice spreadsheet content
After the transaction is committed and the connection is closed, updateInvoiceSs(ssId, data) opens the invoice Google Sheets file and writes to these specific cells:
| Cell / Range | Value written |
|---|---|
K6 | data.customer.code |
K7 | data.date |
K8 | Zero-padded invoice number ("000000" + data.id sliced to 6 digits) |
J1 | data.customer.details |
B8 | Salesperson code (data.sp.code), or blank if no salesperson |
A15:O54 | Line items grid — cleared first, then filled from row 15 with 15 columns per item row |
Editing an Invoice
- Select a row in the Invoices sheet or the Balance sheet.
- Go to Arsinous menu → Edit Invoice (or Edit Credit Note for credit notes).
editInvoiceOrNote(type)validates that the document type in the selected row matches the action type, then callsshowInvoice(id, type).- The modal loads the existing invoice via
getInvoice(id)and pre-fills all fields including items and discounts. - Make changes and click Update.
saveInvoice(data)handles the update path, recalculating lot adjustments as deltas from the original quantities.
Deleting an Invoice
deleteInvoiceOrNote(type) confirms the action via a prompt dialog, then calls deleteInvoice(id):
Invoice Number Generation
getNextId() reads the AUTO_INCREMENT value from information_schema.tables for the invoices table and returns it as a zero-padded 6-digit string (e.g. "000042"). This is called when opening a new invoice dialog and displayed in the Invoice # field.
Drive and Template Constants
The invoice system uses three constants defined inConstants.gs:
| Constant | Purpose |
|---|---|
InvoiceTemplate | Drive file ID of the master invoice Google Sheets template |
InvoiceFolder | Drive folder ID where invoice spreadsheet copies are stored |
CUSTOMERS_FOLDER | Parent Drive folder ID under which customer subfolders live |
data.customer.folder) for easy per-customer navigation.