diff --git a/app.py b/app.py index 37b4423..1081023 100644 --- a/app.py +++ b/app.py @@ -35,6 +35,13 @@ DEFAULT_VALUES = { 'rechnungsnummer': '', 'datum': datetime.now().strftime('%Y-%m-%d'), 'dark_mode': False, + 'firmenName': '', + 'firmenAdresse': '', + 'telefon': '', + 'email': '', + 'paypal': '', + 'iban': '', + 'bankName': '', } @@ -175,50 +182,159 @@ def invoice_pdf(): gesamt_mwst = round(gesamt_netto * 0.19, 2) if calc.get('mwst_ausweisen') else 0 gesamt_brutto = round(gesamt_netto + gesamt_mwst, 2) + firmen_name = config.get('firmenName', '') + firmen_adresse = config.get('firmenAdresse', '') + telefon = config.get('telefon', '') + email = config.get('email', '') + paypal = config.get('paypal', '') + iban = config.get('iban', '') + bank_name = config.get('bankName', '') + + kunde = data.get('kundenName', config.get('kundenName', '')) + adresse = data.get('kundenAdresse', config.get('kundenAdresse', '')) + rechnungsnummer = data.get('rechnungsnummer', config.get('rechnungsnummer', '')) + datum = data.get('datum', config.get('datum', '')) + projekt = config.get('projektName', '') + pdf = FPDF() pdf.add_page() - pdf.set_font("Arial", "B", 24) - pdf.cell(0, 15, "RECHNUNG", ln=True, align='L') - pdf.ln(10) - pdf.set_font("Arial", "", 11) - rechnungsnummer = data.get('rechnungsnummer', config.get('rechnungsnummer', '')) - if rechnungsnummer: - pdf.cell(0, 6, f"Rechnungsnummer: {rechnungsnummer}", ln=True) - pdf.cell(0, 6, f"Datum: {data.get('datum', config.get('datum', ''))}", ln=True) - pdf.ln(10) + left = 15 + right_margin = 15 + col_left = left + col_right = 120 + col_w = 80 - pdf.set_font("Arial", "B", 12) - pdf.cell(0, 6, "Rechnungsempfanger:", ln=True) - pdf.set_font("Arial", "", 11) - pdf.cell(0, 6, data.get('kundenName', config.get('kundenName', '')), ln=True) - pdf.multi_cell(0, 6, data.get('kundenAdresse', config.get('kundenAdresse', ''))) - pdf.ln(5) + # --- Header: Absender links, Logo rechts --- + pdf.set_font("Arial", "B", 11) + pdf.set_xy(col_left, 15) + pdf.cell(col_w, 5, firmen_name, ln=True) + pdf.set_font("Arial", "", 9) + if firmen_adresse: + pdf.set_x(col_left) + pdf.cell(col_w, 4, firmen_adresse, ln=True) + contact_parts = [] + if telefon: + contact_parts.append(f"Tel: {telefon}") + if email: + contact_parts.append(f"Mail: {email}") + if contact_parts: + pdf.set_x(col_left) + pdf.cell(col_w, 4, " | ".join(contact_parts), ln=True) - pdf.set_font("Arial", "B", 12) - pdf.cell(0, 8, "Leistungsbeschreibung:", ln=True) - pdf.set_font("Arial", "", 11) - pdf.cell(100, 8, f"3D-Druck: {config.get('projektName', '')}") - pdf.cell(30, 8, str(stueckzahl), align='R') - pdf.cell(30, 8, f"{calc['verkaufspreis']:.2f} EUR", align='R') - pdf.cell(30, 8, f"{gesamt_netto:.2f} EUR", ln=True, align='R') - pdf.ln(10) + # Logo rechts + pdf.set_font("Arial", "B", 22) + pdf.set_xy(col_right, 15) + y_logo = pdf.get_y() - 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') + line1 = "JET" + line2 = "Design" + pdf.set_xy(col_right, y_logo) + pdf.set_text_color(6, 111, 209) + pdf.cell(col_w, 8, line1, ln=True, align='R') + pdf.set_x(col_right) + pdf.cell(col_w, 8, line2, ln=True, align='R') + pdf.set_text_color(0, 0, 0) - pdf.ln(10) + # --- Rechnungsdaten --- + invoice_y = max(pdf.get_y(), 50) + pdf.set_xy(left, invoice_y) pdf.set_font("Arial", "", 10) - pdf.multi_cell(0, 5, "Zahlbar innerhalb von 14 Tagen ohne Abzug.\nVielen Dank fur Ihren Auftrag!") + if rechnungsnummer: + pdf.cell(col_w, 5, f"Rechnungsnr.: {rechnungsnummer}", ln=True) + pdf.set_x(left) + pdf.cell(col_w, 5, f"Datum: {datum}", ln=True) + + # --- Empfänger --- + pdf.set_xy(left, pdf.get_y() + 10) + pdf.set_font("Arial", "B", 10) + pdf.cell(col_w, 5, "Rechnungsempfanger:", ln=True) + pdf.set_font("Arial", "", 10) + pdf.set_x(left) + pdf.cell(col_w, 5, kunde, ln=True) + if adresse: + pdf.set_x(left) + pdf.set_font("Arial", "", 9) + for line in adresse.split('\n'): + pdf.set_x(left) + pdf.cell(col_w, 4, line.strip(), ln=True) + + # --- Trennlinie --- + pdf.set_draw_color(220, 220, 220) + pdf.line(left, pdf.get_y() + 6, 195, pdf.get_y() + 6) + pdf.set_draw_color(0, 0, 0) + + # --- Positionstabelle --- + table_y = pdf.get_y() + 10 + pdf.set_xy(left, table_y) + pdf.set_font("Arial", "B", 10) + pdf.cell(85, 6, "Leistungsbeschreibung") + pdf.cell(20, 6, "Menge", align='R') + pdf.cell(30, 6, "Einzelpreis", align='R') + pdf.cell(30, 6, "Gesamt", ln=True, align='R') + + pdf.set_draw_color(200, 200, 200) + pdf.line(left, pdf.get_y() + 0.5, 195, pdf.get_y() + 0.5) + pdf.set_draw_color(0, 0, 0) + + pdf.set_font("Arial", "", 10) + pdf.set_x(left) + pos_label = f"3D-Druck: {projekt}" if projekt else "3D-Druck" + pdf.cell(85, 7, pos_label) + pdf.cell(20, 7, str(stueckzahl), align='R') + pdf.cell(30, 7, f"{calc['verkaufspreis']:.2f} EUR", align='R') + pdf.cell(30, 7, f"{gesamt_netto:.2f} EUR", ln=True, align='R') + + pdf.line(left, pdf.get_y() + 0.5, 195, pdf.get_y() + 0.5) + + # --- Summen --- + pdf.set_x(left) + pdf.ln(8) + pdf.set_font("Arial", "", 10) + pdf.cell(130, 6, "Nettobetrag:") + pdf.cell(50, 6, f"{gesamt_netto:.2f} EUR", ln=True, align='R') + if calc.get('mwst_ausweisen'): + pdf.set_x(left) + pdf.cell(130, 6, "MwSt. (19%):") + pdf.cell(50, 6, f"{gesamt_mwst:.2f} EUR", ln=True, align='R') + pdf.set_font("Arial", "B", 12) + pdf.set_x(left) + label_total = "GESAMTBETRAG (brutto):" if calc.get('mwst_ausweisen') else "GESAMTBETRAG:" + pdf.cell(130, 8, label_total) + pdf.cell(50, 8, f"{gesamt_brutto:.2f} EUR", ln=True, align='R') + + # --- Zahlungsbedingungen --- + pdf.set_font("Arial", "", 9) + pdf.set_x(left) + pdf.ln(6) + pdf.cell(0, 4, "Zahlbar innerhalb von 14 Tagen ohne Abzug. Vielen Dank fur Ihren Auftrag!") + + # --- Footer --- + pdf.set_y(-35) + pdf.set_draw_color(180, 180, 180) + pdf.line(left, pdf.get_y(), 195, pdf.get_y()) + pdf.set_draw_color(0, 0, 0) + pdf.ln(3) + pdf.set_font("Arial", "", 8) + pdf.set_text_color(100, 100, 100) + footer_parts = [firmen_name] if firmen_name else [] + if telefon: + footer_parts.append(f"Tel: {telefon}") + if email: + footer_parts.append(email) + if footer_parts: + pdf.set_x(left) + pdf.cell(0, 4, " | ".join(footer_parts), ln=True) + if paypal: + pdf.set_x(left) + pdf.cell(0, 4, f"PayPal: {paypal}", ln=True) + if iban and bank_name: + pdf.set_x(left) + pdf.cell(0, 4, f"{iban} | {bank_name}", ln=True) + elif iban: + pdf.set_x(left) + pdf.cell(0, 4, iban, ln=True) + pdf.set_text_color(0, 0, 0) return send_file( io.BytesIO(pdf.output(dest='S').encode('latin-1')), diff --git a/templates/settings.html b/templates/settings.html index c850efd..28df781 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -42,6 +42,42 @@
+
+
Firmendaten
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
Drucker Abschreibung