42 Commits

Author SHA1 Message Date
jakob 88f1fdc3d0 Move agent settings to opencode dir 2026-04-10 15:00:53 +02:00
jakob 460bb460bb Fix: CLI generate command works with single invocation
The remove_env_flags function was incorrectly returning index 0 when no --env
flag was present, causing it to mistakenly skip the first argument
(program name) and shift all arguments incorrectly.

This required users to specify 'generate' twice to make the CLI work.

Fix by checking if --env was actually found (env_idx > 0) before removing
any arguments from the list.
2026-04-10 14:05:46 +02:00
jakob c0c43ddf20 Add AGENTS.md with project guidelines for opencode 2026-04-10 13:44:03 +02:00
jakob 7c0a61383a Fix batch count showing 0 in generate command output
- Save original batch count before processing loop
- Use saved count in final output message
- Fixes issue #3: 'across 0 batches' bug
2026-04-02 12:50:54 +02:00
jakob e9cf2e031f Implement multi-batch invoice generation
- Add read_csv_file_by_batch() to group transactions by batch_number
- Modify generate command to create separate directories per batch
- Each batch directory contains index.html and customer_XXX.html files
- Add 3 unit tests for batch grouping logic
- Fixes issue #1: CSV with multiple batches now generates separate invoices

Closes: #1
2026-04-02 12:34:14 +02:00
jakob 1e9af16325 Bump version to 0.2.0 v0.2.0 2026-04-02 12:01:04 +02:00
jakob a8ffd0007d Update README: add testing section, production build, test infrastructure docs 2026-04-02 12:00:00 +02:00
jakob e2123e4619 Add comprehensive TDD infrastructure with 45 tests
- Add lib crate exposing modules for integration testing
- Add dev-dependencies: tokio-test 0.4, tempfile
- Refactor parse_csv_fields() as pure function for unit testing
- Add field validation (minimum 16 fields required)
- Fix repository last_insert_id using SELECT LAST_INSERT_ID()
- Add 10 lib tests for CSV parsing and date formatting
- Add 10 config tests for environment configuration
- Add 7 import tests for CSV file parsing
- Add 6 models tests for database structs
- Add 12 repository tests for CRUD operations
2026-04-02 11:13:41 +02:00
jakob 429d5d774f Add documentation comments to codebase
Prioritize AI agent-friendly comments explaining:
- Data model rationale (customers, cards, transactions relationships)
- Business rules (anonymized cards, customer_number requirements)
- Config file loading order and environment mapping
- Import pipeline phases and CSV column mapping
- Database operation behaviors (upsert, reset implications)
- SQL query rationale and data filtering rules
2026-04-02 08:45:14 +02:00
jakob e71c83538f Add README documentation
Document project overview, features, database schema, configuration,
commands, and getting started guide.
2026-04-02 08:21:55 +02:00
jakob 7a172c6fdb Simplify database schema: remove card_type, card_id, add card_number
Refactor the database schema to better model the data relationships:

Schema changes:
- Removed cards.card_type (redundant, identical to card_number)
- Removed transactions.card_id (unnecessary indirection)
- Added transactions.card_number (stores card number for all transactions)
- Made cards.customer_id NOT NULL (every card must belong to a customer)
- Made transactions.customer_id nullable (NULL for anonymized transactions)

Import logic changes:
- Only create cards for known customers (transactions with customer_number)
- Store card_number for ALL transactions (including anonymized)
- Skip cards/customer creation for anonymized transactions

Additional changes:
- Add 'db reset' command to drop and recreate database
- Update migration file with new schema

This simplifies queries and better reflects the data model:
- Cards table: authoritative mapping of card_number -> customer_id
- Transactions table: stores all raw data including anonymized cards
- Customer relationship via JOIN on card_number for known customers
2026-04-02 08:15:05 +02:00
jakob cd46368f79 Add multi-environment support for database configuration
Introduces separate databases and config files for dev, test, and prod
environments. The application now defaults to production, with --env flag
to specify alternative environments.

Changes:
- Update config.rs to support env-based loading (config.toml -> config.<env>.toml -> config.example.toml)
- Add Env enum (Prod, Dev, Test) with database name mapping
- Add --env flag to CLI commands (defaults to prod)
- Add 'db setup' command to create database and schema
- Split migrations into env-specific database creation and shared schema
- Update .gitignore to track config.example.toml but ignore config.toml and config.<env>.toml files
- Update config.example.toml as a template with placeholder values
- Delete 001_initial_schema.sql, replaced by 002_schema.sql + env-specific files

Config loading order:
  1. config.toml (local override)
  2. config.<env>.toml (environment-specific)
  3. config.example.toml (fallback)

Database names:
  - prod: rusty_petroleum
  - dev:  rusty_petroleum_dev
  - test: rusty_petroleum_test

Usage:
  cargo run -- db setup --env dev       # Setup dev database
  cargo run -- import data.csv --env dev # Import to dev
  cargo run -- db setup                # Setup prod (default)
  cargo run -- import data.csv         # Import to prod (default)
2026-04-02 07:09:06 +02:00
jakob 9daa186ff6 Add MariaDB database support for storing transaction data
Introduces a new database layer to persist CSV transaction data in MariaDB,
enabling both invoicing and sales reporting queries. This replaces the
previous file-to-file-only processing.

Changes:
- Add sqlx, tokio, toml, anyhow, bigdecimal dependencies to Cargo.toml
- Create config module for TOML-based configuration (database credentials)
- Create db module with connection pool, models, and repository
- Create commands module with 'import' subcommand for CSV ingestion
- Refactor main.rs to use subcommand architecture (import/generate)
- Add migration SQL file for manual database schema creation

Schema (3 tables):
- customers: customer_number, card_report_group (1=fleet, 3/4=retail)
- cards: card_number, card_type, customer_id (nullable for anonymous)
- transactions: full transaction data with FK to cards/customers

Usage:
  cargo run -- import <csv-file>   # Import to database
  cargo run -- generate <csv> <dir>  # Generate HTML invoices (unchanged)

Configuration:
  cp config.example.toml config.toml  # Edit with database credentials
  mysql < migrations/001_initial_schema.sql  # Create database first
2026-04-02 06:33:38 +02:00
jakob 39b62014b0 Add batch number to customer invoice header 2026-03-23 20:10:55 +01:00
jakob a279c653e0 Change header from Faktura to Fakturaunderlag 2026-03-23 20:08:29 +01:00
jakob d6f3e19215 Fix summary calculations 2026-03-23 20:06:00 +01:00
jakob 81d28b5ee6 Reorder summary rows: Avrundningsfel, Öresutjämning, Totalt 2026-03-23 16:55:03 +01:00
jakob a0df82ab35 Rename to Avrundningsfel, add Öresutjämning row, round total
Summary now shows:
- Product rows
- Avrundningsfel (rounding error)
- Totalt (rounded to nearest integer)
- Öresutjämning (difference from transactions to rounded total)
2026-03-23 16:53:02 +01:00
jakob 82cf4b34ac Fix summary amount calculation and add Öresutjämning row
- Amount = round(volume, 2) * round(avg_price, 2)
- Add Öresutjämning showing difference between transaction sum and calculated total
2026-03-23 16:41:49 +01:00
jakob b95cae2ea7 Ensure grand_total is consistent with product calculations
Calculate grand_total from products (volume * avg_price), matching the product row calculations.
2026-03-23 16:24:59 +01:00
jakob 3bb65ca7f6 Fix grand_total calculation from card totals
Calculate grand_total from card totals instead of products to ensure consistency.
2026-03-23 16:21:58 +01:00
jakob 03f643ba82 Reorder summary columns and calculate amount from volume * avg_price
Summary now shows: Produkt | Volym (L) | Snittpris/L | Belopp
Amount is calculated as volume * average_price instead of summing transactions.
2026-03-23 16:16:54 +01:00
jakob 611a471bf1 Exclude Swedish VAT (25%) from prices and amounts in HTML output
Multiply price and amount by 0.8 before generating HTML.
Original CSV and TXT files remain unchanged.
2026-03-23 16:08:13 +01:00
jakob a9e6d10954 Change header from Faktura to Fakturaunderlag 2026-03-23 15:50:47 +01:00
jakob 6b1c9d0c12 Store original and cleaned files in batch folder
- Save original .txt file in the batch folder
- Save cleaned .csv file with just batch number as filename (no '-cleaned' suffix)
- Both files stored alongside the HTML and PDF outputs
2026-03-23 15:46:24 +01:00
jakob 1632b6162c Revert "Add shell script to rename PDFs by extracting customer numbers"
This reverts commit b27c24f806.
2026-03-23 15:08:42 +01:00
jakob b27c24f806 Add shell script to rename PDFs by extracting customer numbers
- rename_pdfs.sh: Main script that renames PDFs based on content
- extract_customer.py: Helper script to extract customer number from PDF
2026-03-23 14:38:56 +01:00
jakob 1cc34b1a5c Add preprocessing step to convert real input to cleaned format
- Read quoted tab-separated input with US date format (M/D/YYYY H:MM:SS AM/PM)
- Convert dates to ISO format (YYYY-MM-DD HH:MM:SS)
- Save cleaned version to .cleaned.csv alongside the HTML output
- Continue processing with existing workflow on cleaned file
2026-03-23 13:58:36 +01:00
jakob fd2e776181 Support quoted tab-separated input with US date format
Parse dates in M/D/YYYY H:MM:SS AM/PM format in addition to the
ISO format used in the cleaned-up test data.
2026-03-23 13:53:36 +01:00
jakob 2360dc6b53 Get batch number from file contents instead of filename 2026-03-23 13:43:27 +01:00
jakob f1ba5a05fb Accept output path argument and create batch subdirectory 2026-03-23 11:24:34 +01:00
jakob 748d8a1f19 Remove PDF generation
Revert PDF generation feature - will use external tool for HTML to PDF conversion.
2026-03-23 11:19:20 +01:00
jakob deb49aaac7 Revert "Fix PDF generation with simplified HTML"
This reverts commit d0654af339.
2026-03-23 11:18:30 +01:00
jakob d0654af339 Fix PDF generation with simplified HTML
Use simpler HTML structure compatible with printpdf renderer.
Use inline styles and standard table elements for better rendering.
2026-03-23 11:12:28 +01:00
jakob 0ebadbdb48 Add PDF generation for invoices
- Generate both HTML and PDF versions of each customer invoice
- PDFs use printpdf with HTML rendering for consistent styling
- Same layout and formatting as HTML output
2026-03-23 11:04:24 +01:00
jakob 4119ad7059 Add summary section with product breakdown
- Show total volume, total amount, and average price per product
- Include grand total row
- Products sorted alphabetically
2026-03-23 10:57:35 +01:00
jakob 809f5d2a58 Add Kr currency unit and period display
- Show Kr after all amounts and prices
- Replace batch reference with period (first-last date)
- Same period shown on all customer invoices
2026-03-23 10:51:43 +01:00
jakob bc586e21e7 Translate UI to Swedish 2026-03-23 10:46:39 +01:00
jakob 1929b3ed49 Accept CSV file path as command line argument
Output is now written to the same directory as the input file.
2026-03-23 10:41:54 +01:00
jakob 623cf12a1c Create .gitignore 2026-03-23 10:37:53 +01:00
jakob 650435e00c Add invoice generator for fuel station transactions
- Read CSV files from input/ directory
- Generate static HTML invoices grouped by customer and card
- Filter transactions to only include fleet customers
- Compact print-friendly layout with 2 decimal precision
2026-03-23 10:36:14 +01:00
jakob d3b8828260 Initial commit 2026-03-23 09:58:46 +01:00