diff --git a/invoice_logic.py b/invoice_logic.py index ce137ce..6e93413 100644 --- a/invoice_logic.py +++ b/invoice_logic.py @@ -559,10 +559,11 @@ def generate_compliant_xrechnung(data): ET.SubElement(root, f"{{{CBC}}}DocumentCurrencyCode").text = "EUR" # BT-10 Käuferreferenz = Leitweg-ID: NUR bei Behörden-Rechnungen (B2G) vorhanden. Fehlt sie, - # wird das Element weggelassen; bei XRechnung blockiert die UI den Export (BR-DE-15 Pflicht), - # bei ZUGFeRD (B2B) bleibt es zulässigerweise leer. - if data.get("leitweg_id") and str(data["leitweg_id"]).strip() != "": - ET.SubElement(root, f"{{{CBC}}}BuyerReference").text = str(data["leitweg_id"]).strip() + # wird das Element weggelassen. BT-10 ist in XRechnung Pflicht (BR-DE-15), darf aber nie leer + # sein: bei Behoerden (B2G) die Leitweg-ID, sonst als Fallback die Kundennummer. + _buyer_ref_bt10 = str(data.get("leitweg_id") or data.get("customer_number") or "").strip() + if _buyer_ref_bt10: + ET.SubElement(root, f"{{{CBC}}}BuyerReference").text = _buyer_ref_bt10 if data.get("service_start_date") and data.get("service_end_date"): period_elem = ET.SubElement(root, f"{{{CAC}}}InvoicePeriod") @@ -837,10 +838,11 @@ def generate_compliant_zugferd_cii(data): ET.SubElement(mon_sum, f"{{{RAM}}}LineTotalAmount").text = f"{item['total_amount']:.2f}" header_agree = ET.SubElement(trade_trans, f"{{{RAM}}}ApplicableHeaderTradeAgreement") - # BT-10 Käuferreferenz = Leitweg-ID: nur bei Behörden-Rechnungen (B2G). Fehlt sie, wird das - # Element weggelassen (bei ZUGFeRD/B2B zulässig; bei XRechnung blockiert die UI). - if data.get("leitweg_id") and str(data["leitweg_id"]).strip() != "": - ET.SubElement(header_agree, f"{{{RAM}}}BuyerReference").text = str(data["leitweg_id"]).strip() + # BT-10 Käuferreferenz: bei Behörden (B2G) die Leitweg-ID, sonst als Fallback die Kundennummer, + # damit das in XRechnung verpflichtende Feld (BR-DE-15) nie leer bleibt. + _buyer_ref_bt10 = str(data.get("leitweg_id") or data.get("customer_number") or "").strip() + if _buyer_ref_bt10: + ET.SubElement(header_agree, f"{{{RAM}}}BuyerReference").text = _buyer_ref_bt10 supplier_party = ET.SubElement(header_agree, f"{{{RAM}}}SellerTradeParty") ET.SubElement(supplier_party, f"{{{RAM}}}Name").text = VERKAEUFER["name"] diff --git a/main.py b/main.py index a6139e1..be7bf3a 100644 --- a/main.py +++ b/main.py @@ -341,8 +341,9 @@ with col2: leitweg_id = st.text_input( "Leitweg-ID (BT-10)", value=data.get("leitweg_id", ""), - help="Nur für Behörden-Rechnungen (B2G). Bei XRechnung Pflicht (BR-DE-15) - dann die " - "Leitweg-ID der Behörde eintragen. Bei ZUGFeRD / B2B leer lassen.", + help="Nur für Behörden-Rechnungen (B2G) die Leitweg-ID eintragen. Bleibt das Feld leer " + "(normaler B2B-Fall), wird automatisch die Kundennummer als Käuferreferenz (BT-10) " + "verwendet - so bleibt das für XRechnung verpflichtende Feld nie leer.", ) buyer_ref = st.text_input( "Ihr Auftrag / Bestellnummer (BT-13)", @@ -586,10 +587,10 @@ with col2: if parse_to_strict_xml_date(inv_date) == "": blocker.append("Rechnungsdatum (BT-2) fehlt oder ist unlesbar (erwartet: YYYY-MM-DD). " "Bitte korrigieren - es wird KEIN Datum automatisch eingesetzt.") - if is_xrechnung and not str(leitweg_id).strip(): - blocker.append("Leitweg-ID / Käuferreferenz (BT-10) fehlt. Bei XRechnung ist sie Pflicht " - "(BR-DE-15) - für Behörden-Rechnungen bitte die Leitweg-ID eintragen. " - "(Bei ZUGFeRD/B2B ist das Feld optional.)") + if is_xrechnung and not str(leitweg_id).strip() and not str(cust_num).strip(): + blocker.append("Käuferreferenz (BT-10) fehlt. Bei XRechnung ist sie Pflicht (BR-DE-15) - " + "bitte die Leitweg-ID (Behörden) ODER mindestens die Kundennummer (BT-46) " + "eintragen; letztere wird sonst automatisch als Käuferreferenz verwendet.") if is_xrechnung and not str(r_email).strip(): blocker.append("Elektronische Adresse des Kunden (BT-49) fehlt. Bei XRechnung ist sie " "Pflicht (PEPPOL-EN16931-R010) - entweder E-Mail-Adresse oder Netzwerkcode "