CommunityProductivity & Collaborationgithub.com

3447nazmul/smb-bookkeeper-repo

Create a printable invoice, quote or receipt from one small input, log expenses to a plain ledger, list overdue invoices with the next payment reminder drafted in plain English or simple Bengali, and see a simple cash-flow view — for non-technical small businesses. Use when a small business owner needs an invoice from a messy message, wants to know who owes them money and what to write next, or wants this month's money in, money out and money owed on one screen.

What is smb-bookkeeper-repo?

smb-bookkeeper-repo is a Claude Code agent skill that create a printable invoice, quote or receipt from one small input, log expenses to a plain ledger, list overdue invoices with the next payment reminder drafted in plain English or simple Bengali, and see a simple cash-flow view — for non-technical small businesses. Use when a small business owner needs an invoice from a messy message, wants to know who owes them money and what to write next, or wants this month's money in, money out and money owed on one screen.

Works with✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/3447nazmul/smb-bookkeeper-repo/tree/HEAD

Installed? Explore more Productivity & Collaboration skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

SMB Invoice + Bookkeeping

One messy message → invoice, expense log, and the next reminder draft. No account, no subscription, no lock-in — your money, in files you own.

Small businesses do not fail on the work. They fail on the waiting: about 55% of B2B invoices in North America are paid late (Atradius, via Crestmont Capital, updated 2026), US small businesses waited an average 29.3 days to be paid in Q2 2026, ~9 days past the due date (Xero Small Business Insights, via Foundrly, Aug 2026), and 82% of small business failures are attributable to cash-flow problems (US Chamber of Commerce, via Crestmont, 2026). The chance of collecting falls fast with age — over 95% in the first 30 days with proactive follow-up, down to 20–30% beyond 120 days (Crestmont, 2026). The invoice is the easy part. The chasing is the product — and everywhere else the chase is paywalled: automatic reminders are Pro-only at Wave ($19/mo) and Invoice Ninja ($14/mo) (vendor pricing pages, Nov 2026), Wave cannot send invoices outside the US/Canada (Wave support, 8 Sep 2026), and Zoho Invoice's free tier caps at 500 invoices/year and deletes idle data after 180 days (zoho.com/invoice/pricing, read 2026-11-11). This skill drafts the chase for free.

Version 0.2.0. Rebuilt from the v0.1.0 adversarial review (20 gaps, all fixed or recorded in MEASUREMENTS.md §11) and the deep-research corrections (research-notes-v2.md §1). What changed is in CHANGELOG.md. The numbers below are real runs on the bundled sample data, not estimates.

Not legal, tax, or financial advice. This skill helps you create invoices and track money. Tax rates, registration thresholds, and invoice requirements differ by country and change over time. Set your own tax rate, and confirm the rules for your business with your local tax authority (in Bangladesh: the National Board of Revenue, nbr.gov.bd) or a qualified accountant. This disclaimer is also printed in the footer of every generated invoice and receipt — in Bengali on the Bengali documents. For the record-keeping rules behind it (what to keep, TIN/BIN on invoices, Mushak forms, retention), see the reference companion: OpenAccountants' bd-bookkeeping skill (openaccountants/openaccountants, 484★, updated 2026-11-11) — an English-language reference guide, explicitly "general reference only… not reviewed for any specific person's facts". It does not generate invoices. This skill does.

Run it

python3 scripts/bookkeeper.py <command>

Python ≥ 3.9, standard library only. No install step, no dependencies, no network call, no API key, no account. Data lives in plain JSON files you can open, copy, and take anywhere.

Money rules — read before trusting any number

These are the rules that make the totals trustworthy, and the ones the v0.1.0 review caught this skill breaking:

  • Money rounds half-up (ROUND_HALF_UP), the way a shop owner rounds with a calculator — never banker's rounding. ৳2.345 is ৳2.35.
  • Quantities are exact, never rounded as money. A qty of 1.005 is 1.005; only the line total rounds. Quantities print without trailing zeros (3, never 3.00).
  • Tax is per line, on the discounted line amount — each line's tax rounds half-up on that line, then sums (the way Wave / Xero / FreshBooks do it). 3 lines of ৳0.35 at 15% tax ৳0.15, not ৳0.16.
  • Paid-ness comes from the balance, never the status string. An invoice marked "paid" with ৳4,000 still owed reports ৳4,000 owed, and the report says the status is wrong. Status is a hint; the overdue state is derived from the due date and the balance.
  • Money is never summed across currencies. A mixed-currency ledger reports per-currency totals (৳5,000 + $100) and refuses a merged total and a merged net — the skill has no FX and says so.
  • A ledger problem is loud and costs exit 2. overdue and cashflow exit 2 when a row is skipped (invalid data), a number is duplicated, a "paid" invoice still has a balance, a payment overpays, or a payment has no paid_date. The report still prints; the exit code says fix the ledger before trusting it.
  • Negative money prints the minus first: −৳4,100 — one convention, everywhere.

The workflow: one input → invoice → receipt → reminder → cash flow

1. Invoice, quote or receipt from one JSON input

python3 scripts/bookkeeper.py invoice --input samples/invoice-input.json --out out/invoice.html --config config/bd.json
python3 scripts/bookkeeper.py invoice --input samples/invoice-input-bn.json --out out/invoice-bn.html --config config/bd.json --lang bn
python3 scripts/bookkeeper.py invoice --input my-quote.json --out out/quote.html --format md
python3 scripts/bookkeeper.py receipt --input samples/invoice-input.json --out out/receipt.html --paid-date 2026-11-05 --amount-paid 4500
  • The input is one small JSON file: business + client + line items (description, quantity, unit price) + invoice number + issue date + due date. See samples/invoice-input.json for the exact shape.
  • Quote → invoice → receipt is one lifecycle, one data model. type: "quote" needs valid_until instead of a due date; an invoice needs a real calendar due date, not just "Net 30"; a receipt is generated from a paid invoice with --paid-date and --amount-paid and shows the remaining বাকি (balance due) if the payment was partial. A receipt with an amount of 0 is refused — a receipt confirms money received. A quote never shows paid/balance rows (nothing is owed on a proposal), in HTML or Markdown, and its number is labelled "Quote number", not "Invoice number".
  • The invoice carries the fields every invoice needs (research notes §3.1): the word "Invoice", a unique sequential number, issue date, due date, seller details, buyer details, specific descriptions, line items, tax as its own line, payment instructions + total due. A quote number is referenced on the invoice when one exists; a client PO number and the seller's tax registration number (tax_id — in Bangladesh, the 13-digit BIN) print on the invoice when given.
  • Numbering is sequential (INV-2026-001, INV-2026-002, …). Never skip or reuse a number — a gap or duplicate looks like missing income or an invented expense at tax time. Ledger commands warn loudly and exit 2 on a duplicate number. The config's numbering_prefix is checked against the invoice number (a warning, not an error); default_terms fills the Terms line when the input has none.
  • Output is clean printable HTML (open it in a browser, print to PDF) or Markdown (--format md). No external resources in the HTML, so it prints exactly as it looks — the shipped samples were rendered in headless Chromium and printed to PDF once (see MEASUREMENTS.md §11.6, screenshots in docs/).
  • Money is computed with Decimal, never float. Discount is a percentage of the subtotal, applied per line; tax is per line on the discounted amount (see "Money rules").
  • Validation is strict and the exit code is 2 on bad input: missing due date, negative quantity or price, tax rate outside 0–100%, bad dates, malformed JSON, missing file, a due date before the issue date, a payment dated before the issue date. A zero-item invoice is allowed (total ৳0) but prints a warning — it is a draft, not a mistake to hide. Overpaying a document prints a warning on both document commands (a receipt should never show "Balance due: ৳-825").

2. Tax — a setting you type in, never a hard-coded rate

# In the invoice input (this is the ONLY place a rate lives):
"tax": {"name": "VAT", "rate_percent": 15}
  • No tool hard-codes a rate, and neither does this skill. Every invoicing tool (Zoho, FreshBooks, Wave, Xero — research notes §5.1) lets the user define a named tax + percentage, applies it per line, and shows it as a separate line. This skill copies that exactly: tax is a named tax + rate % in the input, default 0% / no tax.
  • Country presets in config/ supply the tax label, the currency, the payment methods, the default terms, and the numbering prefix — never a rate. config/bd.json (Bangladesh: ৳, "VAT", bKash / Nagad / Rocket / bank transfer / cash) and config/us.json (US: $, "Sales tax", Net 30). tax_rate_percent in both configs is null on purpose. A tax_id in the config (your BIN) fills the invoice when the input has none.
  • The sample invoice uses 15% VAT because the sample input says so — Bangladesh's standard VAT rate is 15% under the VAT and Supplementary Duty Act 2012 (ArthiKalap, updated 25 Jul 2026; TRW, FY 2026-27; TaxDo, 2026; SDTT Academy, early 2026) — but the skill does not know that, and must never be quoted as knowing it. VAT returns are monthly again (due within 15 days): the Finance Act 2026 made them quarterly from 1 Jul 2026, but an amending ordinance gazetted 14 Oct 2026 restored monthly returns (TRW "Doing Business in Bangladesh 2026", law as at 24 Oct 2026; entrepreneurs.bd, 2026). Any "quarterly" line in older notes is now wrong.
  • Registration thresholds are NOT hard-coded in this skill. Three independent Oct–Nov 2026 guides now converge on the same figures — compulsory registration above Tk 50 lakh annual turnover; enlistment for Tk 30–50 lakh at 4% turnover tax; some activities register regardless of turnover (TRW "VAT in Bangladesh 2026", position 18 Oct 2026; TRW "VAT Registration"; entrepreneurs.bd, 2026; Aniday, verified Sep 2026). But direct verification against NBR was not achieved: the NBR homepage (loaded 2026-11-11) carries no threshold text, and vat.gov.bd was unreachable that day. So these figures are reported here as converging secondary sources, not NBR-verified fact — the skill never states a threshold as its own, and points users to nbr.gov.bd. The BIN is 13 digits (NBR homepage service listing, 2026-11-11 — a label, not a gazette; confirm the digit count in the NBR VAT registration guide when you check the thresholds).
  • Tax-inclusive prices are supported: "tax": {"name": "VAT", "rate_percent": 15, "inclusive": true} extracts the tax from the gross price (VAT = gross × 15 ÷ 115). Measured in MEASUREMENTS.md §5: ৳1,150 gross → ৳150 VAT, total stays ৳1,150.

3. Expense log — plain language, plain files

python3 scripts/bookkeeper.py expense add --ledger expenses.json --date 2026-11-11 --category Materials --amount 1200 --note "copper wire, 20 m"
python3 scripts/bookkeeper.py expense list --ledger expenses.json --month 2026-11
python3 scripts/bookkeeper.py expense export --ledger expenses.json --out expenses.csv
  • One expense = date, category, amount, note. The ledger is a JSON list; export writes a CSV that opens in any spreadsheet.
  • Categories are plain language, not a chart of accounts: Materials, Transport, Tools, Mobile/internet, Meals, Rent, Labour, Packaging, Other. An unknown category is an error, never silently accepted. Negative amounts are rejected. --month must be a real YYYY-MM (2026-1 is rejected — a raw prefix match would silently merge October and November).
  • A ledger row that is not an object is skipped loudly with a warning and exit 2 — never a traceback, never silent. expense add refuses to rewrite a ledger that contains a broken row (fix it first).

4. Overdue tracker + reminder drafts — the centre of the skill

python3 scripts/bookkeeper.py overdue --invoices samples/invoices.json --as-of 2026-11-11
python3 scripts/bookkeeper.py overdue --invoices samples/invoices.json --as-of 2026-11-11 --lang bn --json
  • Scans the invoice ledger, lists every open invoice by age bucket (current / 1–30 / 31–60 / 61–90 / 90+ days overdue), and drafts the next reminder at the right stage for each one.
  • The 6-stage sequence (the 5-touch consensus across Raoura, verified Jul 2026; InvoiceCub, 31 Oct 2026; InvoiceFly, ~Nov 2026; HeroThemes, ~Aug 2026; FreelanceDesk, ~Jun 2026 — pre-due, due date, 7, 14, 30 days — plus the early friendly nudge for 1–6 days overdue from the 7-touch version; the 7-touch version's extra 21-day touch is not a separate stage, its ground is covered by the 14-day draft's next touch at day 30): 3 days before due, on the due date, 7 days overdue, 14 days overdue, 30 days final notice, plus the 1–6-day nudge. Graduated escalation, never accusation first: assume good intent early (forgot / buried / in an approval queue); mention a late fee only when the agreement provides one and the invoice is ~2 weeks overdue. Every draft restates invoice number, amount, the original due date — and the real days overdue (an 8-day invoice is told "8 days overdue", never the stage number).
  • Drafts only — the skill never sends anything. You send the reminder. The report also prints the next touch date, so the escalation does not depend on remembering. A next touch that is already past prints as "send now (was due …)", never as a bare past date. The final notice gives a deadline 7 days out from today at the earliest (max(due + 37 days, as-of + 7 days)) — a demand whose deadline already passed is worse than no demand.
  • Measured on the samples (as of 2026-11-11): 6 open invoices, ৳48,650 owed to you (বাকি), 4 overdue totalling ৳28,250 — one at each stage from nudge to final notice. See MEASUREMENTS.md §3.
  • Draft invoices are excluded from "owed to you" — an unsent invoice is not money owed yet. Paid invoices (balance 0) are excluded too. (Businesses that follow up on 100% of overdue invoices are 76% more likely to be paid within a week — Chaser 2026 AR Report, via Raoura, second-hand.)

5. Simple cash-flow view — the numbers the owner actually checks

python3 scripts/bookkeeper.py cashflow --invoices samples/invoices.json --expenses samples/expenses.json --month 2026-11 --as-of 2026-11-11
  • One month, five numbers: invoiced this month, money in (paid), money out (expenses), net cash this month, owed to you (বাকি). Money in counts invoices by their paid_date, not their issue date — a late payment lands in the month it arrived. A payment recorded with no paid_date is warned about loudly (it can belong to no month) and the command exits 2.
  • Draft invoices are NOT counted as invoiced — they get their own line ("drafts not yet sent"), so the number is honest.
  • Measured on the samples: November 2026 — invoiced ৳20,400, drafts not yet sent ৳7,300, received ৳4,500, expenses ৳8,600, net −৳4,100, owed ৳48,650. The negative month is the honest story of the sample: one late payment in, three weeks of work still unpaid.
  • Money you owe (bills to pay) is not tracked in v0.2.0 — the command says so in its output. See "What v0.2.0 still does not cover".

6. The 60-second demo + the verify command

python3 scripts/bookkeeper.py demo --outdir out/demo
python3 scripts/bookkeeper.py overdue --invoices samples/invoices.json --as-of 2026-11-11
python3 scripts/bookkeeper.py cashflow --invoices samples/invoices.json --expenses out/demo/expenses-demo.json --month 2026-11 --as-of 2026-11-11
python3 scripts/bookkeeper.py verify

One demo command, sample data only: an English invoice, a Bengali invoice, a receipt for the documented partial payment (৳4,500 paid, বাকি ৳675), an expense added to a demo copy of the ledger, then the two commands above for the overdue report and the cash-flow view. The demo never writes into samples/. verify runs the bundled test suite (tests/test_bookkeeper.py, 45 tests — happy paths plus every adversarial input from the v0.2.0 review) and must pass before any version is called done.

Simple Bengali — a first-class feature, not a footnote

  • Full Bengali invoice template (--lang bn): every field label in Bengali, dates in Bengali digits (২০২৬-১১-০২), and the disclaimer in Bengali in the footer — the most important text on the document is readable to the non-English-reading shop owner the template is for.
  • বাকি (credit / amount owed) is a first-class concept, not generic "accounts receivable". It is named on every invoice, every receipt, and every overdue line. Bangladesh's biggest bookkeeping apps are built around it — Bakir Khata (বাকির খাতা) is named after it — and this skill models it the same way: a sale splits into a cash part and a due part, a later payment is partial or full, and the ledger shows what is still owed per invoice.
  • Bengali reminder drafts for all six stages, in formal আপনি throughout, firm but never rude at the late stages. The subjects say what they mean: "৮ দিন পেরিয়ে গেছে" (8 days have passed), never "৮ দিন বাকি" — বাকি in a subject line reads as "days remaining", the opposite of "days overdue". Nagad the wallet is labelled "নগদ (মোবাইল ব্যাংকিং)" so it can never be confused with "নগদ টাকা" (cash).
  • Payment lines for a Bangladeshi invoice: bKash / Nagad / Rocket
    • bank transfer + cash — the methods the local apps list.
  • An honest correction to the pitch: Bengali invoicing tools already exist and are mature as apps (Bakir Khata claims 500,000+ businesses, self-reported, but its free plan covers only 10 customers and Premium starts at BDT 500/year; HishabPati, HishabEasy, Hisab Digital, KarbarX, Hisabun, TakaTracker, Amar Karobar — all found 2026-11-11). And a Bangladesh bookkeeping reference skill already exists: OpenAccountants' bd-bookkeeping (484★, updated 2026-11-11) — English reference material, no invoice generation, no reminder drafting, no বাকি ledger, no Bengali output. What does not exist is a Bengali-language skill that actually generates invoices, runs a বাকি ledger, and drafts the payment chase — two GitHub API searches for Bengali/Bangla skill terms on 2026-11-11 returned 0 repos. That is this skill's claim, and no bigger one: "the first Bengali-language invoice-generating skill" — not "the first Bengali invoicing tool", and not "the first Bangladesh skill".

What this skill is not

  • It does not collect payments. No payment links, no card processing — that is Wave / Zoho / Stripe's job. Free invoicing as SaaS is already solved: Wave and Zoho Invoice give away at $0 almost everything this skill generates, and they also collect the money. This skill does not compete with them on features. Its differentiation is different in kind: no account, no subscription, no lock-in (and no 10-customer free cap, no 180-day data deletion, no US/Canada-only restriction); plain language, not accounting language; Bengali-first output; works in the chat from one message; the reminder sequence is the product — and it is free.
  • It is not accounting software. No double-entry, no bank reconciliation, no payroll, no inventory — that is QuickBooks / Xero territory. It does not replace an accountant — the disclaimer above is on every invoice for a reason.

Honesty rules

  • A number is only stated with its source and date. The pain statistics in this file are from the research notes (§2, §4), each with its source and 2026 date. Competitor prices are snapshots from Nov 2026 vendor pages — verify on the vendor's own pricing page before quoting them; this skill's README does not quote them as permanent.
  • No fake claims, ever. No invented prices, rates, or star counts. No "trusted by 1,000 businesses", no invented testimonials, no fake client results. All sample data is labelled SAMPLE, with placeholder phone numbers and an example.com email.
  • No hard-coded tax rate, threshold, or legal claim. Tax is a user setting; thresholds are not stated as verified fact anywhere in the skill (see §2).
  • Star potential, honestly: the highest-starred finance-adjacent skill on GitHub is 105★ (erp-mafia/accounted-skills, Swedish compliance, verified 2026-11-11); the invoice-lane leader is 40★ (Dangooy/trade-pipeline-skill, verified 2026-11-11); the closest direct competitor is 22★ (vpodugu/startup-bookkeeper, verified 2026-11-11). A realistic outcome is hundreds to low-thousands of stars. (Invoice Ninja's own open-source repo is 10,567★ — but that is the upstream project, not a Claude skill.)
  • The closest competitors are named, not hidden. vpodugu/startup-bookkeeper does conversational expense/invoice/ subscription tracking in Claude (no printable invoice, no reminder drafting, no Bengali, no partial payments — research-notes-v2 §3.4). OpenAccountants' bd-bookkeeping is the Bangladesh reference guide (see above). This skill differentiates on plain language + Bengali output, the quote→invoice→receipt lifecycle, printable invoice files, the reminder sequence, and the cash-flow view. That is packaging, not a moat — and the skill says so.
  • When the tool cannot do something, it says so. Empty ledgers print honest zeros and exit 0 — the expense list says "empty ledger", while overdue and cashflow print 0 invoices and ৳0 totals (they never use the words "empty ledger"); a zero-item invoice prints a warning, and so does one whose lines all have quantity 0; the cash-flow command states that money you owe is not tracked; a mixed-currency ledger refuses a merged total. A zero is a measurement, not a failure.

What v0.2.0 still does not cover

  • Recurring invoices (monthly retainers) with auto-drafting.
  • Late-fee calculation. The 14-day and final drafts mention a late fee only if the agreement provides one — the skill never computes one, because no rate is ever set by default.
  • Multi-currency with FX notes (no live rates). Mixed ledgers refuse merged totals; conversion is not attempted.
  • Monthly summary export for the owner's accountant (the expense CSV export is the closest thing; an invoice summary export is still open).
  • Client list with per-client totals and "who owes me most" ranking.
  • Money you owe (bills to pay / payables) — expenses are cash out only; supplier credit is not modelled.
  • Partial-payment tracking across multiple payments: amount_paid is a single field. A second payment overwrites the first unless you add them up first.
  • No HTML→PDF conversion built in — the HTML is print-ready; print to PDF from the browser (verified once in headless Chromium, see MEASUREMENTS.md §11.6). No PDF library is bundled, deliberately: stdlib only.
  • Invoice numbering is the owner's job: the skill does not keep a counter. It does warn loudly and exit 2 on a duplicate number — check the ledger before issuing the next number.
  • Bengali wording was corrected against the v0.2.0 review's concrete findings (subjects, Nagad/cash, disclaimer, dates) but has still not been reviewed by a native Bengali business owner — that read-through is an open item.

Related Skills