NZ tax assistant for sole traders. Process receipt photos into IRD-ready GST reports, track sales income for GST Box 5, calculate IR3 annual income tax, provisional tax, asset depreciation, and export to Xero CSV. Use when: (1) user sends a receipt/invoice photo, (2) user asks about GST, income tax, or tax returns, (3) user wants to export receipts or generate reports, (4) user mentions IRD, GST, IR3, provisional tax, or depreciation.
NZ tax assistant for sole trader builders and contractors. Process receipt photos into IRD-ready GST reports, track sales income, calculate annual income tax (IR3), provisional tax, and asset depreciation. Export to XLSX or Xero CSV.
This is a personal-use skill -- each user runs their own instance. No multi-tenant, no login.
~/.openclaw/data/kiwi-receipts/
├── config.json # Business name, GST number, tax settings
├── receipts.json # All captured purchase receipts
├── income.json # Sales/invoice records
├── assets.json # Depreciable assets register
└── tax-history.json # Previous years' tax figures (for provisional tax)
When user sends "setup", or on first use when config.json doesn't exist:
~/.openclaw/data/kiwi-receipts/config.json{
"business_name": "My Construction Ltd",
"gst_number": "12-345-678",
"balance_date": "31-march",
"gst_filing_frequency": "2-monthly",
"depreciation_method": "DV",
"vehicle_business_percent": 80,
"phone_business_percent": 70,
"home_office_percent": 0
}
Each entry represents an invoice or payment received:
[
{
"id": "uuid-here",
"date": "2026-03-15",
"client": "ABC Homes Ltd",
"description": "Bathroom renovation - 42 Rimu St",
"amount_excl_gst": 8500.65,
"gst": 1274.35,
"amount_incl_gst": 9775.00,
"invoice_number": "INV-2026-015",
"status": "paid",
"created_at": "2026-03-15T14:30:00Z"
}
]
[
{
"id": "uuid-here",
"name": "DeWalt DCS570 Circular Saw",
"category": "portable_power_tools",
"purchase_date": "2026-01-15",
"cost": 899.00,
"dv_rate": 0.40,
"sl_rate": 0.30,
"method": "DV",
"business_percent": 100,
"disposed": false,
"disposal_date": null,
"disposal_amount": null,
"created_at": "2026-01-15T10:00:00Z"
}
]
{
"years": {
"2025": {
"tax_year_end": "2025-03-31",
"gross_income": 95000.00,
"total_expenses": 42000.00,
"depreciation": 3500.00,
"taxable_income": 49500.00,
"tax_on_income": 7582.50,
"acc_levy": 826.50,
"total_tax": 8409.00,
"tax_already_paid": 0,
"residual_income_tax": 8409.00
}
}
}
When the user sends an image (check for MediaPaths in context):
Use your vision capabilities to analyze the receipt image. Extract:
{
"merchant": "Bunnings Warehouse",
"date": "2026-03-15",
"items": [
{ "description": "Timber 2x4 3.6m", "quantity": 10, "unit_price": 12.50, "amount": 125.00 },
{ "description": "Concrete Mix 40kg", "quantity": 5, "unit_price": 9.80, "amount": 49.00 }
],
"subtotal": 174.00,
"gst": 22.57,
"total": 174.00,
"gst_number": "123-456-789",
"payment_method": "EFTPOS",
"category": "materials"
}
Extraction rules:
total × 3/23materials, tools, fuel, safety, subcontractor, office, vehicle, otherSend back a summary:
Receipt captured:
Merchant: Bunnings Warehouse
Date: 2026-03-15
Total: $174.00 (GST: $22.57)
Items: Timber 2x4 3.6m x10, Concrete Mix 40kg x5
Category: materials
Reply to save, or correct any details.
After confirmation, append to ~/.openclaw/data/kiwi-receipts/receipts.json:
mkdir -p ~/.openclaw/data/kiwi-receipts
Read existing receipts.json (or start with []), append the new receipt with a generated UUID as id, and write back. Each receipt object:
{
"id": "uuid-here",
"merchant": "...",
"date": "2026-03-15",
"items": [...],
"subtotal": 174.00,
"gst": 22.57,
"total": 174.00,
"gst_number": "...",
"category": "materials",
"payment_method": "EFTPOS",
"created_at": "2026-03-15T10:30:00Z"
}
Create or update config.json with business name and GST number.
Read receipts.json, filter to current GST period, show:
GST Period: Mar-Apr 2026
Total purchases: $1,527.37
Total GST claimable: $199.13
Receipts: 5
By category:
Materials: $882.97 (GST: $115.17)
Tools: $114.00 (GST: $14.87)
Fuel: $131.40 (GST: $17.14)
Safety: $399.00 (GST: $51.95)
Generate and send XLSX report:
python3 {baseDir}/scripts/generate_report.py \
--data ~/.openclaw/data/kiwi-receipts/receipts.json \
--income ~/.openclaw/data/kiwi-receipts/income.json \
--assets ~/.openclaw/data/kiwi-receipts/assets.json \
--tax-history ~/.openclaw/data/kiwi-receipts/tax-history.json \
--output /tmp/gst-report.xlsx \
--period current \
--business-name "from config.json" \
--gst-number "from config.json"
Then send the file back to user via message tool with sendAttachment action.
Generate report for a specific GST period (the 2-month period containing that month).
XLSX report contains up to 7 sheets:
GST101A auto-fill logic:
If income.json has data for the period, BOTH sides are auto-filled:
If no income data exists, Box 5 still shows "enter from accounts" as before.
Remove the most recently added receipt from receipts.json.
Show recent receipts (last 10) with date, merchant, total.
Kiwi Receipts -- Commands:
RECEIPTS:
[Send photo] Capture a receipt
"summary" Current GST period overview
"report" Download GST report (XLSX)
"report 2026-03" Report for specific period
"list" Show recent receipts
"delete last" Remove last receipt
INCOME:
"income 9775 description" Record sales invoice
"income list" Show recent income
"income summary" Period income total
ASSETS:
"asset add name $cost" Register depreciable asset
"asset list" Show assets with book values
"asset dispose name $price" Record asset disposal
"depreciation" Calculate this year's depreciation
TAX:
"provisional" Calculate provisional tax
"set last year tax 8409" Set previous year RIT
"tax return" / "ir3" Annual tax summary
"export ir3" Annual XLSX report
EXPORT:
"xero export" Generate Xero-importable CSV
SETUP:
"setup" Configure business details
"help" This message
Record a sales invoice or payment received:
User: income 9775 Bathroom renovation - 42 Rimu St, ABC Homes
Parse:
Confirm:
Income recorded:
Client: ABC Homes
Description: Bathroom renovation - 42 Rimu St
Amount: $9,775.00 (GST: $1,274.35)
Date: 2026-03-19
Reply to save, or correct any details.
After confirmation, append to ~/.openclaw/data/kiwi-receipts/income.json.
Show last 10 income entries with date, client, amount.
Show current GST period income total:
Income Summary: Mar-Apr 2026
Total income (incl GST): $28,500.00
Total GST on income: $3,717.39
Invoices: 4
Record a new business asset:
User: asset add DeWalt circular saw $899
Parse:
references/nz-depreciation-rates.mdIf cost is $1,000 or less (excl GST): inform user this can be expensed immediately. Still record it.
Confirm:
Asset recorded:
Name: DeWalt circular saw
Cost: $899.00 (excl GST)
Category: Portable power tools
Depreciation: DV 40% (estimated life 5 years)
Year 1 claim: $359.60
This asset costs under $1,000 -- you can alternatively expense it
immediately in the year of purchase. Reply "expense" to do that,
or "depreciate" to spread over 5 years.
Save to ~/.openclaw/data/kiwi-receipts/assets.json.
Show all assets with current book value:
Assets Register:
1. DeWalt circular saw -- cost $899, book value $539.40 (DV 40%)
2. Toyota Hilux -- cost $45,000, book value $31,500.00 (DV 30%)
3. Scaffolding set -- cost $3,200, book value $2,784.00 (DV 13%)
Mark an asset as disposed. Calculate depreciation recovery or loss:
User: asset dispose DeWalt circular saw $200
Bot: Asset disposed:
DeWalt circular saw
Book value: $539.40
Sale price: $200.00
Loss on disposal: $339.40 (deductible)
Calculate this year's total depreciation for all active assets:
Depreciation Schedule 2025-2026:
DeWalt circular saw: $215.76 (DV 40%, book: $539.40 -> $323.64)
Toyota Hilux (70% business): $6,615.00 x 70% = $4,630.50
Scaffolding set: $416.00
Total depreciation: $5,262.26
For each active (non-disposed) asset:
DV method:
book_value = cost
for each completed year since purchase:
depreciation = book_value * dv_rate
book_value = book_value - depreciation
current_year_depreciation = book_value * dv_rate * business_percent/100
SL method:
annual_depreciation = cost * sl_rate
current_year_depreciation = annual_depreciation * business_percent/100
Partial year: If purchased part-way through the tax year (April-March), pro-rate:
months_owned = months from purchase date to 31 March (or today)
partial_rate = months_owned / 12
depreciation = full_year_depreciation * partial_rate
Calculate provisional tax based on tax history:
tax-history.json for previous year's residual income tax (RIT)Provisional Tax 2026-2027:
Based on 2025-2026 RIT: $8,409.00
Uplift (x 1.05): $8,829.45
Per instalment: $2,943.15
Payment schedule:
1st instalment: 28 August 2026 -- $2,943.15
2nd instalment: 15 January 2027 -- $2,943.15
3rd instalment: 7 May 2027 -- $2,943.15
Set the previous year's residual income tax for provisional tax calculation:
User: set last year tax 8409
Bot: Saved. Previous year RIT: $8,409.00
Provisional tax this year: $8,829.45 ($2,943.15 x 3 instalments)
Save to tax-history.json.
Generate a complete annual tax summary. Reads from all data files for the tax year (1 April - 31 March):
Annual Tax Summary: 2025-2026
INCOME:
Gross business income (from invoices): $95,000.00
GST on income: $12,391.30
Income excl GST: $82,608.70
EXPENSES (from receipts):
Materials: $28,500.00
Tools: $3,200.00
Fuel: $4,800.00
Vehicle: $2,100.00
Safety: $1,500.00
Subcontractors: $8,000.00
Office: $900.00
Other: $500.00
Total expenses: $49,500.00
DEPRECIATION:
Portable power tools: $1,200.00
Motor vehicle (70%): $4,630.50
Scaffolding: $416.00
Total depreciation: $6,246.50
TAX CALCULATION:
Gross income: $82,608.70
Less expenses: -$49,500.00
Less depreciation: -$6,246.50
Taxable income: $26,862.20
Tax on $26,862.20:
$15,600 @ 10.5% = $1,638.00
$11,262.20 @ 17.5% = $1,970.89
Total tax: $3,608.89
ACC earner's levy: $448.60
Less provisional tax: -$2,943.15
Tax to pay: $1,114.34
Reply "export ir3" to generate the XLSX report.
Generate XLSX with annual sheets added. Run:
python3 {baseDir}/scripts/generate_report.py \
--data ~/.openclaw/data/kiwi-receipts/receipts.json \
--income ~/.openclaw/data/kiwi-receipts/income.json \
--assets ~/.openclaw/data/kiwi-receipts/assets.json \
--tax-history ~/.openclaw/data/kiwi-receipts/tax-history.json \
--output /tmp/annual-tax-report.xlsx \
--period all \
--business-name "from config.json" \
--gst-number "from config.json"
Generate a CSV file importable into Xero as bank transactions:
python3 {baseDir}/scripts/generate_report.py \
--data ~/.openclaw/data/kiwi-receipts/receipts.json \
--income ~/.openclaw/data/kiwi-receipts/income.json \
--output /tmp/xero-export.csv \
--format xero-csv \
--period current
Xero CSV format:
Date,Amount,Payee,Description,Reference,Category
15/03/2026,-174.00,Bunnings Warehouse,"Timber 2x4 x10, Concrete Mix x5",,Cost of Goods Sold - Materials
16/03/2026,-65.00,Z Energy,Fuel,,Motor Vehicle Expenses - Fuel
17/03/2026,9775.00,ABC Homes Ltd,Bathroom renovation - INV-2026-015,,Sales
Category to Xero account mapping:
| Kiwi Receipts Category | Xero Account Name |
|---|---|
| materials | Cost of Goods Sold - Materials |
| tools | Tools and Equipment |
| fuel | Motor Vehicle Expenses - Fuel |
| vehicle | Motor Vehicle Expenses |
| safety | Health and Safety |
| subcontractor | Subcontractor Expenses |
| office | Office Expenses |
| other | General Expenses |
| (income) | Sales |
User imports into Xero: Accounting > Bank Accounts > [Account] > Import Statement.
NZ GST periods (2-monthly, most common for small business):
Per the Goods and Services Tax Act 1985 (NZ) and IRD guidelines:
Per the Income Tax Act 2007 and Tax Administration Act 1994: