Who can use this: Owner, Manager, Accountant. URL / Route:
/finance/ap/bills(finance.ap.bills.index). Detail:finance.ap.bills.show,edit,update,create,store,destroy. Action endpoints:finance.ap.bills.post,unpost,void,send-email,allocate.form,allocate,document,scan-and-prefill. Bulk:finance.ap.bills.bulk.index,bulk.template,bulk.parse,bulk.preview,bulk.store. Plan / feature gate:feature:tracker.bills(default: enabled). Permissions:purchases.bills.view,purchases.bills.create,purchases.bills.edit_draft,purchases.bills.send,purchases.bills.delete,purchases.bills.post,purchases.bills.unpost,purchases.bills.allocate,purchases.bills.download.
Purpose
A Bill is a posted obligation to pay a supplier. Once posted, it appears in your AP ledger, hits the General Ledger, ages in the AP Aging report, and is reportable through Supplier Balance Summary, AP Aging, and Bill Details. Until it is posted it is a Draft and does not affect your books.
Step by step
Browse bills
- Open
/finance/ap/bills. Each row shows bill number, supplier, bill date, due date, total, amount due, and status (Draft / Pending Approval / Posted / Partially Paid / Paid / Void). - Filter by supplier, status, date range, or "open balance > 0".
Create a bill
Route: finance.ap.bills.create / store. Permission: purchases.bills.create.
- Click New bill.
- Pick Supplier (or "+ New supplier").
- Enter Bill number (this is the supplier's reference, not yours), Bill date, Due date.
- Add line items. Each line: Account or Item, Description, Quantity, Unit price, Tax.
- Optionally tag lines with Dimensions.
- Optionally upload the supplier's PDF or photo of the bill in the Attachment panel.
- Save as Draft or Save and Post.
Scan and prefill from a receipt or PDF
Route: finance.ap.bills.scan-and-prefill. Requires feature:receipt_scan_enabled (default: enabled).
Upload a PDF or photo and let the OCR engine extract the supplier, date, Bill No., amount, line items, and tax. Review the suggested fields and save.
Scan vs attach — automatic based on form state. The scan panel shows an info note explaining the behaviour:
- Form empty → the upload is scanned and the fields are auto-filled.
- Form has any data (supplier, bill no., reference, notes, or any line) → the upload is only attached as a file — it is not scanned, so your data is kept and no scan credit is consumed.
So it's always safe to upload — your typed data is never overwritten.
Line-item matching. When a description from the receipt matches an existing inventory item (exact, contains, or close fuzzy match — handles single-character OCR misreads), the line is created as an Item line with the inventory item, account, unit and price wired in. If no match is found, the line falls back to an Account line with a default expense account so the bill is immediately saveable.
See also Expenses which uses the same scan path.
Bulk create / import bills
Route: finance.ap.bills.bulk.index (page), bulk.template, bulk.parse, bulk.preview, bulk.store. Permission: purchases.bills.create.
To enter many bills at once, use Bulk Bills — open it from the caret next to New bill, or go to /finance/ap/bills/bulk. Bulk is an input shortcut only: every bill it creates is an ordinary draft bill, saved through the same rules 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 bill (bill date, due date, supplier, bill number, currency, item or account, description, 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 bill. The XLSX template has drop-downs on the supplier, currency, item/account, and tax-code columns; the tax drop-down shows the code, name, and rate. Searchable reference lists (accounts, taxes, suppliers) are shown on the import tab with copy buttons.
After entering or uploading, Validate previews every bill — totals and any blocking errors are shown before anything saves. Fix the highlighted rows, then save. The batch saves in one transaction: if any bill fails, nothing is saved. Bulk-created bills are always Draft — post them from the bills list or detail page as usual.
Edit a draft
Route: finance.ap.bills.edit / update. Permission: purchases.bills.edit_draft.
Drafts are freely editable. A posted bill is read-only: the Edit action is hidden and opening the edit form is blocked. To change a posted bill, Unpost it first, edit the draft, then post again.
Post a bill
Route: finance.ap.bills.post. Permission: purchases.bills.post.
Posting:
- Validates the bill against accounts, taxes, and supplier currency.
- Writes journal entries: debit Expense (or Inventory for stocked items), credit AP (and Tax — Recoverable).
- Locks the document.
- Generates the PDF.
Posting is blocked when the date falls in a locked period, the bill has zero lines, the supplier is archived, or workflow approval is pending.
Unpost
Route: finance.ap.bills.unpost. Permission: purchases.bills.unpost.
Returns the bill to Draft so you can correct and re-post it. Unposting voids the bill's journal entry — the entry is kept for the audit trail but marked void and excluded from reports — and unwinds any inventory and tax effects. It does not post a separate reversal entry, so the ledger is not cluttered with reversal pairs.
Unpost is blocked if any payments or debit notes are allocated to the bill (remove the allocations first), if the period is locked, or if the bill's journal is matched in a bank reconciliation.
Void
Route: finance.ap.bills.void.
Posts a fully reversing journal as of the void date and marks the bill as Void. Use Void when you want a permanent record that the bill should not have happened, rather than removing it.
Allocate
Route: finance.ap.bills.allocate.form (GET) / finance.ap.bills.allocate (POST). Permission: purchases.bills.allocate.
Apply existing unallocated bill payments or unapplied debit notes to this bill. The allocation form shows everything the supplier currently has on account.
Send by email
Route: finance.ap.bills.send-email. Permission: purchases.bills.send. Mostly used to forward the bill to internal approvers or to your accountant.
Print a PDF
Route: finance.ap.bills.pdf.
Download attachment
Route: finance.ap.bills.document. Permission: purchases.bills.download. Streams the original uploaded supplier document.
Delete a draft
Route: finance.ap.bills.destroy. Permission: purchases.bills.delete. Allowed only when status is Draft.
How the journal looks
A JOD 117 bill for office supplies, 17% VAT recoverable:
| Account | Debit | Credit |
|---|---|---|
| Office supplies | 100.00 | |
| VAT Input (Recoverable) | 17.00 | |
| AP — Supplier control | 117.00 |
A JOD 117 bill for a stocked inventory item (JOD 100 cost + JOD 17 VAT):
| Account | Debit | Credit |
|---|---|---|
| Inventory | 100.00 | |
| VAT Input (Recoverable) | 17.00 | |
| AP — Supplier control | 117.00 |
A USD 1,000 supplier bill (base JOD, FX 0.710), 17% VAT recoverable:
| Account | Debit (JOD) | Credit (JOD) |
|---|---|---|
| Expense — Imported goods | 710.00 | |
| VAT Input (Recoverable) | 120.70 | |
| AP — Supplier control (USD 1,000 + tax) | 830.70 |
The supplier-side balance is held in USD; the books carry both currency amounts. When the bill is paid, the FX rate on the payment date may differ — a realised FX gain/loss is booked at that point.
Paying the JOD 117 bill in full from the bank:
| Account | Debit | Credit |
|---|---|---|
| AP — Supplier control | 117.00 | |
| Bank | 117.00 |
The bill flips from Posted to Paid and the open balance becomes zero.
Recurring bills
⚠️ Risk: feature key
tracker.recurring_billsis declared infinance_features.phpbut thefeature:tracker.recurring_*middleware on/recurring/templateschecks all four recurring keys at once — if any is missing, the page is blocked.
If feature:tracker.recurring_bills is on you can make a Recurring Template from any bill (More actions ▸ Make recurring) or from /finance/recurring/templates.
When to use which AP document
| You want to… | Use this |
|---|---|
| Record an unpaid supplier invoice (with ageing + a later payment) | Bill (this page) |
| Record something paid on the spot (card / cash) — no balance owed | Expense |
| Commit to a future purchase before the supplier bills you | Purchase order — convert to a bill when goods arrive |
| Reduce a bill you've already posted | Debit note |
| Record cash coming back from a supplier | Supplier refund |
| Spread freight / duty across received inventory | Landed cost |
| Pay back staff for business kilometres | Mileage |
Common mistakes
- "Post is blocked" → check: (1) the bill date is in a locked period, (2) the bill has zero lines or zero total, (3) the supplier is archived, (4) workflow approval is on and the bill is pending.
- "3-way match failure" → with
feature:enable_3_way_matchon, the bill's quantities and amounts must match the originating PO and recorded goods receipt. Open the bill side-by-side with the PO and find the variance. - Duplicate Bill No. warning. The Bill number is the supplier's reference. Two bills from the same supplier cannot share the same number. If you got the warning, search the supplier profile first — you may have already entered it.
- Currency drift. A supplier's currency is locked once they have any posted document. Bill them in a new currency by creating a separate supplier record.
- VAT didn't reduce the net payable. Check the tax code's Recoverable flag — non-recoverable VAT is added back into the expense, not the recoverable VAT account.
Tips
- Use Bulk Bills at
/finance/ap/bills/bulkto enter many bills from a CSV / XLSX template — see Bulk create / import bills above. - Drop a PDF or photo straight onto the New bill page to scan and auto-fill via OCR. If the form is empty it scans; if you've already typed something it just attaches.
- The list page supports filtering by Open balance > 0 to find unpaid bills.
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.
- A posted bill cannot be edited or deleted. Unpost it back to Draft first.
- 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 recoverability. Each line's tax is split into recoverable / non-recoverable based on the tax code.
- Multi-currency. The bill carries an exchange rate at the bill date; the AP credit posts in the supplier currency, the expense lines post in base currency.
- Locked period. Post / Unpost / Void all require the bill date's period to be open.
- Inventory. Stocked-item lines on a bill increase on-hand and post to the Inventory account; non-stocked lines hit the Expense account directly. See Inventory.
- 3-way match. If
feature:enable_3_way_matchis on, posting a bill that arrived via a Purchase Order is checked against the matching PO and goods receipt before being allowed.
Permissions / restrictions
- View:
purchases.bills.view. - Create / edit drafts:
purchases.bills.create,purchases.bills.edit_draft. - Bulk create / import:
purchases.bills.create. - Post / Unpost:
purchases.bills.post,purchases.bills.unpost. - Send:
purchases.bills.send. - Delete (drafts only):
purchases.bills.delete. - Allocate:
purchases.bills.allocate. - Download supplier attachment:
purchases.bills.download.