Datumsausgabe im Format TT.MM.JJJJ

Auf der Rechnung standen die Daten bisher in ISO-Form (2026-08-22).

- Neuer Helfer datum_de() formatiert nach TT.MM.JJJJ. Er versteht ISO
  und bereits deutsche Eingaben und laesst alles Unbekannte unveraendert
  statt es zu verstuemmeln.
- Angewendet auf Rechnungs- und Leistungsdatum im PDF sowie auf die
  Datumszeile im TXT-Export. Auch als Jinja-Filter registriert.
- Gespeichert wird weiterhin ISO: sortierbar und eindeutig. Nur die
  Ausgabe ist deutsch.
- Die beiden Datumsfelder auf der Rechnungsseite sind jetzt
  type="date". Der Browser zeigt sie im deutschen Format mit
  Kalenderauswahl und liefert intern sauberes ISO zurueck, womit
  mehrdeutige Freitexteingaben entfallen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Erik Thiele
2026-08-22 12:35:48 +02:00
parent ab6d02eccb
commit e1142ac904
2 changed files with 27 additions and 6 deletions

29
app.py
View File

@@ -82,6 +82,24 @@ ZAHLUNGSZIEL = "Zahlbar innerhalb von 14 Tagen ohne Abzug."
DANK = "Vielen Dank für Ihren Auftrag!"
def datum_de(wert):
"""Formatiert ein Datum als TT.MM.JJJJ.
Intern wird ISO (JJJJ-MM-TT) gespeichert -- das ist sortierbar und
eindeutig. Bereits deutsche Eingaben werden durchgereicht, alles
Unbekannte unveraendert gelassen statt verstuemmelt.
"""
text = str(wert or '').strip()
if not text:
return ''
for muster in ('%Y-%m-%d', '%d.%m.%Y', '%d.%m.%y'):
try:
return datetime.strptime(text, muster).strftime('%d.%m.%Y')
except ValueError:
continue
return text
def mwst_satz_label(satz):
"""Formatiert den Steuersatz ohne unnoetige Nachkommastellen (19 statt 19.0)."""
return f"{satz:g}"
@@ -536,6 +554,9 @@ def calculate(data):
# ---------------------------------------------------------------------------
app.jinja_env.filters['datum_de'] = datum_de
@app.context_processor
def inject_konstanten():
"""Stellt den §19-Hinweis allen Templates zur Verfuegung."""
@@ -807,11 +828,11 @@ def invoice_pdf():
kunde = pdf_text(data.get('kundenName', config.get('kundenName', '')))
adresse = pdf_text(data.get('kundenAdresse', config.get('kundenAdresse', '')))
rechnungsnummer = pdf_text(data.get('rechnungsnummer', config.get('rechnungsnummer', '')))
datum = pdf_text(data.get('datum', config.get('datum', '')))
datum = pdf_text(datum_de(data.get('datum', config.get('datum', ''))))
# §14 UStG verlangt den Leistungszeitpunkt. Fehlt er, gilt das
# Rechnungsdatum -- dann ist der uebliche Zusatz noetig.
leistungsdatum = pdf_text(data.get('leistungsdatum',
config.get('leistungsdatum', '')))
leistungsdatum = pdf_text(datum_de(data.get('leistungsdatum',
config.get('leistungsdatum', ''))))
projekt = pdf_text(config.get('projektName', ''))
pdf = FPDF()
@@ -993,7 +1014,7 @@ def export():
"=" * 58 + "",
"",
f"Projekt: {merged.get('projektName', '')}",
f"Datum: {merged.get('datum', '')}",
f"Datum: {datum_de(merged.get('datum', ''))}",
"",
]

View File

@@ -52,11 +52,11 @@
</div>
<div class="col-md-6">
<label class="form-label">Rechnungsdatum</label>
<input type="text" class="form-control" name="datum" data-var="datum" value="{{ config.datum }}">
<input type="date" class="form-control" name="datum" data-var="datum" value="{{ config.datum }}">
</div>
<div class="col-md-6">
<label class="form-label">Leistungsdatum</label>
<input type="text" class="form-control" name="leistungsdatum" data-var="leistungsdatum" value="{{ config.leistungsdatum }}" placeholder="leer = wie Rechnungsdatum">
<input type="date" class="form-control" name="leistungsdatum" data-var="leistungsdatum" value="{{ config.leistungsdatum }}">
{% if calc.ist_unternehmer %}<div class="form-text">Pflichtangabe nach §14 UStG. Leer lassen, wenn Leistung am Rechnungsdatum erbracht wurde.</div>{% else %}<div class="form-text">Optional &ndash; bei Privatverkauf keine Pflichtangabe.</div>{% endif %}
</div>
<div class="col-12">