Invoices and bills
Add a customer or vendor, optionally a job, then create an invoice or bill, add its lines, post it to Receivable or Payable, and unpost or duplicate it.
An invoice is what you send a customer to ask for payment; a bill is what a vendor sends you. Both are documents: a list of lines (entries) with prices, taxes and discounts, which you edit freely until you post it. Posting turns it into a transaction against your Accounts Receivable (invoice) or Accounts Payable (bill), and opens a lot that payments will close. Before this, set the book up as in Set up the business features.
Steps
- Add the other party with customer.create or vendor.create: a
name, acurrency, and optionally billingterms, ataxTableand adiscount. Its ID comes from the counter unless you give one. - Add a job with job.create if the work is for a particular project; its
ratebecomes the default price of its lines. A job's documents belong to the job's owner. - Create the document with invoice.create. The
ownerdecides what it is: a customer makes an invoice, a vendor a bill, an employee an expense voucher, a job whatever its owner is. GivebillingId(your customer's order number, or the vendor's invoice number). The number comes from the counter. - Add lines with invoice.addEntry: description,
quantity,price,account(the income or expense account) and, on invoices,discountand tax. A line takes the owner's tax table and discount unless it says otherwise. - Check the figures with invoice.totals: subtotal, tax per tax account, and total.
- Post it with invoice.post: the Receivable or Payable
accountin the document's currency, and thepostDate. The due date comes from the billing term unless you givedueDate. The result names the transaction and the lot. - Posted by mistake? invoice.unpost deletes the transaction and makes the document editable again, as long as no payment has been applied.
- Another one like it? invoice.duplicate copies a document's lines to a new, unposted one.
- Find documents with invoice.list and read one with invoice.get.
Example
An invoice and a bill, in a book that already has a customer, a vendor, tax tables and Receivable and Payable accounts.
Example: with a copy of the synthetic/business-editable example book open as book.gnucash, at 2024-03-10T12:00:00Z.
JSON-RPC
Request:
{"jsonrpc":"2.0","id":1,"method":"customer.create","params":{"name":"Globex","currency":"EUR","terms":"Net30"}}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "000002",
"name": "Globex",
"currency": "CURRENCY::EUR",
"active": true,
"…": "…"
}
}
Request:
{"jsonrpc":"2.0","id":2,"method":"invoice.create","params":{"owner":"5b22073fa4e34411b07c14a77147ce6b","billingId":"PO-5"}}
Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"id": "000003",
"type": "invoice",
"posted": false,
"billingId": "PO-5",
"entryCount": 0,
"…": "…"
}
}
Request:
{"jsonrpc":"2.0","id":3,"method":"invoice.addEntry","params":{"invoice":"00ed0000000000000000000000000002","description":"Design","quantity":"4","price":"90.00","account":"Income"}}
Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"description": "Design",
"quantity": {
"num": "4",
"denom": "1"
},
"…": "…"
}
}
Request:
{"jsonrpc":"2.0","id":4,"method":"invoice.totals","params":{"invoice":"00ed0000000000000000000000000002"}}
Response:
{
"jsonrpc": "2.0",
"id": 4,
"result": "…"
}
Request:
{"jsonrpc":"2.0","id":5,"method":"invoice.post","params":{"invoice":"00ed0000000000000000000000000002","account":"Assets:Receivable","postDate":"2024-03-10"}}
Response:
{
"jsonrpc": "2.0",
"id": 5,
"result": {
"transaction": "…",
"lot": "…",
"due": "…"
}
}
Request:
{"jsonrpc":"2.0","id":6,"method":"invoice.create","params":{"owner":"9697710198334d558a9bfde219bb1e41","billingId":"INV-8841"}}
Response:
{
"jsonrpc": "2.0",
"id": 6,
"result": {
"id": "000002",
"type": "bill",
"posted": false,
"…": "…"
}
}
Command line
red-ale exec --book book.gnucash --script - <<'EOF'
customer.create {"name":"Globex","currency":"EUR","terms":"Net30"}
invoice.create {"owner":"5b22073fa4e34411b07c14a77147ce6b","billingId":"PO-5"}
invoice.addEntry {"invoice":"00ed0000000000000000000000000002","description":"Design","quantity":"4","price":"90.00","account":"Income"}
invoice.totals {"invoice":"00ed0000000000000000000000000002"}
invoice.post {"invoice":"00ed0000000000000000000000000002","account":"Assets:Receivable","postDate":"2024-03-10"}
invoice.create {"owner":"9697710198334d558a9bfde219bb1e41","billingId":"INV-8841"}
EOF
It prints:
[
{
"id": "000002",
"name": "Globex",
"currency": "CURRENCY::EUR",
"active": true,
"…": "…"
},
{
"id": "000003",
"type": "invoice",
"posted": false,
"billingId": "PO-5",
"entryCount": 0,
"…": "…"
},
{
"description": "Design",
"quantity": {
"num": "4",
"denom": "1"
},
"…": "…"
},
"…",
{
"transaction": "…",
"lot": "…",
"due": "…"
},
{
"id": "000002",
"type": "bill",
"posted": false,
"…": "…"
}
]
MCP tool call
Tool call:
{"name":"customer.create","arguments":{"name":"Globex","currency":"EUR","terms":"Net30"}}
Result:
{
"structuredContent": {
"id": "000002",
"name": "Globex",
"currency": "CURRENCY::EUR",
"active": true,
"…": "…"
}
}
Tool call:
{"name":"invoice.create","arguments":{"owner":"5b22073fa4e34411b07c14a77147ce6b","billingId":"PO-5"}}
Result:
{
"structuredContent": {
"id": "000003",
"type": "invoice",
"posted": false,
"billingId": "PO-5",
"entryCount": 0,
"…": "…"
}
}
Tool call:
{"name":"invoice.addEntry","arguments":{"invoice":"00ed0000000000000000000000000002","description":"Design","quantity":"4","price":"90.00","account":"Income"}}
Result:
{
"structuredContent": {
"description": "Design",
"quantity": {
"num": "4",
"denom": "1"
},
"…": "…"
}
}
Tool call:
{"name":"invoice.totals","arguments":{"invoice":"00ed0000000000000000000000000002"}}
Result:
{
"content": [
{
"type": "text",
"text": "\"…\""
}
]
}
Tool call:
{"name":"invoice.post","arguments":{"invoice":"00ed0000000000000000000000000002","account":"Assets:Receivable","postDate":"2024-03-10"}}
Result:
{
"structuredContent": {
"transaction": "…",
"lot": "…",
"due": "…"
}
}
Tool call:
{"name":"invoice.create","arguments":{"owner":"9697710198334d558a9bfde219bb1e41","billingId":"INV-8841"}}
Result:
{
"structuredContent": {
"id": "000002",
"type": "bill",
"posted": false,
"…": "…"
}
}