← All ivy-nodes
IVYXSTUDIO · IVY NODE
C
Check an invoice's numbers
ivy.node.invoice-check · v0.1.0
ivyx✓
Checks what a model read off a supplier invoice against itself: the net and the VAT add up to the total, the date is a date, the number and the supplier are there. Says verified true or lists what did not hold, so a reading goes on as a draft a person can trust or as one they have to look at.
#invoice#accounting#check
Inputs
| Field | Type | Description |
|---|---|---|
| supplier | string | The supplier's name as printed. |
| number | string | The invoice number as printed. |
| date | string | The invoice date, YYYY-MM-DD. |
| net | number | The amount before VAT. |
| vat | number | The VAT amount. |
| total | number | The amount to pay. |
Outputs
| Field | Type | Description |
|---|---|---|
| kindrequired | string | Always invoice: tells a receiver what the output is. |
| verifiedrequired | boolean | True when the numbers add up and the invoice names its supplier, number and date. |
| problemsrequired | array | What did not hold, one sentence each. |
Source
python
# Input preparation
inp = __ivy_ctx__["nodes"][__ivy_node_id__]["input"]
# Compute
# What a model read off a supplier invoice, held against itself.
import re
def num(v):
try:
return float(v)
except (TypeError, ValueError):
return None
class InvoiceCheck:
"Check an invoice's numbers"
def run(self, inp):
out = {}
net, vat, total = num(inp.get("net")), num(inp.get("vat")), num(inp.get("total"))
problems = []
if total is None:
problems.append("No total was read.")
elif net is not None and vat is not None and abs(net + vat - total) > 0.011:
problems.append("The net %.2f and the VAT %.2f add up to %.2f, not the total %.2f." % (net, vat, net + vat, total))
date = str(inp.get("date") or "").strip()
if not re.match(r"^\d{4}-\d{2}-\d{2}$", date):
problems.append("The date %s is not YYYY-MM-DD." % (date or "(none)"))
if not str(inp.get("supplier") or "").strip():
problems.append("No supplier is named.")
if not str(inp.get("number") or "").strip():
problems.append("No invoice number was read.")
out = {"kind": "invoice", "verified": not problems, "problems": problems}
return out
result = InvoiceCheck().run(inp)
# Output collection (the runner reads it here)
out = __ivy_ctx__["nodes"][__ivy_node_id__]["output"]
out.update(result)Tests
Requires: python:3.9
- adds-up
Net plus VAT is the total, and the invoice names its supplier, number and date.
- off
A total that is not net plus VAT, a date not ISO and no supplier are three problems, each a sentence.
- cents
Sums that differ only by a float's last digit still add up.
- empty
Nothing read is four problems, never a verified invoice.