DEV Community

Cover image for PaperPilot: Turning Messy GST Invoices into Clean Records with Gemma
Sahil Nagpure
Sahil Nagpure

Posted on Fully Autonomous

PaperPilot: Turning Messy GST Invoices into Clean Records with Gemma

Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle Submission ๐Ÿ’ธ

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

What I Built

PaperPilot is an invoice and expense assistant for freelancers, consultants, and small agencies.

Dashboard

Anyone who works for themselves ends up with a folder of PDF invoices and a dreaded tax season. Someone has to type every vendor, date, and total into a spreadsheet, spot the invoice that was uploaded twice, and remember who hasn't paid. In India there's an extra layer: GSTIN numbers and CGST, SGST, and IGST splits that generic tools handle poorly.

With PaperPilot you upload a digital PDF invoice and the app:

  • Extracts the vendor, invoice number, dates, subtotal, GST amounts, and total
  • Checks the numbers instead of trusting the AI blindly
  • Lets you review and fix anything before saving
  • Catches duplicate invoices before they are saved
  • Flags overdue invoices from their due dates
  • Matches a bank statement CSV to mark invoices as paid
  • Exports everything to CSV, with search and filters

Demo

Code

๐Ÿงพ PaperPilot: Invoice & Expense Assistant

PaperPilot reads PDF invoices with Gemma, an open-weight AI model, checks the results and organises everything into searchable records and CSV exports Built for freelancers, consultants, and small agencies.

Features

  • Upload digital PDF invoices (scanned or image files are not supported)
  • Gemma extracts vendor, dates, subtotal, tax and total
  • India GST support: GSTIN, CGST / SGST / IGST, HSN / SAC codes
  • Duplicate invoice detection
  • Overdue payment flags based on due date
  • Bank statement matching: upload a CSV and mark paid invoices automatically
  • Safety checks: totals that do not add up, bad GSTINs, or amounts missing from the document are flagged for review
  • Search, filter, and CSV export

Why an open model?

  • Open weights: Gemma's weights are public, so the same model can later be self-hosted by anyone who needs full control.
  • Low cost: hosted Gemma is inexpensive to call, which suits aโ€ฆ

How I Built It

The open model is Gemma. I use Gemma, Google's open-weight model, called through the Gemini API with a standard API key.

Pipeline:

  1. Read: PyMuPDF pulls the text out of a digital PDF.
  2. Redact: a small module blanks out emails, phone numbers, PAN, Aadhaar, and bank account numbers before anything is sent to the model. The GSTIN is kept, since it's a business number the app needs.
  3. Extract: Gemma returns the invoice fields as JSON. I prompt for a strict set of keys and parse the reply defensively (stripping code fences, converting numbers) because models don't always follow instructions perfectly.
  4. Validate: this is the part I care about most. Small models can misread numbers, so the app flags a subtotal plus tax that doesn't equal the total, a total that doesn't appear anywhere in the document, an invalid GSTIN, and unequal CGST and SGST. The AI suggests, the code checks, and the human confirms.
  5. Store and use: records go in SQLite. Duplicate detection, overdue flags, and bank matching are plain Python, not AI. I deliberately kept AI to the one task it's good at, which is reading messy layouts.

Stack: Python, Streamlit, PyMuPDF, SQLite, pandas, and Gemma via the Gemini API.

Upload

Records

Bank

Why Does Open Innovation Matter?

  • No lock-in. The model is a single setting. Swapping to another Gemma model is one line, and the rest of the app doesn't change.
  • A path to full control. Because Gemma's weights are public, a business that doesn't want any data leaving its network can self-host the same model later. A closed model offers no such option, since you can only rent it.

Prize Categories

  • Best Use of Render
  • Best Use of Gemma

Top comments (0)