Solavel Solavel Docs

Invoices

docs/solavel-finance/invoices.md

Who can use this: Owner, Manager, Accountant. URL / Route: /finance/ar/invoices (finance.ar.invoices.index). Detail: finance.ar.invoices.show, edit, update, create, store, destroy. Action endpoints: finance.ar.invoices.post, unpost, void, pdf, send-email. Bulk: finance.ar.invoices.bulk.index, bulk.template, bulk.parse, bulk.preview, bulk.store. Plan / feature gate: feature:tracker.invoices (default: enabled on every plan). Permissions: sales.invoices.view, sales.invoices.create, sales.invoices.edit_draft, sales.invoices.send, sales.invoices.delete, sales.invoices.post, sales.invoices.unpost, sales.invoices.void. Recurring invoices use recurring.* permissions.

Purpose

An Invoice is a posted demand for payment from a customer. Use one when:

  • you've delivered goods or services and the customer will pay later,
  • you need to age a receivable on the AR ledger,
  • you want to share a numbered, branded document the customer can print or pay through the portal.

Once posted, the invoice appears in your AR ledger, hits the General Ledger, ages in the AR Aging report, and is visible to the customer through the secure portal. Until it is posted it is a Draft and does not affect your books.

Compared with a Sales receipt: a sales receipt is paid on the spot — cash is collected and revenue recognised in one step, no AR. An invoice splits the two: post now to recognise the receivable, collect later via a Payment.

Step by step

Browse invoices

  1. Open /finance/ar/invoices. Each row shows invoice number, customer, date, due date, total, amount due (after payments and credits), and status (Draft / Pending Approval / Posted / Partially Paid / Paid / Void).
  2. Filter by status, customer, date range, or "open balance > 0".

Create an invoice

Route: finance.ar.invoices.create / store. Permission: sales.invoices.create.

  1. Click New invoice.
  2. Pick Customer (or "+ New customer").
  3. The Invoice number comes from the active sequence — see Settings. You can override it.
  4. Set Invoice date and Due date (the customer's default payment terms suggest the due date).
  5. Add line items: Product/Service, Description, Quantity, Unit price, Tax. Sub-totals, tax totals, and grand total update live.
  6. Optionally add a Customer message and pick a PDF template.
  7. Optionally tag lines with Dimensions for analytic reporting.
  8. Click Save as draft to keep editing, or Save and post to post immediately.

A faster path: convert an accepted quote or an approved sales order.

Bulk create / import invoices

Route: finance.ar.invoices.bulk.index (page), bulk.template, bulk.parse, bulk.preview, bulk.store. Permission: sales.invoices.create.

To enter many invoices at once, use Bulk Invoices — open it from the caret next to New invoice, or go to /finance/ar/invoices/bulk. Bulk is an input shortcut only: every invoice it creates is an ordinary draft invoice, saved through the same rules, numbering, and tax logic as one typed on the normal form. There is no special record type.

Two ways to enter data:

  • Manual entry — fill in one card per invoice (invoice date, due date, customer, invoice number, currency, item, revenue account, quantity, rate, discount, tax).
  • File import — download a per-document CSV or XLSX template, fill it in, and upload it. One row becomes one single-line invoice. The XLSX template has drop-downs on the customer, currency, revenue account, and tax-code columns; the tax drop-down shows the code, name, and rate. Searchable reference lists are shown on the import tab with copy buttons.

After entering or uploading, Validate previews every invoice — totals and any blocking errors are shown before anything saves. Fix the highlighted rows, then save. The batch saves in one transaction: if any invoice fails, nothing is saved. Bulk-created invoices are always Draft — post them as usual.

Edit a draft

Route: finance.ar.invoices.edit / update. Permission: sales.invoices.edit_draft.

Drafts can be edited freely. Once posted, the invoice is read-only — see Unpost below.

Post an invoice

Route: finance.ar.invoices.post (POST). Permission: sales.invoices.post.

Posting:

  1. Validates the invoice against the chart of accounts and tax rates.
  2. Writes journal entries: debit AR, credit Sales (and Tax Liability and Inventory/COGS for stocked items).
  3. Locks the document.
  4. Generates and stores the PDF.

Posting is blocked when:

  • the invoice date falls inside a locked period (see Fiscal years and lock dates);
  • the invoice has zero lines;
  • the customer has been archived;
  • approval workflow is on and the invoice is not yet Approved.

Unpost (back to draft)

Route: finance.ar.invoices.unpost. Permission: sales.invoices.unpost.

Returns the invoice to Draft so you can correct and re-post it. Unposting voids the invoice's journal entry — the entry is kept for the audit trail but marked void and excluded from reports — rather than posting a separate reversal entry. Unpost is not allowed if any payment has been allocated to the invoice — unallocate the payment first — and is blocked when the period is locked.

Void an invoice

Route: finance.ar.invoices.void. Permission: sales.invoices.void.

Marks a posted invoice as void: writes a fully reversing journal on the void date, sets balance to zero, keeps the document number on the books. Use Void when you want a permanent record that the invoice should not have happened.

Send by email

Route: finance.ar.invoices.send-email. Permission: sales.invoices.send.

Opens the Send invoice dialog. Pre-fills customer email, default subject and body, attaches the PDF, and includes a secure portal link the customer can use to view, download, or pay (where supported). Successful sends are logged on the invoice's activity tab.

Print a PDF

Route: finance.ar.invoices.pdf. Permission: sales.invoices.view.

Streams the invoice as a PDF using the active PDF template. Templates are managed in Settings → PDF Templates (requires pdf_templates_enabled).

Delete a draft

Route: finance.ar.invoices.destroy. Permission: sales.invoices.delete.

Allowed only when status is Draft. Posted invoices cannot be deleted — Void instead.

How the journal looks

A JOD 100 service invoice (zero-rated tax):

Account Debit Credit
AR — Customer control 100.00
Revenue — Services 100.00

A JOD 117 invoice with 17% VAT, no inventory:

Account Debit Credit
AR — Customer control 117.00
Revenue — Sales 100.00
VAT Output 17.00

A JOD 117 invoice with 17% VAT, sold as a stocked item with JOD 60 cost:

Account Debit Credit
AR — Customer control 117.00
Revenue — Sales 100.00
VAT Output 17.00
COGS 60.00
Inventory 60.00

A USD 1,000 invoice with base currency JOD at an exchange rate of 0.710 (no tax):

Account Debit (JOD) Credit (JOD)
AR — Customer control (USD 1,000) 710.00
Revenue — Sales 710.00

When the customer later pays, the FX rate on the payment date may differ — the realised FX gain/loss is booked at that point. See Multi-currency.

Customer payment later applied to the JOD 117 invoice in full:

Account Debit Credit
Bank 117.00
AR — Customer control 117.00

The invoice flips to Paid and the open balance becomes zero.

Recurring invoices

⚠️ Risk: feature key tracker.recurring_invoices is declared in finance_features.php but the feature:tracker.recurring_* middleware on /recurring/templates checks all four recurring keys at once — if any one is missing, the page is blocked.

If feature:tracker.recurring_invoices is on and the user has recurring.create, you can create a Recurring Template from any invoice's More actions ▸ Make recurring menu, or under Recurring → Templates at /finance/recurring/templates. The template runs on its schedule and creates fresh draft (or auto-posted) invoices.

When to use which AR document

You want to… Use this
Bill the customer now, collect later (with ageing) Invoice (this page)
Collect money on the spot — walk-in / counter sale Sales receipt
Hold a deposit before any service is delivered Retainer
Repeat the same invoice on a schedule Recurring template of an invoice
Reduce an invoice you've already posted Credit note
Refund cash to the customer Refund receipt

Common mistakes

  • "Post is blocked" → almost always one of: (1) the invoice date is in a locked period, (2) the invoice has zero lines or zero total, (3) the customer is archived, (4) workflow approval is on and the invoice is still pending. The error toast tells you which.
  • Currency mismatch. A customer's currency is locked the moment they have any posted document. Trying to invoice them in a different currency will be blocked — issue the invoice in their original currency, or create a new customer record.
  • PDF looks wrong. Templates are managed at /finance/settings/pdf-templates. Make sure the right template is set as default for invoices, or pick it on the invoice itself.
  • Tax line missing. Tax codes are line-level. If a line shows no tax, the line's tax code is "None" — pick a code, or set a default on the customer record so new lines inherit it.

Tips

  • Press Ctrl/⌘ + K anywhere in Finance to global-search for an invoice number.
  • The list page at /finance/ar/invoices supports bulk send and bulk PDF from the toolbar — tick rows and pick the action.
  • The Open balance > 0 saved view (top of the filter bar) is the fastest way to find what's unpaid.

Lifecycle

Draft  ──Submit (workflow on)──▶  Pending Approval  ──Approve──▶  Approved
Draft / Approved  ──Post──▶  Posted
Posted  ──Allocate payments──▶  Partially Paid  ──more payments──▶  Paid
Posted  ──Unpost──▶  Draft  (only if no payments allocated, period unlocked)
Posted  ──Void──▶  Void

Behaviour and rules

  • Posting hits the GL. Drafts do not. Reports show only posted documents by default.
  • Unposting voids the journal. It does not create a reversal entry — the original journal is kept (marked void) for audit and dropped from reports.
  • Tax is line-level. Each line carries a tax code; the totals shown on the document are derived.
  • Multi-currency. If the customer's currency differs from the base currency, the invoice carries an exchange rate at the invoice date. Posting writes both currency amounts.
  • Period lock. Post / Unpost / Void all require the invoice date's period to be open.
  • Inventory. A posted invoice with stocked-item lines decreases on-hand quantity and posts to COGS — see Inventory.
  • PDF cache. The PDF is generated at post-time. Re-sending an email regenerates the PDF only if the template or invoice has changed.

Permissions / restrictions

  • View: sales.invoices.view.
  • Create / edit drafts: sales.invoices.create, sales.invoices.edit_draft.
  • Bulk create / import: sales.invoices.create.
  • Post / Unpost: sales.invoices.post, sales.invoices.unpost.
  • Send: sales.invoices.send.
  • Void: sales.invoices.void.
  • Delete (drafts only): sales.invoices.delete.

Related

Source: docs/solavel-finance/invoices.md ← All documentation