171 lines
4.5 KiB
Markdown
171 lines
4.5 KiB
Markdown
# Freelance Invoice
|
|
|
|
is a simple command line tool to generate invoices for freelance work. It uses a simple template system based
|
|
on `jinja2` to generate the
|
|
invoice in HTML and then converts it to a PDF using `xhtml2pdf`.
|
|
|
|
## Install
|
|
|
|
Use python venv:
|
|
|
|
```bash
|
|
python -m venv .venv
|
|
source .venv/bin/activate
|
|
```
|
|
|
|
Build executable:
|
|
|
|
```bash
|
|
pip install --upgrade build
|
|
python -m build
|
|
```
|
|
|
|
Install the executable:
|
|
|
|
```bash
|
|
pip install .
|
|
```
|
|
|
|
See where it is installed:
|
|
```bash
|
|
which invoice
|
|
```
|
|
|
|
## usage
|
|
|
|
```bash
|
|
invoice -h
|
|
|
|
|
|
|
|
```
|
|
|
|
There are two yaml files describing your invoice:
|
|
|
|
- `invoice.yaml` contains the invoice data
|
|
- `envelope.yaml` contains the address data of the sender and the recipient
|
|
|
|
The invoice data is read from the `invoice.yaml` file and the address data is read from the `envelope.yaml` file. The
|
|
invoice data is then used to fill in the invoice template and the address data is used to fill in the address fields of
|
|
the invoice.
|
|
|
|
Some data are globaly available from the envelope template. Some of them can be overriden by the invoice template.
|
|
|
|
invoice.yaml - The Name of the invoice file is used as the invoice number but you are free to override it in the
|
|
invoice.yaml file.
|
|
|
|
```yaml
|
|
Id: RG004712 # overrides the file name as invlice Number
|
|
CustomerId: KD01234 # The customer id is used to identify the customer and is beeing looked up in the envelope.yaml file.
|
|
InvoiceDate: 2023-12-23 # The date of the invoice. If not set the current date is used.
|
|
|
|
Positions:
|
|
- Title: "Zuckerwatte fressen Ganz besonders langer Text"
|
|
SubTitle: "Leistungszeitraum: 11/2022"
|
|
PricePerUnit: 100 # The price per unit is taken from the envelope.yaml file using the customer id but can be overriden here.
|
|
Quantity: 100
|
|
|
|
- Title: "Aschlecken"
|
|
SubTitle: "Leistungszeitraum: 11/2022"
|
|
PricePerUnit: 99.99
|
|
Quantity: 12
|
|
|
|
- Title: "Aschkriechen"
|
|
SubTitle: "Leistungszeitraum: 10/2022"
|
|
PricePerUnit: 77.88
|
|
Quantity: 3
|
|
```
|
|
|
|
envelope.yaml
|
|
|
|
```yaml
|
|
AddressContent:
|
|
# AddressBoxSender is is used as the sender address in the letter head inside the address windows.
|
|
AddressBoxSender: "Abs.: Torsten Ueberschar - Pfarrweg 1 - 57439 Attendorn"
|
|
# The Content is a place to put your personal data. E.G. it is used in the footer of the invoice.
|
|
# you may put markdown in here.
|
|
Contents:
|
|
- Text: |
|
|

|
|
Torsten Ueberschar
|
|
Pfarrweg 1
|
|
57439 Attendorn
|
|
- Text: |
|
|
**Kontakt**
|
|
tu@uesome.de
|
|
+49 2734 4239271
|
|
- Text: |
|
|
**Steuern**
|
|
USt-IdNr.: DE313460724
|
|
- Text: |
|
|
**Bankverbindung**
|
|
Torsten Ueberschar
|
|
DE67 1001 1001 2626 8627 86
|
|
NTSBDEB1XXX
|
|
N26 Bank GmbH
|
|
|
|
# The Invoice field is used to put default values for the invoice. You may override them in the invoice.yaml file.
|
|
Invoice:
|
|
Vat: 19.0
|
|
Introduction: |
|
|
### Rechnung
|
|
|
|
*Sehr geehrte Damen und Herren*,
|
|
|
|
für folgende in Ihrem Auftrag ausgeführten Leistungen erlaube ich mir zu berechnen
|
|
|
|
Footer: |
|
|
Bitte überweisen Sie den Rechnungsbetrag unter Angabe der Rechnungsnummer auf mein Konto bis zum %%ZahlungsZiel%%.
|
|
|
|
Mit freundlichen Grüßen
|
|
|
|
*Torsten Uebeschar*
|
|
|
|
# Customers is a list of customers. The customer id is used to identify the customer and is beeing looked up in the invoice.yaml file.
|
|
Customers:
|
|
- CustomerId: KD01234
|
|
PricePerUnit: 88.88
|
|
DueDate: 30 # DueDate is the number of days the customer has to pay the invoice.
|
|
# The AddressField is used to fill in the address field window of the invoice.
|
|
AddressField: |
|
|
Klaus Peter Klausen
|
|
Am Klausenhof 1
|
|
04711 Klausenhausen
|
|
```
|
|
|
|
```bash
|
|
python src/main.py --help
|
|
Simple invoice generator for freelancers and small businesses by Torsten Ueberschar
|
|
|
|
usage: main.py [-h] -b BASE -i INVOICE [-e ENVELOPE] [-t TEMPLATE]
|
|
|
|
Read invoice and envelope data from yaml file
|
|
|
|
options:
|
|
-h, --help show this help message and exit
|
|
-b BASE, --base BASE base directory for invoice and envelope files
|
|
-i INVOICE, --invoice INVOICE
|
|
Invoice file name
|
|
-e ENVELOPE, --envelope ENVELOPE
|
|
Envelope file name
|
|
-t TEMPLATE, --template TEMPLATE
|
|
directory for template files
|
|
```
|
|
|
|
## example
|
|
|
|
```bash
|
|
invoice -b test_data -i invoice.yaml -e envelope.yaml -t test_data/templates
|
|
```
|
|
|
|
## to do
|
|
|
|
- give more structure to code
|
|
- make code testable
|
|
|
|
## see also
|
|
|
|
- https://xhtml2pdf.readthedocs.io/en/latest/index.html
|
|
- https://jinja.palletsprojects.com/
|
|
|