Skip to content
Romanovich.Back to projects
Case · 06 · 2026

Receipt Scanner.

Desktop tool that reconciles photo receipts against a 14-page bank statement, every month.

Client
Accounting team, EU operations
Role
Solo, end to end
Stack
Python · Apple Vision · Claude · pdfplumber · pydantic
Year
2026

The problem.

An EU company runs operations in Slovakia and Hungary. Every month the accountant reconciles 30 to 50 photo receipts against a 14-page Fio banka statement, around 150 transactions in EUR with some HUF and CZK.

Manual reconciliation took 4 to 6 hours per month. Small receipts went missing. By the end of the quarter someone had to call the client and ask for documents nobody remembered.

The approach.

I started from a fork of an open-source linker built around Gemini and US receipts. Kept the parts that worked. Replaced everything else.

Statement parsing moved from a vision model to pdfplumber plus a text-only Claude call. Apple Vision runs OCR locally on macOS for simple receipts. Claude vision steps in only when the local engine is uncertain.

4-6 h → 2-3 minmonthly workload
$0.10-0.15per full reconciliation
70-85%receipts processed offline
2 passesexact + fuzzy matcher

Decisions worth explaining.

Desktop interface.

Drop-zone on the left for receipts, on the right for the statement PDF. Side panel for API key, report path, model, and date window. Bottom row is the progress bar and an Open Excel button. customtkinter on top of tkinter, light theme, no terminal.

Outcomes.

  • Monthly reconciliation dropped from 4-6 hours to 2-3 minutes.
  • Hybrid OCR keeps 70 to 85 percent of receipts free and offline.
  • Re-running on the same files is free thanks to the SHA256 cache.
  • Missing-receipt discoveries happen the same week, not at quarter end.

What's next.

If the volume grows past 100 receipts a day, three switches sit ready: Anthropic Batch API for a 50 percent input discount, Gemini Flash through litellm with one config line, and prompt caching on the system prompt. The architecture takes all three without rewrites.