MWST optional: Schalter in Einstellungen (mwst_ausweisen), standardmassig Ausweis deaktiviert
This commit is contained in:
22
app.py
22
app.py
@@ -31,6 +31,7 @@ DEFAULT_VALUES = {
|
|||||||
'stundenlohn': 25,
|
'stundenlohn': 25,
|
||||||
'gewinnmarge': 20,
|
'gewinnmarge': 20,
|
||||||
'stueckzahl': 1,
|
'stueckzahl': 1,
|
||||||
|
'mwst_ausweisen': False,
|
||||||
'rechnungsnummer': '',
|
'rechnungsnummer': '',
|
||||||
'datum': datetime.now().strftime('%Y-%m-%d'),
|
'datum': datetime.now().strftime('%Y-%m-%d'),
|
||||||
'dark_mode': False,
|
'dark_mode': False,
|
||||||
@@ -89,7 +90,8 @@ def calculate(data):
|
|||||||
gesamtkosten_netto = materialkosten + stromkosten + abschreibung + arbeitskosten
|
gesamtkosten_netto = materialkosten + stromkosten + abschreibung + arbeitskosten
|
||||||
gewinn = gesamtkosten_netto * (float(data.get('gewinnmarge', 0)) / 100)
|
gewinn = gesamtkosten_netto * (float(data.get('gewinnmarge', 0)) / 100)
|
||||||
verkaufspreis = gesamtkosten_netto + gewinn
|
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
|
gesamt_brutto = verkaufspreis + mwst
|
||||||
|
|
||||||
material_preis_pro_kg = float(data.get('materialPreisProKg', 0))
|
material_preis_pro_kg = float(data.get('materialPreisProKg', 0))
|
||||||
@@ -103,6 +105,7 @@ def calculate(data):
|
|||||||
'gewinn': round(gewinn, 2),
|
'gewinn': round(gewinn, 2),
|
||||||
'verkaufspreis': round(verkaufspreis, 2),
|
'verkaufspreis': round(verkaufspreis, 2),
|
||||||
'mwst': round(mwst, 2),
|
'mwst': round(mwst, 2),
|
||||||
|
'mwst_ausweisen': mwst_ausweisen,
|
||||||
'gesamt_brutto': round(gesamt_brutto, 2),
|
'gesamt_brutto': round(gesamt_brutto, 2),
|
||||||
'druckzeit_stunden': round(druckzeit_stunden, 2),
|
'druckzeit_stunden': round(druckzeit_stunden, 2),
|
||||||
'material_kg': round(material_kg, 3),
|
'material_kg': round(material_kg, 3),
|
||||||
@@ -169,7 +172,7 @@ def invoice_pdf():
|
|||||||
calc = calculate(config)
|
calc = calculate(config)
|
||||||
stueckzahl = int(config.get('stueckzahl', 1))
|
stueckzahl = int(config.get('stueckzahl', 1))
|
||||||
gesamt_netto = round(calc['verkaufspreis'] * stueckzahl, 2)
|
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)
|
gesamt_brutto = round(gesamt_netto + gesamt_mwst, 2)
|
||||||
|
|
||||||
pdf = FPDF()
|
pdf = FPDF()
|
||||||
@@ -201,10 +204,14 @@ def invoice_pdf():
|
|||||||
|
|
||||||
pdf.cell(130, 6, "Nettobetrag:")
|
pdf.cell(130, 6, "Nettobetrag:")
|
||||||
pdf.cell(60, 6, f"{gesamt_netto:.2f} EUR", ln=True, align='R')
|
pdf.cell(60, 6, f"{gesamt_netto:.2f} EUR", ln=True, align='R')
|
||||||
pdf.cell(130, 6, "MwSt. (19%):")
|
if calc.get('mwst_ausweisen'):
|
||||||
pdf.cell(60, 6, f"{gesamt_mwst:.2f} EUR", ln=True, align='R')
|
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)
|
pdf.set_font("Arial", "B", 12)
|
||||||
pdf.cell(130, 8, "GESAMTBETRAG:")
|
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')
|
pdf.cell(60, 8, f"{gesamt_brutto:.2f} EUR", ln=True, align='R')
|
||||||
|
|
||||||
pdf.ln(10)
|
pdf.ln(10)
|
||||||
@@ -240,9 +247,10 @@ def export():
|
|||||||
f"Gesamtkosten: {calc['gesamtkosten_netto']:.2f} EUR",
|
f"Gesamtkosten: {calc['gesamtkosten_netto']:.2f} EUR",
|
||||||
f"Gewinn: {calc['gewinn']:.2f} EUR",
|
f"Gewinn: {calc['gewinn']:.2f} EUR",
|
||||||
f"Verkaufspreis (netto): {calc['verkaufspreis']:.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)
|
text = '\n'.join(lines)
|
||||||
|
|
||||||
return send_file(
|
return send_file(
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ function getFormData() {
|
|||||||
const type = el.dataset.type || 'text';
|
const type = el.dataset.type || 'text';
|
||||||
let val = el.value;
|
let val = el.value;
|
||||||
if (type === 'number') val = parseFloat(val) || 0;
|
if (type === 'number') val = parseFloat(val) || 0;
|
||||||
|
else if (type === 'checkbox') val = el.checked;
|
||||||
data[key] = val;
|
data[key] = val;
|
||||||
});
|
});
|
||||||
data.dark_mode = document.documentElement.getAttribute('data-bs-theme') === 'dark';
|
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`,
|
`Gewinn (${((document.querySelector('[data-var="gewinnmarge"]')?.value) || 20)}%): ${String(calc.gewinn.toFixed(2)).padStart(10)} EUR`,
|
||||||
`${'\u2500'.repeat(40)}`,
|
`${'\u2500'.repeat(40)}`,
|
||||||
`Verkaufspreis (netto): ${String(calc.verkaufspreis.toFixed(2)).padStart(10)} EUR`,
|
`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');
|
document.getElementById('result-text').textContent = lines.join('\n');
|
||||||
|
|
||||||
const details = [
|
const details = [
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
{% set stueckzahl = config.stueckzahl|default(1)|int %}
|
{% set stueckzahl = config.stueckzahl|default(1)|int %}
|
||||||
{% set gesamt_netto = (calc.verkaufspreis * stueckzahl)|round(2) %}
|
{% 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) %}
|
{% 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:
|
<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 }}
|
{{ '\u2500' * 50 }}
|
||||||
@@ -82,9 +82,9 @@ Gesamt: {{ "%.2f"|format(gesamt_netto) }} EUR
|
|||||||
|
|
||||||
{{ '\u2500' * 50 }}
|
{{ '\u2500' * 50 }}
|
||||||
Nettobetrag: {{ "%.2f"|format(gesamt_netto) }} EUR
|
Nettobetrag: {{ "%.2f"|format(gesamt_netto) }} EUR
|
||||||
MwSt. (19%): {{ "%.2f"|format(gesamt_mwst) }} EUR
|
{% if calc.mwst_ausweisen %}MwSt. (19%): {{ "%.2f"|format(gesamt_mwst) }} EUR
|
||||||
{{ '\u2550' * 50 }}
|
{% endif %}{{ '\u2550' * 50 }}
|
||||||
GESAMTBETRAG: {{ "%.2f"|format(gesamt_brutto) }} EUR
|
GESAMTBETRAG{% if calc.mwst_ausweisen %} (brutto){% endif %}: {{ "%.2f"|format(gesamt_brutto) }} EUR
|
||||||
|
|
||||||
Zahlbar innerhalb von 14 Tagen ohne Abzug.
|
Zahlbar innerhalb von 14 Tagen ohne Abzug.
|
||||||
Vielen Dank fur Ihren Auftrag!</div>
|
Vielen Dank fur Ihren Auftrag!</div>
|
||||||
|
|||||||
@@ -75,13 +75,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-3">
|
<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="card-body">
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="form-label">Gewinnmarge (%)</label>
|
<label class="form-label">Gewinnmarge (%)</label>
|
||||||
<input type="number" step="0.5" class="form-control" data-var="gewinnmarge" data-type="number" value="{{ config.gewinnmarge }}">
|
<input type="number" step="0.5" class="form-control" data-var="gewinnmarge" data-type="number" value="{{ config.gewinnmarge }}">
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user