Conta
Built Conta, a Python-based desktop tool that helps self-employed professionals keep track of invoices, deductible expenses, social security payments, and quarterly tax obligations in Spain. The application combines a typed domain model, SQLite-backed persistence, and task-focused commands to provide a fast workflow for everyday bookkeeping, along with an interactive terminal UI (TUI) built with Textual for anyone who prefers a visual panel over loose commands.
View the project: Source code on GitHub
Core Responsibilities & Contributions
Product Architecture & System Design
-
Designed a modular accounting engine using Python 3.10,
sqlmodel,pydantic, and SQLite for local, file-based storage -
Modeled core bookkeeping entities
(
FacturaEmitida,GastoDeducible,PagoAutonomo,PagoFraccionado130) with explicit enums for activity types (programacion,musica) -
Structured the application as a reusable package with a
dedicated
contaentry point and environment-based configuration
CLI UX & Workflow Automation
- Implemented a multi-command CLI using Typer, with structured help text and argument parsing tailored to Spanish tax workflows
-
Added commands to register issued invoices
(
emite), deductible expenses (gasto), autonomous social security payments, and fractioned IRPF payments - Provided rich terminal output using the Rich library, including tabular listings for invoices and expenses
- Included validation and helpful error messages for dates, numeric fields, and quarter formats to reduce user mistakes
Interactive Terminal UI (TUI) with Textual
-
Designed and built a full TUI with
textual, organized into 6 screens navigable via function keys (F1–F6): dashboard, invoices, expenses, new invoice, new expense, and Modelo 130 - Dashboard with per-quarter tax summary cards (VAT owed/deductible, accumulated IRPF snapshot, self-employment contributions), with a year selector and on-demand refresh
- Invoice and expense tables with filters by year, quarter, and client, plus inline editing of collection/VAT status directly on the selected row
- Entry forms for invoices, expenses, and Modelo 130 fractioned payments, reusing the same service layer as the CLI
- Reactive data reload on tab switch, avoiding stale data when returning to a screen after registering entries elsewhere
Tax & Reporting Logic for Spanish Freelancers
- Encapsulated quarterly VAT (IVA) calculations in a dedicated service, computing devengado (owed) and deducible (deductible) VAT per quarter
-
Implemented IRPF accumulated snapshot logic matching the
structure of Modelo 130 (base, withholdings, previous payments)
via the
irpf_snapshot_acumuladoservice - Accounted for social security contributions, prior fractioned payments, and activity filters to give a realistic view of quarterly income tax obligations
Data Model & Persistence
- Used SQLModel to define typed tables with indexes on dates and invoice numbers for efficient filtering and reporting
- Ensured idempotent operations for critical entities (e.g. preventing duplicate invoice numbers on creation)
-
Managed a lightweight SQLite database file, initialized via a
single
conta initcommand -
Used
Decimalarithmetic for all monetary amounts, with consistent rounding (ROUND_HALF_UPto 2 decimal places) at calculation and display boundaries, avoiding floating-point precision errors in tax figures
Exports, Backups & Extensibility
- Built CSV export of official VAT books (libros de IVA) using pandas, generating separate files for issued and received invoices per quarter
-
Added a
backup-dbcommand to create timestamped copies of the SQLite database for safe archiving -
Implemented a PDF invoice importer (text extraction, field
detection, and heuristic tax classification by activity and
VAT/IRPF), with a
--dry-runmode to verify results before committing an import - Generated an annual tax report in PDF (via WeasyPrint) that pulls together invoices, expenses, contributions, and Modelo 130/303 results into a single document ready to archive or share with an accountant
- Structured the project with FastAPI and Uvicorn dependencies to allow a future evolution from pure CLI to a small web dashboard without changing the core domain layer