Zahlungsziel als Klartext (BT-20) und Zahlungsreferenz (BT-83) ergänzt.
BT-20: Das Zahlungsziel erscheint zusätzlich zum strukturierten Fälligkeits-
datum im Klartext ("Zahlbar innerhalb von 14 Tagen ohne Abzug."). Bei Vorkasse
bewusst unterdrückt, da sich beide Angaben widersprechen würden.
BT-83: Die Rechnungsnummer als Verwendungszweck für den automatischen
Zahlungsabgleich - cbc:PaymentID (UBL) bzw. ram:PaymentReference (CII), jeweils
an der schema-korrekten Position der Sequenz.
Beides ergab der Vergleich gegen fünf Eingangs-E-Rechnungen: BT-20 lieferten
vier von fünf Lieferanten, BT-83 zwei von fünf.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
4b4118fe70
commit
df015c9f97
|
|
@ -157,13 +157,36 @@ def format_skonto_text(skonto_percent, skonto_days, invoice_date_str):
|
|||
return f"Bei Zahlung innerhalb von {days} Tagen gewähren wir {percent_str}% Skonto."
|
||||
|
||||
|
||||
def format_payment_term_text(payment_term_days):
|
||||
"""Klartext des Zahlungsziels fuer BT-20 ('14' -> 'Zahlbar innerhalb von 14 Tagen ohne
|
||||
Abzug.'). Das Faelligkeitsdatum steht strukturiert in BT-9; der Klartext daneben ist bei
|
||||
Lieferanten die Regel (4 von 5 Eingangsrechnungen liefern ihn) und fuer den Empfaenger
|
||||
lesbar. Gibt "" zurueck, wenn kein gueltiges Zahlungsziel angegeben ist - es wird NICHTS
|
||||
geraten."""
|
||||
try:
|
||||
days = int(str(payment_term_days).strip())
|
||||
except (TypeError, ValueError):
|
||||
return ""
|
||||
if days <= 0:
|
||||
return ""
|
||||
return f"Zahlbar innerhalb von {days} Tagen ohne Abzug."
|
||||
|
||||
|
||||
def build_payment_terms_note(data):
|
||||
"""Kombinierter Freitext fuer die Zahlungsbedingungen (BT-20): optionaler Vorkasse-Hinweis
|
||||
und/oder eine Skonto-Vereinbarung. Beides sind Zahlungsbedingungen, fuer die EN16931 kein
|
||||
eigenes strukturiertes Feld kennt. Gibt "" zurueck, wenn keiner von beiden gesetzt ist."""
|
||||
"""Kombinierter Freitext fuer die Zahlungsbedingungen (BT-20): das Zahlungsziel im Klartext
|
||||
ODER ein Vorkasse-Hinweis, jeweils optional ergaenzt um eine Skonto-Vereinbarung. Fuer all
|
||||
das kennt EN16931 kein eigenes strukturiertes Feld. Gibt "" zurueck, wenn nichts davon
|
||||
gesetzt ist.
|
||||
|
||||
Vorkasse und Zahlungsziel schliessen sich bewusst aus: 'Zahlung per Vorkasse vor Lieferung'
|
||||
und 'zahlbar innerhalb von 14 Tagen' wuerden sich widersprechen."""
|
||||
parts = []
|
||||
if data.get("vorkasse"):
|
||||
parts.append(VORKASSE_HINWEIS)
|
||||
else:
|
||||
term_text = format_payment_term_text(data.get("payment_term_days"))
|
||||
if term_text:
|
||||
parts.append(term_text)
|
||||
skonto_text = format_skonto_text(
|
||||
data.get("skonto_percent"), data.get("skonto_days"), data["invoice_date"]
|
||||
)
|
||||
|
|
@ -1050,6 +1073,11 @@ def generate_compliant_xrechnung(data):
|
|||
# BT-81 Zahlungsart: Standard bleibt 58 (SEPA-Ueberweisung), aber ueber
|
||||
# PAYMENT_MEANS_CODES pro Rechnung waehlbar (siehe UN/EDIFACT 4461).
|
||||
ET.SubElement(payment_means, f"{{{CBC}}}PaymentMeansCode").text = str(data.get("payment_means_code", "58"))
|
||||
# BT-83 Zahlungsreferenz (Verwendungszweck): die Rechnungsnummer, damit der Empfaenger die
|
||||
# Zahlung automatisch zuordnen kann. Muss laut UBL-Sequenz NACH PaymentMeansCode und VOR
|
||||
# PayeeFinancialAccount stehen.
|
||||
if str(data.get("invoice_number") or "").strip():
|
||||
ET.SubElement(payment_means, f"{{{CBC}}}PaymentID").text = str(data["invoice_number"]).strip()
|
||||
payee_acc = ET.SubElement(payment_means, f"{{{CAC}}}PayeeFinancialAccount")
|
||||
ET.SubElement(payee_acc, f"{{{CBC}}}ID").text = str(data["iban"]).replace(" ", "")
|
||||
# BT-86 BIC der Verkaeuferbank (optional, aber von vielen Empfaengern erwartet).
|
||||
|
|
@ -1351,6 +1379,11 @@ def generate_compliant_zugferd_cii(data):
|
|||
ET.SubElement(dn_ref, f"{{{RAM}}}IssuerAssignedID").text = str(data["delivery_note_id"]).strip()
|
||||
|
||||
header_settle = ET.SubElement(trade_trans, f"{{{RAM}}}ApplicableHeaderTradeSettlement")
|
||||
# BT-83 Zahlungsreferenz (Verwendungszweck): die Rechnungsnummer, damit der Empfaenger die
|
||||
# Zahlung automatisch zuordnen kann. Muss laut CII-Sequenz VOR InvoiceCurrencyCode stehen
|
||||
# (die Sequenz ist CreditorReferenceID -> PaymentReference -> ... -> InvoiceCurrencyCode).
|
||||
if str(data.get("invoice_number") or "").strip():
|
||||
ET.SubElement(header_settle, f"{{{RAM}}}PaymentReference").text = str(data["invoice_number"]).strip()
|
||||
ET.SubElement(header_settle, f"{{{RAM}}}InvoiceCurrencyCode").text = "EUR"
|
||||
|
||||
pay_means = ET.SubElement(header_settle, f"{{{RAM}}}SpecifiedTradeSettlementPaymentMeans")
|
||||
|
|
|
|||
Loading…
Reference in New Issue