Metadata-Version: 2.4
Name: facturization
Version: 0.1.1
Summary: Generate high-quality PDF invoices from a YAML specification.
License: MIT License
        
        Copyright (c) 2026 Martino Pilia
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Requires-Python: >=3.11
Requires-Dist: jinja2>=3
Requires-Dist: pyyaml>=6
Description-Content-Type: text/markdown

# facturization

Generate high-quality PDF invoices from a YAML specification.

## Background

I needed an invoice generator for my business with high quality typesetting, but I did not like any of the LaTeX templates I could find, and I wanted full control and greater flexibility compared to the projects I had seen. And so here we are.

## Requirements

- A TeX distribution providing `pdflatex` (e.g. [TeX Live](https://tug.org/texlive/))
  with a few common packages: `geometry`, `ragged2e`, `booktabs`, `tabularx`,
  `enumitem`, `hyperref`, and `babel`. These ship with a full TeX Live install.

## Installation

Run it directly with uv:

```sh
uv run facturization path/to/input.yml --output-dir out/
```

Or install it as a standalone command-line tool:

```sh
uv tool install facturization
```

Pip is also supported:

```sh
pip install facturization
```

## Usage

```sh
facturization path/to/input.yml
```


The only mandatory argument is the path to the input YAML file. `--output-dir`
(`-o`) defaults to the current directory. For an input named `foo.yml` the tool
writes `foo.tex` and `foo.pdf` (alongside pdflatex's `.aux`/`.log`) into the
output folder.

## Example

Try out the example from the repo:

```sh
uv run facturization example/details.yml --output-dir example
```

This renders [`example/details.yml`](example/details.yml) to `example/details.pdf`:

![Example invoice](https://raw.githubusercontent.com/m-pilia/facturization/master/example/preview.png)

## Input schema

### Top-level keys

| Key | Required | Description |
| --- | --- | --- |
| `invoice_number` | yes | Invoice identifier, shown in the header. |
| `issue_date` | yes | Date of issue. A YAML date is formatted like `May 4, 2026`. |
| `due_date` | no | Payment due date, formatted the same way. |
| `from` | yes | The sender party (see [Party](#party)). |
| `to` | yes | The recipient party (see [Party](#party)). |
| `service` | yes | The invoice line items (see [Service](#service)). |
| `currency` | yes | Currency code shown next to the totals, e.g. `EUR`. |
| `separator` | yes | Decimal separator for amounts: `dot` or `comma`. |
| `payment` | no | Ordered mapping of label → value with payment instructions, rendered as a labelled list at the bottom. |
| `reverse_charge_note` | no | Footnote text used when any line sets `reverse_charge`. Default: `VAT to be paid on a reverse charge basis.` |
| `closingnote` | no | Free text printed at the very bottom; blank lines start new paragraphs. |
| `lang` | no | `babel` language for hyphenation and date/typography conventions, e.g. `english`. |
| `fontsize` | no | Base font size: `10pt` (default), `11pt`, or `12pt`. |
| `geometry` | no | LaTeX `geometry` options for page size and margins. Default: `a4paper, margin=18mm`. |

### Party

Used for both `from` and `to`.

| Key | Required | Description |
| --- | --- | --- |
| `address` | yes | List of lines (name, street, city, country, …), printed as given. |
| `email` | no | Shown as `e-mail`. |
| `phone` | no | Shown as `Phone`. |
| `vat_identification_number` | no | Shown as `VAT ID`. |
| `company_registration_number` | no | Shown as `Corp. reg. no.` |
| `tax_code` | no | Shown as `Tax code`. |

### Service

Each entry in the `service` list is one line item.

| Key | Required | Description |
| --- | --- | --- |
| `description` | yes | Line description. |
| `unit_price` | yes | Price per unit. |
| `quantity` | no | Quantity, default `1`. |
| `vat` | no | VAT rate in percent, default `0`. |
| `reverse_charge` | no | If true, marks the line with a footnote and enables the shared reverse-charge note. |
| `details` | no | List of sub-bullets shown under the description. |

## Development

Linting and type checking are handled by [Ruff](https://docs.astral.sh/ruff/) and
[ty](https://docs.astral.sh/ty/), configured in `pyproject.toml`. Both are part of the
`dev` dependency group, so `uv sync` installs them.

```sh
# Lint
uv run ruff check .

# Verify formatting (no changes written)
uv run ruff format --check .

# Apply auto-fixes and reformat
uv run ruff check --fix .
uv run ruff format .

# Type check (strict mode, all rules as errors)
uv run ty check .
```

## Credits

Inspired by [mrzool/invoice-boilerplate](https://github.com/mrzool/invoice-boilerplate). This project takes the same idea of invoice typesetting from a plain data file, but replaces the heavy pandoc dependency with a small uv + Python + Jinja2 pipeline that renders a LaTeX template and compiles it with `pdflatex`.

## License

[MIT](LICENSE)
