MWST optional: Schalter in Einstellungen (mwst_ausweisen), standardmassig Ausweis deaktiviert

This commit is contained in:
Erik Thiele
2026-07-02 14:39:12 +02:00
parent 4f3c6763ca
commit f77be1c07a
4 changed files with 32 additions and 15 deletions

16
app.py
View File

@@ -31,6 +31,7 @@ DEFAULT_VALUES = {
'stundenlohn': 25,
'gewinnmarge': 20,
'stueckzahl': 1,
'mwst_ausweisen': False,
'rechnungsnummer': '',
'datum': datetime.now().strftime('%Y-%m-%d'),
'dark_mode': False,
@@ -89,7 +90,8 @@ def calculate(data):
gesamtkosten_netto = materialkosten + stromkosten + abschreibung + arbeitskosten
gewinn = gesamtkosten_netto * (float(data.get('gewinnmarge', 0)) / 100)
verkaufspreis = gesamtkosten_netto + gewinn
mwst = verkaufspreis * 0.19
mwst_ausweisen = str(data.get('mwst_ausweisen', '')).lower() in ('true', '1', 'yes')
mwst = verkaufspreis * 0.19 if mwst_ausweisen else 0
gesamt_brutto = verkaufspreis + mwst
material_preis_pro_kg = float(data.get('materialPreisProKg', 0))
@@ -103,6 +105,7 @@ def calculate(data):
'gewinn': round(gewinn, 2),
'verkaufspreis': round(verkaufspreis, 2),
'mwst': round(mwst, 2),
'mwst_ausweisen': mwst_ausweisen,
'gesamt_brutto': round(gesamt_brutto, 2),
'druckzeit_stunden': round(druckzeit_stunden, 2),
'material_kg': round(material_kg, 3),
@@ -169,7 +172,7 @@ def invoice_pdf():
calc = calculate(config)
stueckzahl = int(config.get('stueckzahl', 1))
gesamt_netto = round(calc['verkaufspreis'] * stueckzahl, 2)
gesamt_mwst = round(gesamt_netto * 0.19, 2)
gesamt_mwst = round(gesamt_netto * 0.19, 2) if calc.get('mwst_ausweisen') else 0
gesamt_brutto = round(gesamt_netto + gesamt_mwst, 2)
pdf = FPDF()
@@ -201,9 +204,13 @@ def invoice_pdf():
pdf.cell(130, 6, "Nettobetrag:")
pdf.cell(60, 6, f"{gesamt_netto:.2f} EUR", ln=True, align='R')
if calc.get('mwst_ausweisen'):
pdf.cell(130, 6, "MwSt. (19%):")
pdf.cell(60, 6, f"{gesamt_mwst:.2f} EUR", ln=True, align='R')
pdf.set_font("Arial", "B", 12)
if calc.get('mwst_ausweisen'):
pdf.cell(130, 8, "GESAMTBETRAG (brutto):")
else:
pdf.cell(130, 8, "GESAMTBETRAG:")
pdf.cell(60, 8, f"{gesamt_brutto:.2f} EUR", ln=True, align='R')
@@ -240,9 +247,10 @@ def export():
f"Gesamtkosten: {calc['gesamtkosten_netto']:.2f} EUR",
f"Gewinn: {calc['gewinn']:.2f} EUR",
f"Verkaufspreis (netto): {calc['verkaufspreis']:.2f} EUR",
f"MwSt. (19%): {calc['mwst']:.2f} EUR",
f"GESAMTPREIS (brutto): {calc['gesamt_brutto']:.2f} EUR",
]
if calc.get('mwst_ausweisen'):
lines.append(f"MwSt. (19%): {calc['mwst']:.2f} EUR")
lines.append(f"GESAMTPREIS: {calc['gesamt_brutto']:.2f} EUR")
text = '\n'.join(lines)
return send_file(

View File

@@ -17,6 +17,7 @@ function getFormData() {
const type = el.dataset.type || 'text';
let val = el.value;
if (type === 'number') val = parseFloat(val) || 0;
else if (type === 'checkbox') val = el.checked;
data[key] = val;
});
data.dark_mode = document.documentElement.getAttribute('data-bs-theme') === 'dark';
@@ -52,10 +53,12 @@ function renderResult(calc) {
`Gewinn (${((document.querySelector('[data-var="gewinnmarge"]')?.value) || 20)}%): ${String(calc.gewinn.toFixed(2)).padStart(10)} EUR`,
`${'\u2500'.repeat(40)}`,
`Verkaufspreis (netto): ${String(calc.verkaufspreis.toFixed(2)).padStart(10)} EUR`,
`MwSt. (19%): ${String(calc.mwst.toFixed(2)).padStart(10)} EUR`,
`${'\u2550'.repeat(40)}`,
`GESAMT (brutto): ${String(calc.gesamt_brutto.toFixed(2)).padStart(10)} EUR`,
];
if (calc.mwst_ausweisen) {
lines.push(`MwSt. (19%): ${String(calc.mwst.toFixed(2)).padStart(10)} EUR`);
}
lines.push(`${'\u2550'.repeat(40)}`);
lines.push(`GESAMT: ${String(calc.gesamt_brutto.toFixed(2)).padStart(10)} EUR`);
document.getElementById('result-text').textContent = lines.join('\n');
const details = [

View File

@@ -71,7 +71,7 @@
<div class="card-body p-0">
{% set stueckzahl = config.stueckzahl|default(1)|int %}
{% set gesamt_netto = (calc.verkaufspreis * stueckzahl)|round(2) %}
{% set gesamt_mwst = (gesamt_netto * 0.19)|round(2) %}
{% set gesamt_mwst = (gesamt_netto * 0.19)|round(2) if calc.mwst_ausweisen else 0 %}
{% set gesamt_brutto = (gesamt_netto + gesamt_mwst)|round(2) %}
<div class="p-3" style="font-family:'Courier New',Courier,monospace;font-size:13px;line-height:1.8;white-space:pre;overflow-x:auto;background:var(--tblr-bg-surface);">LEISTUNGSBESCHREIBUNG:
{{ '\u2500' * 50 }}
@@ -82,9 +82,9 @@ Gesamt: {{ "%.2f"|format(gesamt_netto) }} EUR
{{ '\u2500' * 50 }}
Nettobetrag: {{ "%.2f"|format(gesamt_netto) }} EUR
MwSt. (19%): {{ "%.2f"|format(gesamt_mwst) }} EUR
{{ '\u2550' * 50 }}
GESAMTBETRAG: {{ "%.2f"|format(gesamt_brutto) }} EUR
{% if calc.mwst_ausweisen %}MwSt. (19%): {{ "%.2f"|format(gesamt_mwst) }} EUR
{% endif %}{{ '\u2550' * 50 }}
GESAMTBETRAG{% if calc.mwst_ausweisen %} (brutto){% endif %}: {{ "%.2f"|format(gesamt_brutto) }} EUR
Zahlbar innerhalb von 14 Tagen ohne Abzug.
Vielen Dank fur Ihren Auftrag!</div>

View File

@@ -75,13 +75,19 @@
</div>
<div class="card mb-3">
<div class="card-header"><i class="ti ti-currency-euro me-2"></i>Gewinnmarge</div>
<div class="card-header"><i class="ti ti-currency-euro me-2"></i>Gewinnmarge & Steuer</div>
<div class="card-body">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Gewinnmarge (%)</label>
<input type="number" step="0.5" class="form-control" data-var="gewinnmarge" data-type="number" value="{{ config.gewinnmarge }}">
</div>
<div class="col-md-6 d-flex align-items-end pb-2">
<label class="form-check form-switch form-check-custom mb-0">
<input class="form-check-input" type="checkbox" data-var="mwst_ausweisen" data-type="checkbox" {% if config.mwst_ausweisen %}checked{% endif %}>
<span class="form-check-label">MwSt. ausweisen (19%)</span>
</label>
</div>
</div>
</div>
</div>