DEV Community

Cover image for InvoiceGenie: The 100% Private, Local AI Financial Assistant & Receipt Sorter 🧾
A K
A K

Posted on

InvoiceGenie: The 100% Private, Local AI Financial Assistant & Receipt Sorter 🧾

What I Built

Meet InvoiceGenie—a local, offline AI-powered financial assistant and receipt sorter designed specifically for freelancers, independent contractors, and small business owners.

The Problem: Freelancers juggle multiple clients, irregular invoices, software subscriptions, and messy expense receipts. Manual bookkeeping is tedious, and commercial cloud-based finance tools either charge expensive monthly subscriptions or pose serious data privacy risks when handling sensitive client billing details.

The Solution: InvoiceGenie runs entirely on a laptop with zero internet required. A user can paste raw, unstructured text (like a messy receipt, an email confirmation, or rough notes about a business purchase), and local open-weight AI instantly extracts structured expense logs, tax-ready categories, and professional client payment reminders.

Demo
InvoiceGenie features a clean, responsive web interface built with Streamlit, backed by Ollama (gemma2:2b), and launched instantly using a zero-friction Windows batch script (run.bat).

Local Execution Snapshot:

http://localhost:8501 — Running 100% locally with zero cloud API latency or dependency.
**

Code

**
The project is structured for simplicity, portability, and zero-command setup:
InvoiceGenie/
├── app.py # Streamlit user interface & Gemma 2 prompt handler
└── run.bat # All-in-one dependency checker & automated app launcher

You can find the core application logic in app.py:

import streamlit as st
import ollama

st.set_page_config(
    page_title="InvoiceGenie",
    page_icon="🧾",
    layout="wide"
)

st.title("🧾 InvoiceGenie: Local AI Receipt & Invoice Sorter")
st.caption("Turn messy client notes, receipts, and billing emails into clean financial logs | 100% Private & Local")

with st.sidebar:
    st.header("⚙️ Settings")
    task_type = st.selectbox(
        "Select Task:",
        ["Extract Invoice / Receipt Details", "Draft Client Payment Reminder", "Categorize Business Expense"]
    )
    st.divider()
    st.success("🔒 Privacy First: Financial data never leaves your laptop.")
    st.info("💡 Side Hustle Value: Saves freelancers hours of bookkeeping with $0 API costs.")

col1, col2 = st.columns([1, 1])

with col1:
    st.subheader("📥 Raw Notes or Receipt Text")
    raw_input = st.text_area(
        "Paste messy receipt text, invoice draft, or client email:",
        value="Bought 3 design software licenses for $150 each on Oct 10 from Adobe via business credit card. Need to log this for client project Alpha.",
        height=180
    )

with col2:
    st.subheader("🎯 What InvoiceGenie Generates")
    st.markdown("""
    - **Structured Expense Log:** Vendor, date, amount, and category.
    - **Tax-Ready Breakdown:** Clear itemization for bookkeeping.
    - **Professional Email Draft:** Polished client-facing communication.
    """)

if st.button("✨ Process with Local Gemma 2", type="primary", use_container_width=True):
    if not raw_input.strip():
        st.warning("Please enter some text first!")
    else:
        with st.spinner("Gemma 2 is analyzing your financial data locally..."):
            system_prompt = (
                "You are an expert freelance accountant and financial assistant. "
                "Analyze the provided text and format your response cleanly using exact Markdown headers:\n"
                "### 📊 Structured Financial Breakdown\n"
                "### 🗂️ Bookkeeping & Tax Category\n"
                "### ✉️ Actionable Output or Draft"
            )

            try:
                response = ollama.chat(
                    model="gemma2:2b",
                    messages=[
                        {"role": "system", "content": system_prompt},
                        {"role": "user", "content": f"Task: {task_type}\nInput: {raw_input}"}
                    ]
                )

                result = response["message"]["content"]

                st.markdown("---")
                st.markdown("## 📋 Analysis Result")
                st.markdown(result)

            except Exception as e:
                st.error(f"Could not connect to local Ollama server: {e}")
Enter fullscreen mode Exit fullscreen mode

How I Built It
InvoiceGenie relies entirely on open-source and open-weight technology:

Model: Google's Gemma 2 (gemma2:2b) running locally via Ollama. It provides lightning-fast local inference optimized for text structuring and summarization.

Framework: Streamlit for building an interactive, clean Python web UI.

Automation: A custom Windows batch launcher (run.bat) that verifies environment requirements, handles dependency checks, and boots the app with a single double-click.

Why Does Open Innovation Matter?
Open innovation and local open-weight models made InvoiceGenie possible in ways a closed API never could:

Absolute Data Privacy: Freelancers frequently handle confidential client receipts, proprietary project briefs, and banking details. Sending raw financial data to third-party cloud APIs violates client trust and NDAs. Running Gemma 2 locally guarantees that financial data never leaves the laptop.

Zero Operating Costs ($0 API Fees): Commercial AI wrapper tools charge monthly subscriptions because of backend token costs. With local inference, a freelancer can process hundreds of receipts daily with zero marginal cost, making a solo side hustle genuinely profitable.

Offline Reliability: Freelancers work from cafes, trains, and remote spots. InvoiceGenie runs completely offline without depending on cloud uptime or internet connectivity.

My First User
To test InvoiceGenie in the wild, I had a peer who freelances in graphic design run their actual software subscription receipts and client invoice notes through the tool.

Feedback: They loved how instantly it categorized business expenses for tax season without manual data entry.

Would they pay? They immediately asked if they could install it on their backup laptop and noted they would gladly pay a one-time fee for a packaged desktop version to keep their client records entirely offline away from SaaS subscription bloat!

Top comments (0)