feat: add invoice
This commit is contained in:
parent
4418b88852
commit
a6694920a8
5 changed files with 176 additions and 5 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
*.pdf
|
*.pdf
|
||||||
|
*.yml
|
|
@ -57,7 +57,6 @@
|
||||||
#form_field[unterschrift (bei minderjährigen der ges. vertr.)]
|
#form_field[unterschrift (bei minderjährigen der ges. vertr.)]
|
||||||
]
|
]
|
||||||
|
|
||||||
#v(0.5em)
|
|
||||||
#text(10pt, style: "italic")[
|
#text(10pt, style: "italic")[
|
||||||
\* Bitte eines der Felder ankreuzen. Es kann auch ein beliebig höherer Beitrag entrichtet werden.
|
\* Bitte eines der Felder ankreuzen. Es kann auch ein beliebig höherer Beitrag entrichtet werden.
|
||||||
]
|
]
|
||||||
|
|
146
rechnung.typ
Normal file
146
rechnung.typ
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
#import "templates/form.typ": tmpl, colors
|
||||||
|
#let config = yaml("rechnung.yml")
|
||||||
|
|
||||||
|
#show: doc => tmpl(
|
||||||
|
title: (
|
||||||
|
invoice: "Rechnung",
|
||||||
|
estimate: "Kostenvoranschlag",
|
||||||
|
internal: "Eigenbeleg"
|
||||||
|
).at(config.type),
|
||||||
|
version: "",
|
||||||
|
change_date: config.date,
|
||||||
|
text_size: 11.25pt,
|
||||||
|
doc,
|
||||||
|
)
|
||||||
|
|
||||||
|
// DIN 5008 Sichtfenster: 45mm
|
||||||
|
#place(
|
||||||
|
top+left,
|
||||||
|
dy: 25mm,
|
||||||
|
)[
|
||||||
|
#text(size: 0.75em)[#underline[swablab e.V. - Katharinenstr. 1 - 72250 Freudenstadt]] \
|
||||||
|
#v(0.5em)
|
||||||
|
#config.address
|
||||||
|
]
|
||||||
|
|
||||||
|
// DIN 5008 Informationsblock: 50mm
|
||||||
|
#place(
|
||||||
|
top+right,
|
||||||
|
dy: 30mm,
|
||||||
|
)[
|
||||||
|
#v(1em)
|
||||||
|
Datum: #config.date \
|
||||||
|
#if config.type != "internal" [
|
||||||
|
Kunden-Nr.: #config.customer_no \
|
||||||
|
]
|
||||||
|
#if config.type == "invoice" [
|
||||||
|
Rechnungs-Nr.: #config.invoice_no \
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
// DIN 5008 Faltmarke 1: 105mm
|
||||||
|
#place(
|
||||||
|
top+left,
|
||||||
|
dy: 85mm,
|
||||||
|
dx: -1cm,
|
||||||
|
line(
|
||||||
|
length: -1em,
|
||||||
|
stroke: 0.5pt + colors.subtext
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// DIN 5008 Faltmarke 2: 210mm
|
||||||
|
#place(
|
||||||
|
top+left,
|
||||||
|
dy: 190mm,
|
||||||
|
dx: -1cm,
|
||||||
|
line(
|
||||||
|
length: -1em,
|
||||||
|
stroke: 0.5pt + colors.subtext
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
#let money(i) = {
|
||||||
|
if i == 0 {
|
||||||
|
return "0.00€"
|
||||||
|
}
|
||||||
|
str(i * 100).slice(0,-2)+ "." + str(i * 100).slice(-2) + " €"
|
||||||
|
}
|
||||||
|
|
||||||
|
// DIN 5008 nach Faltmarke 1
|
||||||
|
#place(
|
||||||
|
top+left,
|
||||||
|
dy: 85mm,
|
||||||
|
)[
|
||||||
|
#table(
|
||||||
|
columns: (auto, 1fr, auto, auto, auto ,auto),
|
||||||
|
fill: (_, row) => if row == 0 { colors.highlight } else { white },
|
||||||
|
stroke: 0.1pt + colors.subtext,
|
||||||
|
[*Pos.*],
|
||||||
|
[*Beschreibung*],
|
||||||
|
[*Stück*],
|
||||||
|
[*Einzelpreis*],
|
||||||
|
[*Rabatt*],
|
||||||
|
[*Betrag*],
|
||||||
|
..config.entries.enumerate().map(e => (
|
||||||
|
e.at(0)+1,
|
||||||
|
e.at(1).description,
|
||||||
|
e.at(1).pieces,
|
||||||
|
money(e.at(1).price),
|
||||||
|
money(e.at(1).sale),
|
||||||
|
money(e.at(1).pieces * e.at(1).price - e.at(1).sale),
|
||||||
|
)).flatten().map(e => [#e]),
|
||||||
|
)
|
||||||
|
|
||||||
|
#align(right)[
|
||||||
|
#pad(x:1em)[
|
||||||
|
*Gesamtbetrag: #money(config.entries.map(e => e.pieces * e.price - e.sale).sum())*
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
// Footer
|
||||||
|
#place(bottom+left)[
|
||||||
|
#if config.type == "invoice" [
|
||||||
|
Vielen Dank für deine Bestellung! \
|
||||||
|
] else if config.type == "estimate" [
|
||||||
|
Wir freuen uns auf deine Bestellung! \
|
||||||
|
] else if config.type == "internal" [
|
||||||
|
*Grund für Eigenbeleg:* \
|
||||||
|
#config.internal_reason
|
||||||
|
]
|
||||||
|
|
||||||
|
#text(size: 0.7em, fill: colors.subtext)[
|
||||||
|
#if config.type == "invoice" [
|
||||||
|
Gesamtbetrag fällig in 10 Tagen ab Rechnungserhalt. \
|
||||||
|
Für überfällige Zahlungen wird eine Bearbeitungsgebühr von min. 5 % pro Monat berechnet.
|
||||||
|
] else if config.type == "estimate" [
|
||||||
|
Dieser Kostenvoranschlag ist unverbindlich.
|
||||||
|
]
|
||||||
|
|
||||||
|
#table(
|
||||||
|
stroke: none,
|
||||||
|
align: top+left,
|
||||||
|
columns: (1fr,1fr,auto,1fr,1fr),
|
||||||
|
[*Telefon*],[*E-Mail / Web*],[*Bankverbindung*],[*Vereinsregister*],[*Vorstand*],
|
||||||
|
[
|
||||||
|
+49 15679232971
|
||||||
|
],
|
||||||
|
[
|
||||||
|
info\@swablab.de \
|
||||||
|
https://swablab.de
|
||||||
|
],
|
||||||
|
[
|
||||||
|
VR-Bank Dornstetten-Horb \
|
||||||
|
DE12 6426 2408 0125 6340 05
|
||||||
|
],
|
||||||
|
[
|
||||||
|
VR 724909 \
|
||||||
|
Amtsgericht Stuttgart
|
||||||
|
],
|
||||||
|
[
|
||||||
|
Fabian Haas \
|
||||||
|
Manuel Knodel
|
||||||
|
],
|
||||||
|
)
|
||||||
|
]
|
||||||
|
]
|
18
rechnung.yml.template
Normal file
18
rechnung.yml.template
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
type: invoice # invoice (Rechnung), estimate (Kostenvoranschlag), internal (Eigenbeleg)
|
||||||
|
date: 01.01.2024
|
||||||
|
customer_no: 0 # für Rechnung und Kostenvoranschlag
|
||||||
|
invoice_no: 0 # für Rechnung
|
||||||
|
internal_reason: Begründung # für Eigenbeleg
|
||||||
|
address: |
|
||||||
|
Name
|
||||||
|
Straße
|
||||||
|
PLZ Adresse
|
||||||
|
entries:
|
||||||
|
- description: Teil 1
|
||||||
|
pieces: 2
|
||||||
|
price: 5
|
||||||
|
sale: 1
|
||||||
|
- description: Teil 2
|
||||||
|
pieces: 1
|
||||||
|
price: 2
|
||||||
|
sale: 0
|
|
@ -1,3 +1,10 @@
|
||||||
|
#let colors = (
|
||||||
|
primary: oklch(93.84%, 0.09, 183.69deg),
|
||||||
|
secondary: oklch(73.51%, 0.168, 40.25deg),
|
||||||
|
subtext: oklch(60%, 0, 0deg),
|
||||||
|
highlight: oklch(90%, 0, 0deg),
|
||||||
|
)
|
||||||
|
|
||||||
#let tmpl(
|
#let tmpl(
|
||||||
title: none,
|
title: none,
|
||||||
version: none,
|
version: none,
|
||||||
|
@ -39,7 +46,7 @@ place(
|
||||||
origin: bottom + left,
|
origin: bottom + left,
|
||||||
text(
|
text(
|
||||||
size: 10pt,
|
size: 10pt,
|
||||||
fill: rgb("9c9c9c"),
|
fill: colors.subtext,
|
||||||
[swablab e.V. / #title #version / #change_date]
|
[swablab e.V. / #title #version / #change_date]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -82,17 +89,17 @@ doc
|
||||||
#let form_field(name, width: 100%) = {
|
#let form_field(name, width: 100%) = {
|
||||||
stack(spacing: 2pt)[
|
stack(spacing: 2pt)[
|
||||||
#rect(
|
#rect(
|
||||||
fill: rgb("e4e5ea"),
|
fill: colors.highlight,
|
||||||
width: width,
|
width: width,
|
||||||
height: 2em,
|
height: 2em,
|
||||||
)
|
)
|
||||||
][
|
][
|
||||||
#text(9pt, fill: rgb("000000"))[
|
#text(9pt, fill: black)[
|
||||||
#name
|
#name
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
#let form_inline(width: 12em) = {
|
#let form_inline(width: 12em) = {
|
||||||
box(height: 0.75em, width: width, fill: rgb("e4e5ea"), outset: (y: 3pt))
|
box(height: 0.75em, width: width, fill: colors.highlight, outset: (y: 3pt))
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue