diff --git a/Website/modules/emailservice/email.py b/Website/modules/emailservice/email.py index ea302f5..20d58fb 100644 --- a/Website/modules/emailservice/email.py +++ b/Website/modules/emailservice/email.py @@ -7,8 +7,24 @@ import os import tempfile from fpdf import FPDF from flask import current_app +from weasyprint import HTML +SELLER_INFO = { + "company_name": "Invario UG", + "sub_title": "Inventar- & Schulsoftware", + "owner": "Invario Team", + "street": "Am Sportplatz 10", + "zip_city": "83052 Bruckmühl", + "email": "info@invario-software.de", + "website": "https://invario-software.de", + "bank_name": "Commerzbank AG", + "iban": "DE27 7114 0041 0183 3136 00", + "bic": "COBADEFFXXX", + "tax_number": "143/100/12345", + "vat_id": "HRB 35441" +} + def _build_smtp_client(): smtp = smtplib.SMTP( "mail.invario-software.de", @@ -336,6 +352,458 @@ def generate_main_contract_pdf( pdf.output(output_path) return output_path +def generate_invoice_pdf( + invoice_number: str, + invoice_date: str, + due_date: str, + customer: dict, + seller: dict, + items: list, + output_path: str, + notes: str = None +) -> str: + """ + Generiert eine professionelle PDF-Rechnung mit WeasyPrint. + + :param invoice_number: Rechnungsnummer (z. B. "INV-20260827-100002") + :param invoice_date: Rechnungsdatum (z. B. "27.08.2026") + :param due_date: Fälligkeitsdatum (z. B. "10.09.2026") + :param customer: Dict mit Kundeninformationen (name, attn, street, zip_city, customer_id) + :param seller: Dict mit Verkäuferinformationen (company_name, street, zip_city, iban, bic, vat_id, etc.) + :param items: Liste von Dicts mit Leistungspositionen (description, details, quantity, unit_price, tax_rate) + :param output_path: Zielpfad für die generierte PDF-Datei + :param notes: Optionaler Hinweistext (z. B. Zahlungsbedingungen oder Kleinunternehmerregelung) + """ + # 1. Summen und Steuern berechnen + subtotal = 0.0 + tax_totals = {} + + processed_items = [] + for item in items: + qty = item.get("quantity", 1) + unit_price = item.get("unit_price", 0.0) + tax_rate = item.get("tax_rate", 19.0) + + line_total = qty * unit_price + subtotal += line_total + + tax_amount = line_total * (tax_rate / 100.0) + tax_totals[tax_rate] = tax_totals.get(tax_rate, 0.0) + tax_amount + + processed_items.append({ + "pos": len(processed_items) + 1, + "description": item.get("description", ""), + "details": item.get("details", ""), + "quantity": qty, + "unit_price": f"{unit_price:,.2f}".replace(",", "X").replace(".", ",").replace("X", "."), + "tax_rate": f"{tax_rate:.0f}%" if tax_rate.is_integer() else f"{tax_rate:.1f}%", + "line_total": f"{line_total:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".") + }) + + total_tax = sum(tax_totals.values()) + grand_total = subtotal + total_tax + + formatted_subtotal = f"{subtotal:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".") + formatted_grand_total = f"{grand_total:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".") + + # Tabellenzeilen für Leistungen erzeugen + items_html = "" + for item in processed_items: + details_html = f'
|
+ {seller.get('company_name', 'INVARIO')}
+ {seller.get('sub_title', 'Software & Inventarsysteme')}
+ |
+
+ {seller.get('company_name', '')} + {seller.get('street', '')} + {seller.get('zip_city', '')} + E-Mail: {seller.get('email', '')} + Web: {seller.get('website', '')} + |
+
|
+
+ {seller.get('company_name', '')} • {seller.get('street', '')} • {seller.get('zip_city', '')}
+
+
+ {customer.get('name', '')}
+ + {f"z. Hd. {customer['attn']} " if customer.get('attn') else ""} + {customer.get('street', '')} + {customer.get('zip_city', '')} + |
+
+
+
+
|
+
| Pos. | +Beschreibung | +Menge | +Einzelpreis | +MwSt. | +Gesamt | +
|---|
| Zwischensumme (netto): | +{formatted_subtotal} € | +
| Gesamtbetrag: | +{formatted_grand_total} € | +
|
+
+ {seller.get('company_name', '')} + Inhaber: {seller.get('owner', '')} + {seller.get('street', '')} + {seller.get('zip_city', '')} + |
+
+
+ Bank: {seller.get('bank_name', '')} + IBAN: {seller.get('iban', '')} + BIC: {seller.get('bic', '')} + Verwendungszweck: {invoice_number} + |
+
+
+ Steuernummer: {seller.get('tax_number', '')} + USt-IdNr.: {seller.get('vat_id', '')} + Amtsgericht: {seller.get('court', 'München')} + |
+
Vielen Dank für Ihre Akkreditierung. Im Anhang finden Sie Ihren Hauptvertrag, Ihre Rechnung sowie AGB und AVV. + Bitte laden Sie die Dokumente herunter und unterschreiben Sie den Hauptvertrag. Danach können Sie die Unterlagen per E-Mail an uns zurücksenden oder über das Invario-Portal hochladen, um die Akkreditierung abzuschließen.
Registergericht: Amtsgericht Traunstein
- Registernummer: HRB 123456
+ Registernummer: HRB 35441
USt-ID: DE 123 456 789