This commit is contained in:
Xiretza 2025-01-04 20:31:10 +00:00
parent 2fe3418b8e
commit feae5270e4
6 changed files with 148 additions and 0 deletions

5
.editorconfig Normal file
View file

@ -0,0 +1,5 @@
root = true
[*.typ]
indent_style = space
indent_size = 4

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.pdf

12
README.md Normal file
View file

@ -0,0 +1,12 @@
# Rechnungstemplate IT-Syndikat
Usage:
```
git clone https://git.it-syndikat.org/IT-Syndikat/its-rechnung
cd its-rechnung
git worktree add ~/.local/share/typst/packages/preview/its-rechnung/0.1.0 0.1.0`
cd ~/wherever
typst init @preview/its-rechnung:0.1.0
```

100
lib.typ Normal file
View file

@ -0,0 +1,100 @@
#import "@preview/letter-pro:3.0.0": letter-simple
#let format_date(d) = {
let month = (
"Jänner",
"Februar",
"März",
"April",
"Mai",
"Juni",
"Juli",
"August",
"September",
"Oktober",
"November",
"Dezember",
).at(d.month()-1)
str(d.day()) + ". " + month + " " + str(d.year())
}
#let format_eur(dec) = {
let (int, frac) = str(dec).split(".")
let int = int.rev().clusters().chunks(3).intersperse(".").flatten().rev().join("")
let frac = frac + calc.max(0, 2-frac.len()) * "0"
align(right, text(number-width: "tabular", int + "," + frac + " €"))
}
#let its-rechnung(
recipient: none,
invoice_date: none,
due_date: none,
invoice_num: none,
items: (),
) = {
set text(lang: "de", size: 10pt, font: "Noto Sans")
show heading.where(level: 1): set align(center)
show heading: set text(font: "Noto Serif")
let invoice_num = "R" + invoice_date.display("[year][month][day]") + "." + invoice_num
let total = items.map(((_name, amount)) => amount).sum()
letter-simple(
sender: (
name: "IT-Syndikat",
address: "c/o Cunst & Co, Tschamlerstraße 3, 6020 Innsbruck, Österreich",
extra: [
E-Mail: #link("mailto:wir@it-syndikat.org")[wir\@it-syndikat.org]\
ZVR-Nr.: 553029636
],
),
recipient: recipient,
)[
#let header_cells = (
("Rechnungsnummer", invoice_num),
("Fällig am", format_date(due_date)),
("Rechnungsdatum", format_date(invoice_date)),
)
#grid(
columns: 5,
inset: 2.5pt,
..header_cells.map(array.first).map(text.with(size: 0.7em)).intersperse(h(1fr)),
..header_cells.map(array.last).intersperse(h(1fr)),
)
= Rechnung
#v(1em)
Wir erlauben uns wie folgt in Rechnung zu stellen:
#table(
columns: (1fr, auto),
stroke: none,
table.header([*Posten*], [*Betrag*]),
table.hline(),
..items.map(((name, amount)) => ([#name], format_eur(amount))).flatten(),
table.hline(),
align(horizon)[*Total*], text(size: 1.2em, weight: "semibold", format_eur(total))
)
#v(2em)
Mit freundlichen Grüßen, \
Armin Brauns, \
Kassier IT-Syndikat.
#align(bottom, grid(columns: (1fr, 1.2fr), inset: 3pt,
[_Bankverbindung_], [_Legal information_],
table(columns: 2, stroke: none, align: (right, left), inset: 3pt,
[Empfänger:], [IT-Syndikat Innsbruck],
[IBAN:], [AT67 5700 0300 5321 9753],
[BIC:], [HYPTAT22],
[Payment reference:], invoice_num,
),
align(top)[
Umsatzsteuerfrei aufgrund der Kleinunternehmerregelung. \
Austrian law applies.
]
))
]
}

17
template/main.typ Normal file
View file

@ -0,0 +1,17 @@
#import "@preview/its-rechnung:0.1.0": its-rechnung
#its-rechnung(
recipient: [
Fritz Gruber \
Anichstraße 8 \
6020 Innsbruck \
Österreich
],
invoice_date: datetime(year: 2025, month: 1, day: 3),
due_date: datetime(year: 2025, month: 1, day: 17),
invoice_num: "0042",
items: (
("T-Shirt", decimal("20.00")),
("Blinkenshit", decimal("5.99")),
),
)

13
typst.toml Normal file
View file

@ -0,0 +1,13 @@
[package]
name = "its-rechnung"
version = "0.1.0"
entrypoint = "lib.typ"
authors = ["Lambda"]
license = "MIT"
description = "IT-Syndikat Rechnungstemplate"
categories = ["layout", "office"]
repository = "https://git.it-syndikat.org/IT-Syndikat/its-rechnung"
[template]
path = "template"
entrypoint = "main.typ"