Skip to content

Buying

The Buying module (internal app slug buying, shown in the sidebar as "Creditors") is Lubb ERP's purchasing workspace: it manages the supplier master and the paper trail from a supplier quotation through a Purchase Order, a Purchase Receipt, and finally a Purchase Invoice that posts to the general ledger. It's used by accounts/procurement staff to record what the business buys, who it owes, and to run the "Upload & Scan Invoice" OCR shortcut for keying in supplier bills quickly. It shares its item catalogue, tax templates, payment terms and chart of accounts with the Selling side of Accounting, and was split out of the Accounting app on 2026-07-12 as its own root-menu section.

What you can do

  • Maintain the Suppliers master: name, type, contact person, email, phone, address, city, country, website, VAT number, your account number with them, currency, a payable control account, a "Monthly" flag, and a disable switch.
  • See each supplier's live payable balance (computed from the GL, the same figure AP Ageing uses) and their last payment date, both computed on the fly rather than stored.
  • Track a "Monthly suppliers unpaid 30+ days" flag per supplier, backing a dashboard stat card that deep-links into the filtered grid.
  • Attach and manage an Agreement Files library per supplier (upload, rename, preview inline, download, delete) — kept indefinitely, unlike the one-shot customer email attachments elsewhere in Accounting.
  • Raise a Supplier Quotation — a supplier's quoted price for a set of items, with line items, VAT and a grand total.
  • Raise a Purchase Order against a supplier, tracking per_received / per_billed progress percentages and a delivery schedule date per line.
  • Record a Purchase Receipt for goods that have arrived — a status/tracking document only; it does not move stock or post to the ledger.
  • Record a Purchase Invoice (a supplier's bill), with a supplier reference number (bill_no), bill date, due date, a payable/"credit to" account override, and an is_return flag for debit notes.
  • Upload & Scan Invoice — upload a PDF or image of a supplier bill and have it OCR'd into a draft Purchase Invoice automatically (see Configuration & integrations below).
  • Submit any draft Buying document to lock it and (for Purchase Invoices only) post it to the General Ledger, or Cancel a submitted one to reverse that posting.
  • Search Suppliers by name/VAT/email, and search each transactional grid by document number or supplier name (Purchase Invoices also search on the supplier's bill number).
  • See per-grid stat cards: total suppliers / suppliers with an email / monthly suppliers on the Suppliers grid; invoice count and total billed (base_grand_total) on the Purchase Invoices grid; a Draft/Submitted/Cancelled status badge on every document grid.

Common tasks

  1. Add a supplier. Open Suppliers and create a row: name is required; fill in contact details, VAT number, currency and a payable account if you want postings to a non-default control account. Toggle "Monthly" if this is a recurring monthly bill so the unpaid-30-days tracking picks it up.
  2. Attach a signed agreement to a supplier. Open the supplier's edit drawer's "Agreement Files" tab and upload the file — it's stored against that supplier indefinitely and can be previewed, renamed or deleted later from the same tab.
  3. Raise a Purchase Order. Click "New Purchase Order" on the Purchase Orders grid, pick the supplier, add item lines (item, qty, rate, warehouse, expense account, cost centre), then Submit. A Purchase Order does not touch the ledger — it's pre-purchase paperwork tracking what's on order.
  4. Record goods received. Click "New Purchase Receipt", pick the supplier and the items received, and Submit. Like the Purchase Order, this only tracks status — it does not post to the GL and does not adjust on-hand stock quantities (only a Stock Reconciliation does that).
  5. Enter a supplier bill manually. Click "New Purchase Invoice", pick the supplier, enter the supplier's own reference number and bill/due dates, add item lines, and Submit to post Dr Expense (+ Dr VAT input) / Cr Creditors to the ledger. Cancelling a submitted invoice reverses that posting.
  6. Scan a supplier bill instead of typing it in. Click "Upload & Scan Invoice" on the Purchase Invoices grid toolbar and upload a PDF or image (max 20MB; password-protected PDFs prompt for their password). The extracted fields create an ordinary editable draft (docstatus 0) — if the supplier couldn't be confidently matched by name the draft is created without a party, and you pick the correct supplier on the normal edit form before submitting.

Data model

  • acc_supplier (AccSupplier) — the creditor record: name, type, VAT number, currency, payable account, payment terms, our account number with them, a "Monthly" flag, disabled flag. Balance and last-payment-date are never stored — always computed live from gl_entry / acc_payment_entry, the same way the Debtors module computes customer balances.
  • acc_supplier_documents (AccSupplierDocument) — one row per uploaded Agreement File, soft-linked (plain indexed column, not a DB FK) to a supplier; the actual file lives on disk under a per-supplier directory.
  • acc_supplier_quotation / acc_supplier_quotation_item — a supplier's quoted price for a set of items.
  • acc_purchase_order / acc_purchase_order_item — an order placed with a supplier; header adds transaction_date, schedule_date and per_received/per_billed progress percentages; each line adds its own schedule_date.
  • acc_purchase_receipt / acc_purchase_receipt_item — goods-received tracking only; explicitly does not post to the GL and (unlike a Stock Reconciliation) does not update acc_stock_balance.
  • acc_purchase_invoice / acc_purchase_invoice_item — the supplier's bill; adds bill_no (their reference), bill_date, due_date, credit_to_id (payable account override) and is_return (debit note). The only Buying document that posts to the ledger: Dr Expense per line (+ Dr VAT input per tax) / Cr Creditors (payable) for the grand total, against the supplier's payable_account_id or the company default.
  • All four transactional documents share a common header (company, posting date, currency + conversion rate, net/tax/grand totals in both transaction and base currency, docstatus/status, remarks, created_by/updated_by) and item-line shape (item, qty, UOM, rate, amount, income/expense account, cost centre, warehouse, item tax template) with their Selling-side counterparts (Quotation → Sales Order → Delivery Note → Sales Invoice).
  • Relationship to the shared catalogue — Buying documents reference acc_item (the same Items grid used by Selling and the storefront; an item's is_purchase flag and expense_account_id/valuation_rate cost fields are what Buying cares about), acc_warehouse, acc_tax_template, acc_payment_terms, acc_account and acc_cost_center — all owned by the Accounting module, not duplicated here.
  • Relationship to Accounting — every Purchase Invoice submission writes gl_entry rows through the same posting engine (app.services.accounting_posting) used by Sales Invoices, Payments and Journals; AP Ageing, the Purchase Register report and the Creditors reports feature read that same ledger and live in the Accounting module, not this one.

Configuration & integrations

  • No third-party purchasing/procurement provider is integrated — suppliers, orders, receipts and invoices are entered and stored entirely in Lubb's own backend.
  • Upload & Scan Invoice (OCR) does not call a vision API/SDK directly: the uploaded file is written to a scratch path and read by the Claude Code CLI (must be on PATH), which is instructed to return a single JSON object of extracted invoice fields. A password-protected PDF is decrypted server-side first (the CLI's file reader can't supply a password itself); accepted uploads are PDF, PNG, JPG/JPEG, WEBP or GIF, up to 20MB.
  • Submit/Cancel run through the same posting engine as the rest of Accounting (app.services.accounting_posting) — no separate configuration; account resolution falls back through the line's own account → the item's expense account → the company's configured default expense/payable accounts.
  • Company defaults (payable control account, default expense account, default cost centre) are configured once per company under Accounting's company settings and apply to every Buying document unless overridden on the supplier or the document line.

API reference

Buying's masters (Suppliers) are plain grid CRUD; the four transactional documents (Supplier Quotations, Purchase Orders, Purchase Receipts, Purchase Invoices) go through the shared document-create/edit/submit endpoints rather than generic row PUT/POST, since they carry child item rows:

  • GET /grid/acc-suppliers/data, POST /grid/acc-suppliers, PUT /grid/acc-suppliers/{row_id}, DELETE /grid/acc-suppliers/{row_id} — standard CRUD on the supplier master.
  • GET /suppliers/{supplier_id}/documents / POST /suppliers/{supplier_id}/documents / PATCH .../{document_id} / GET .../{document_id}/content / DELETE .../{document_id} — list, upload, rename, preview and delete a supplier's Agreement Files.
  • POST /accounting/documents/{doctype} — create a draft Buying document (header + item lines) from the entry form; doctype is one of acc_supplier_quotation, acc_purchase_order, acc_purchase_receipt, acc_purchase_invoice. Pass ?submit=true to post it immediately after creation.
  • GET /accounting/documents/{doctype}/{doc_id} — read a document (header + lines, FK ids resolved to names) for the grid's view modal.
  • GET /accounting/documents/{doctype}/{doc_id}/edit — read a draft back in raw/editable form for the edit form.
  • PUT /accounting/documents/{doctype}/{doc_id} — update a draft's header + lines in place; ?submit=true posts it after saving.
  • POST /accounting/{doctype}/{doc_id}/submit — submit a document (locks it; Purchase Invoices additionally post to the GL).
  • POST /accounting/{doctype}/{doc_id}/cancel — cancel a submitted document (Purchase Invoices additionally reverse their GL posting).
  • POST /accounting/documents/acc_purchase_invoice/ocr-upload — the "Upload & Scan Invoice" endpoint; multipart file upload (+ optional password for a locked PDF), returns the created draft invoice or a 423 asking for a PDF password.
  • GET /grid/acc-purchase-invoices/data, /grid/acc-purchase-orders/data, /grid/acc-purchase-receipts/data, /grid/acc-supplier-quotations/data — paginated, sortable, filterable list views for each document grid (read side; writes go through the /accounting/documents/... endpoints above).

Lubb ERP Documentation