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:
29
app.py
29
app.py
@@ -82,6 +82,24 @@ ZAHLUNGSZIEL = "Zahlbar innerhalb von 14 Tagen ohne Abzug."
|
|||||||
DANK = "Vielen Dank für Ihren Auftrag!"
|
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):
|
def mwst_satz_label(satz):
|
||||||
"""Formatiert den Steuersatz ohne unnoetige Nachkommastellen (19 statt 19.0)."""
|
"""Formatiert den Steuersatz ohne unnoetige Nachkommastellen (19 statt 19.0)."""
|
||||||
return f"{satz:g}"
|
return f"{satz:g}"
|
||||||
@@ -536,6 +554,9 @@ def calculate(data):
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
app.jinja_env.filters['datum_de'] = datum_de
|
||||||
|
|
||||||
|
|
||||||
@app.context_processor
|
@app.context_processor
|
||||||
def inject_konstanten():
|
def inject_konstanten():
|
||||||
"""Stellt den §19-Hinweis allen Templates zur Verfuegung."""
|
"""Stellt den §19-Hinweis allen Templates zur Verfuegung."""
|
||||||
@@ -807,11 +828,11 @@ def invoice_pdf():
|
|||||||
kunde = pdf_text(data.get('kundenName', config.get('kundenName', '')))
|
kunde = pdf_text(data.get('kundenName', config.get('kundenName', '')))
|
||||||
adresse = pdf_text(data.get('kundenAdresse', config.get('kundenAdresse', '')))
|
adresse = pdf_text(data.get('kundenAdresse', config.get('kundenAdresse', '')))
|
||||||
rechnungsnummer = pdf_text(data.get('rechnungsnummer', config.get('rechnungsnummer', '')))
|
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
|
# §14 UStG verlangt den Leistungszeitpunkt. Fehlt er, gilt das
|
||||||
# Rechnungsdatum -- dann ist der uebliche Zusatz noetig.
|
# Rechnungsdatum -- dann ist der uebliche Zusatz noetig.
|
||||||
leistungsdatum = pdf_text(data.get('leistungsdatum',
|
leistungsdatum = pdf_text(datum_de(data.get('leistungsdatum',
|
||||||
config.get('leistungsdatum', '')))
|
config.get('leistungsdatum', ''))))
|
||||||
projekt = pdf_text(config.get('projektName', ''))
|
projekt = pdf_text(config.get('projektName', ''))
|
||||||
|
|
||||||
pdf = FPDF()
|
pdf = FPDF()
|
||||||
@@ -993,7 +1014,7 @@ def export():
|
|||||||
"=" * 58 + "",
|
"=" * 58 + "",
|
||||||
"",
|
"",
|
||||||
f"Projekt: {merged.get('projektName', '')}",
|
f"Projekt: {merged.get('projektName', '')}",
|
||||||
f"Datum: {merged.get('datum', '')}",
|
f"Datum: {datum_de(merged.get('datum', ''))}",
|
||||||
"",
|
"",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -52,11 +52,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="form-label">Rechnungsdatum</label>
|
<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>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="form-label">Leistungsdatum</label>
|
<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 – bei Privatverkauf keine Pflichtangabe.</div>{% endif %}
|
{% 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 – bei Privatverkauf keine Pflichtangabe.</div>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
|||||||
Reference in New Issue
Block a user