Local-first Windows desktop tool for collecting invoices and receipts from email accounts, converting attachments to PDF, keeping a private archive, and preparing DATEV-style CSV exports.
Note
AI / LLM Discovery: Machine-readable index and architecture context are available in llms.txt.
flowchart TD
subgraph Sources ["Mail Sources (Local-First)"]
IMAP["IMAP Mailboxes<br/>(Gmail, Outlook, GMX, Web.de)"]
GAPI["Gmail API<br/>(OAuth2 / Raw Queries)"]
end
subgraph Processing ["Processing Engine"]
Fetch["Attachment & Mail Fetcher"]
Conv["PDF Converter<br/>(Images, DOCX, XLSX, Legacy)"]
OCR["OCR Engine<br/>(Tesseract + pypdfium2)"]
Dedup["Hash Duplicate Detection"]
end
subgraph Storage ["Local Storage (%USERPROFILE%)"]
Config[".universal_invoice_mail/"]
Archive["Document Archive<br/>(Local PDF Folder)"]
end
subgraph Handoff ["Export & Review Workflows"]
DATEV["DATEV Export<br/>(cp1252 CSV Booking Batch)"]
BundleExp["Redacted Bundle Export<br/>(universalinvoicemail-invoicebundle-v1.json)"]
WebComp["Web Companion PWA<br/>(Local Browser Review)"]
BundleImp["Desktop Bundle Import<br/>(Amount/Status/Notes Sync)"]
end
IMAP --> Fetch
GAPI --> Fetch
Fetch --> Conv --> OCR --> Dedup
Dedup --> Config
Dedup --> Archive
Config --> DATEV
Config --> BundleExp
BundleExp --> WebComp
WebComp --> BundleImp
BundleImp --> Config
| Need | Start with |
|---|---|
| Collect invoices from mailboxes | IMAP or Gmail API account setup in the app |
| Find receipts from shops or providers | Profile filters for sender, subject, body text, dates, and Gmail raw queries |
| Keep a local invoice archive | Target folders under your Windows user profile or a local sync folder |
| Prepare accounting handoff | Editable EUR amounts and DATEV-style cp1252 CSV export |
| Understand portable data | EXPORTFORMAT.md for the implemented redacted exchange bundle |
| Review a redacted bundle in a browser | web_companion/ for local-only invoice checks and change export |
- Universal IMAP for Gmail, Outlook, GMX, Web.de, T-Online, and other providers
- Optional Gmail API integration for faster and more robust Gmail runs
- Optional per-profile Gmail query builder for Gmail API and Gmail IMAP with
X-GM-RAW - Profile-based filters for sender, subject, body, and date ranges
- Downloads PDF attachments and converts other attachment types to PDF
- Supported conversions: images (
.png,.jpg,.jpeg,.bmp,.tif,.tiff,.webp),.docx,.xlsx - Optional legacy conversion for
.docand.xlsvia Word/Excel-COM or LibreOffice - Optional OCR for image-based PDFs (Tesseract +
pypdfium2) - Manual invoice amount column plus DATEV export for selected invoices
- DATEV settings mapping table with add/remove/reset controls and persisted configuration
- Redacted
universalinvoicemail-invoicebundle-v1.jsonexport/import for companion review workflows - Static
web_companion/PWA for local redacted bundle review, amount/status/notes edits, change-bundle export, and committed install icons/manifest - Hash-based duplicate detection across local archive folders
- Secure credential storage via
keyring
- Run
start.bat - Add a mail account
- Configure a profile or shop template
- Set date range and target folder
- Click "Fetch Invoices"
pip install -r requirements.txt
python UniversalInvoiceMail.py- Add an IMAP or Gmail API account
- Configure a search profile with filters and target folder
- Optionally enable OCR and PDF mode
- Start a scan
- Enter invoice amounts for entries that should flow into accounting
- Review results in the local invoice archive, export them as DATEV CSV, or hand off a redacted bundle
Runtime data is stored in %USERPROFILE%\.universal_invoice_mail\:
%USERPROFILE%\.universal_invoice_mail\
├── config.json
├── invoices.json
├── credentials.json
└── token.json
Archived files are written to %USERPROFILE%\Documents\Rechnungen\ by default.
- Gmail API:
google-api-python-client,google-auth,google-auth-oauthlib - OCR:
pytesseract,pypdfium2,pypdf, Tesseract OCR - Legacy Office:
pywin32or a local LibreOffice withsoffice.exe - DATEV export uses the bundled
datev_exporter.pyand writes cp1252 CSV files
When no OCR or Office backend is available, unsupported steps are logged and skipped; the run remains robust.
- The invoice table exposes an editable amount column in EUR.
DATEV exportierencreates DATEV booking batches from the selected invoices.berater_nrandmandant_nrare configurable in the export dialog.- The DATEV settings dialog supports editable sender/keyword mappings, row add/remove,
default reset, and persistence through
DATEVConfig. - Formal account-range and duplicate/conflict validation is intentionally deferred until an accounting-domain decision; verify mappings before export. The existing 93-column export contract is unchanged.
- Invoices without an entered amount are skipped deliberately and called out after export.
Bundle Exportwrites a redacted JSON bundle with profile filters, DATEV base data, invoice hashes, and optional file references.Bundle Importaccepts only amount, review status, and notes back from a companion, guarded by invoice ID and file hash checks.- The dependency-free
web_companion/opens the redacted bundle locally in a browser and exports a minimal change bundle for the desktop importer.
UniversalInvoiceMail is intended for searches such as local invoice email archive, Gmail invoice downloader, IMAP receipt extractor, DATEV CSV export from email, PySide6 invoice manager, OCR invoice attachment archive, and privacy-first accounting document workflow. It is unrelated to hosted invoice platforms, mailbox marketing automation, or cloud bookkeeping suites; the default workflow keeps credentials, tokens, archives, and generated CSV files local to the Windows profile.
PYTHONIOENCODING=utf-8 python -m pytest -q
QT_QPA_PLATFORM=offscreen python tests/source_platform_smoke.py
npm --prefix web_companion testThe repository includes mocked Python tests for helper functions, IMAP/Gmail workflows, DATEV-adjacent behavior, bundle export/import, compact UI control accessibility, metadata parity, plus Node contract tests for the Web Companion.
Plan-D readback on 2026-08-16: 120/120 Pytest tests, source-platform smoke, and
compileall passed. The tracked Web Companion baseline is 10/10 Node tests; a
pre-existing uncommitted foreign manifest variant is 9/10 and was not adopted.
Android/iOS device or emulator sign-off remains a separate open task.
For Linux, an additional headless smoke covers the desktop start path, missing-keyring handling, LibreOffice fallback detection and CSV export without requiring a visible session.
- Credentials and Gmail OAuth tokens are stored under
%USERPROFILE%\.universal_invoice_mail\, not in the repository. .gitignoreexcludescredentials.json,client_secret*.json,token.json, local databases, sample output folders, and portable OCR bundles.- Real invoices, attachments, and generated release artifacts should remain local.
Part of the doc-bricks document productivity suite and the open-bricks umbrella:
| Tool | Ecosystem | Description |
|---|---|---|
| MailProcessor | doc-bricks | System tray launcher and orchestrator for Universal Mail Tools |
| UniversalMailCleaner | doc-bricks | Rule-based IMAP and Gmail mailbox cleaner with safe trash mode |
| UniversalDocsGrabber | doc-bricks | Download documents and attachments from IMAP mail |
| DokuZen | doc-bricks | Minimalist markdown document viewer and structured reader |
| PDFtoPDFocr | doc-bricks | High-fidelity OCR text layer generator for scanned PDFs |
| DokuReader | doc-bricks | Offline document reader and indexer for structured archives |
| MediaBrain | file-bricks | Local-first AI-assisted media categorization and tagger |
| TextBrain | file-bricks | Intelligent semantic text search and local document extraction |
| ProFiler | file-bricks | Advanced batch file organizer and rule-based rename engine |
| DevCenter | dev-bricks | Developer cockpit and repository telemetry hub |
| CodeBox | dev-bricks | Reusable code snippet repository with semantic lookup |
Third-party runtime inventory: THIRD_PARTY_LICENSES.txt
