Metadata-Version: 2.4
Name: ebia
Version: 0.4.3
Summary: EquipeBaie Invoice Automation
Author: AAH
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: pdfplumber
Requires-Dist: openpyxl
Provides-Extra: app
Requires-Dist: customtkinter>=5.2.0; extra == "app"
Requires-Dist: Pillow>=10.0.0; extra == "app"
Requires-Dist: watchdog>=4.0; extra == "app"
Requires-Dist: python-dotenv>=1.0; extra == "app"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"
Requires-Dist: pytest-mock>=3.12; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"

# Equipe Baie — Invoice Automation

Automated invoicing pipeline that parses PDF invoices, enriches them with client accounting references, and generates Excel accounting exports — with a desktop UI for day-to-day operation.

---

## Project structure

```
EquipeBaie_Freelance-project/
├── src/
│   ├── ebia/                  # Core library (published to PyPI)
│   │   ├── parser.py          # PDF invoice parser
│   │   ├── xls_generator.py   # Excel (.xlsx) generator
│   │   └── cli.py             # CLI entry point
│   └── ebia_ui/               # Desktop application (not on PyPI)
│       ├── paths.py           # All filesystem paths — single source of truth
│       ├── logging_config.py  # App-wide logging setup
│       ├── main.py            # Application entry point
│       ├── core/
│       │   ├── config_manager.py   # Persistent JSON config
│       │   ├── client_manager.py   # Client reference registry
│       │   ├── engine.py           # Orchestration layer (RunEngine)
│       │   ├── manifest.py         # Processed-file tracking (SHA-256)
│       │   └── _mp_worker.py       # Subprocess entry point (multiprocessing)
│       ├── ui/
│       │   ├── main_window.py
│       │   ├── components/    # Reusable widgets, sidebar
│       │   └── views/         # Run, Config, Client, About pages
│       └── assets/            # logo.png, logo.ico, default_clients.json
├── installer/
│   ├── EquipeBaie.iss         # Inno Setup installer script
│   └── equipebaie.cer         # Self-signed code-signing certificate (public key)
├── tests/
│   ├── unit/                  # Pure-function tests, no I/O
│   ├── integration/           # Real PDF/Excel tests
│   └── e2e/                   # CLI subprocess tests
├── scripts/
│   └── build_exe.py           # PyInstaller Windows build (onedir)
└── pyproject.toml
```

---

## Components

### `ebia` — core library

Stateless, no side effects. Can be used standalone via CLI or imported directly.

- **`parser.py`** — extracts `Client`, `date`, `total_ttc` from a French-format PDF invoice using `pdfplumber`; `parse_many()` parses a list of PDFs in parallel using `ProcessPoolExecutor`, returning `(path, dict | Exception, list[LogRecord])` triples — log records collected in the worker are re-emitted by the caller so they reach the UI and log file on all platforms
- **`xls_generator.py`** — generates one `.xlsx` per month with one sheet per day; 3 accounting rows per invoice (411 / 44571 / 701). Supports retroactive insertion (`patch_month_workbook`) for late invoices arriving after a month has already been processed.

### `ebia_ui` — desktop application

Built with `customtkinter`. Requires Python + display (not headless).

- **Run view** — manual trigger + recurring scheduler (daily / weekly / monthly). The engine runs in a separate process (own GIL) so the UI stays responsive during execution. Includes a shortcut button to open the reports folder directly in File Explorer, and a run history table showing the last 20 executions (manual and scheduled) with status, report count, invoice count, and error details.
- **Config view** — VAT rate, invoice folder path, configurable reports output folder, manual PDF archive trigger
- **Client view** — client reference registry (accounting code ↔ client name) backed by a `ttk.Treeview` for instant rendering regardless of list size. Add and edit via modal popup dialog; pre-populated with a default client list on first launch.
- **About view** — app version (read dynamically from the installed package)
- **Manifest** — SHA-256 deduplication: already-processed PDFs are skipped on subsequent runs; only recorded after successful Excel generation
- **Per-month document counters** — each calendar month tracks its own last-used document number independently, so re-running for a past month never resets or conflicts with other months

### `ebia_ui/paths.py` — centralised path configuration

All filesystem paths are defined in one place. To change a location, edit only this file:

```python
APP_DIR      = Path.home() / ".equipe_baie"                          # config, clients, manifest, logs
REPORTS_DIR  = Path.home() / "Documents" / "Equipe_Baie" / "Rapports"
ARCHIVES_DIR = Path.home() / "Documents" / "Equipe_Baie" / "factures_archives"
```

---

## Application data locations

| Data | Default location |
|---|---|
| Config (VAT rate, folder paths, etc.) | `~/.equipe_baie/config.json` |
| Client reference registry | `~/.equipe_baie/clients.json` |
| Processed-file manifest | `~/.equipe_baie/processed.json` |
| Run history | `~/.equipe_baie/run_history.json` (last 100 runs, all triggers) |
| Application logs | `~/.equipe_baie/logs/ebia.log` (5 MB × 3 rotating backups) |
| Generated Excel reports | `~/Documents/Equipe_Baie/Rapports/` (configurable in Config view) |
| Archived PDFs | `~/Documents/Equipe_Baie/factures_archives/` (configurable in Config view) |

On Windows `~` resolves to `C:\Users\<user>`, on Linux/macOS to `/home/<user>`.

---

## Installation

### Windows — client machines

Download `EquipeBaie_Setup.exe` from the [latest GitHub Release](https://github.com/Alamajdoub9/EquipeBaie_Freelance-project/releases/latest).

**Before running the installer**, unblock the downloaded file to prevent Windows SmartScreen from prompting. Open PowerShell and run:

```powershell
Unblock-File -Path "$env:USERPROFILE\Downloads\EquipeBaie_Setup.exe"
```

Then double-click `EquipeBaie_Setup.exe`. The installer will:
1. Install the application to `Program Files\EquipeBaie`
2. Silently import the code-signing certificate into the Windows Trusted Root store
3. Create a Start Menu shortcut (and optionally a Desktop shortcut)
4. Register an uninstaller in Programs & Features

After the first installation, all future updates signed with the same certificate will run without any SmartScreen warning — no `Unblock-File` step needed again.

### Library only (CLI usage)

```bash
pip install ebia
```

### Development (library + UI + tests)

```bash
git clone https://github.com/Alamajdoub9/EquipeBaie_Freelance-project.git
cd EquipeBaie_Freelance-project

python -m venv .venv
source .venv/bin/activate          # Linux / macOS
# .venv\Scripts\Activate.ps1       # Windows PowerShell

pip install -e ".[dev,app]"
```

---

## Running the application

```bash
ebia-ui
# or
python -m ebia_ui.main
```

On first launch:
1. Go to **Configurations** and set the invoice folder path (where your PDFs are stored)
2. Optionally adjust the VAT rate, the reports output folder, and the archive folder
3. Go to **Clients** to review the pre-loaded client list and add or edit entries as needed
4. Go to **Exécution** and click **Lancer maintenant**

Generated Excel files are written to the reports folder configured in the Config view (default: `~/Documents/Equipe_Baie/Rapports/`).

To archive processed PDFs after a run, go to **Configurations → Archivage des Factures** and click **Archiver les factures traitées**. Only PDFs already recorded in the manifest are moved.

---

## CLI usage (library only)

```bash
# Parse a single PDF and print extracted fields
ebia --path facture.pdf

# Generate Excel from a folder of PDFs
ebia --path ./invoices --out ./output/result.xlsx --start-piece 1 --start-document 1
```

---

## Running tests

```bash
# All tests
pytest

# By level
pytest -m unit
pytest -m integration
pytest -m e2e

# With coverage
pytest --cov=src/ebia --cov=src/ebia_ui/core --cov-report=term-missing
```

**Test matrix:**

| Suite | What it covers |
|---|---|
| `unit/test_parser.py` | PDF field extraction logic, `parse_many` contract (3-tuple return, log records) |
| `unit/test_generator.py` | Excel row generation and formatting |
| `unit/test_manifest.py` | SHA-256 manifest: load, save, deduplication |
| `unit/test_ebia_ui_core.py` | ConfigManager, ClientManager, RunEngine error paths |
| `integration/test_engine.py` | Full pipeline: PDFs → parse → enrich → xlsx |
| `integration/test_generator_xlsx.py` | Multi-month/multi-day workbook structure |
| `integration/test_parser_pdf.py` | Real PDF corpus parsing |
| `e2e/test_cli.py` | CLI invoked as subprocess |

---

## Delivery

The project has two deliverables released together by the same workflow.

### 1. `ebia` PyPI package

```bash
pip install ebia
```

Published automatically on every release. The `ebia_ui` package is **excluded** from the wheel (internal app, not a public library).

### 2. Windows installer (`EquipeBaie_Setup.exe`)

Built via PyInstaller (onedir) + Inno Setup on a Windows runner and attached to the GitHub Release alongside the wheel. No Python installation required on the target machine.

```bash
# Build the app folder locally (requires PyInstaller)
python scripts/build_exe.py
# produces: dist/EquipeBaie/EquipeBaie.exe

# Build the installer locally (requires Inno Setup installed)
iscc /DMyAppVersion=x.y.z installer\EquipeBaie.iss
# produces: dist/EquipeBaie_Setup.exe
```

---

## Code signing

The Windows installer and executable are signed with a self-signed certificate (`installer/equipebaie.cer`). The certificate is automatically imported into the client machine's Trusted Root store during installation, so no SmartScreen warnings appear on subsequent runs.

The private key (`.pfx`) is stored as a GitHub Actions secret (`CODESIGN_PFX_B64`) and never committed to the repository. The public certificate (`.cer`) is committed and bundled into the installer.

To regenerate the certificate (e.g. after expiry in 2031):
1. Run `New-SelfSignedCertificate` as described in the signing setup guide
2. Export the new `.pfx` and `.cer`
3. Update the `CODESIGN_PFX_B64` and `CODESIGN_PFX_PASSWORD` GitHub secrets
4. Replace `installer/equipebaie.cer` with the new `.cer`
5. Re-run the one-time `Import-Certificate` step on each client machine

---

## Versioning and release

Both deliverables share a single version number defined in `pyproject.toml`. The about view reads it dynamically via `importlib.metadata` — no manual update needed.

**To publish a new release**, trigger the `Release` workflow from the GitHub Actions UI and pick the bump type:

| Input | Effect | Example |
|---|---|---|
| `patch` (default) | Bug fixes | `0.2.0` → `0.2.1` |
| `minor` | New features, backwards-compatible | `0.2.0` → `0.3.0` |
| `major` | Breaking changes | `0.2.0` → `1.0.0` |

The workflow will:
1. Bump the version in `pyproject.toml` and push a `chore: bump version to X.Y.Z` commit to `main`
2. Run the full test suite (gate)
3. Build and publish the wheel to PyPI
4. Create a GitHub Release with the wheel attached
5. Build `EquipeBaie/` (onedir) with PyInstaller on a Windows runner
6. Sign `EquipeBaie.exe` with the code-signing certificate
7. Build `EquipeBaie_Setup.exe` with Inno Setup
8. Sign the installer
9. Attach `EquipeBaie_Setup.exe` to the GitHub Release

---

## Requirements

- Python >= 3.10
- Library deps: `pdfplumber`, `openpyxl`
- UI extra deps: `customtkinter >= 5.2.0`, `Pillow >= 10.0.0`
- Dev deps: `pytest`, `pytest-cov`, `pytest-mock`, `ruff`, `mypy`
