Table of Contents

Events Export

Wichtig

Um Header-Felder vor der XML-Generierung zu überschreiben, sollte das Event OnBeforeInsertXRechnungHeader verwendet werden. Dieses Event erfordert eine App-Dependency auf die SIEVERS E-Rechnung App.

Anpassungen über den OnDatabaseInsert-Trigger (z. B. per RecRef/FieldRef) werden durch ein erneutes Lesen (Get) des Headers unmittelbar vor der XML-Generierung berücksichtigt. Diese Vorgehensweise ist jedoch unzuverlässig und widerspricht dem AL-Architekturmodell. Der Weg über die App-Dependency und die Nutzung von Events ist der von Microsoft empfohlene Weg, benutzerdefinierte Änderungen durchzuführen.

Codeunit "SNCX XRechnung Sales Invoice"

OnBeforeSetLineFilter

Mit diesem Event kann die Standardfilterung der Belegzeilen vor der Verarbeitung angepasst werden. Standardmäßig werden Kommentarzeilen mit leerem Type-Feld ausgeschlossen. Wird ApplyLineTypeFilter auf false gesetzt, wird dieser Standardfilter nicht angewendet. Anschließend können eigene Filter auf SalesInvoiceLine gesetzt werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Sales Invoice", 'OnBeforeSetLineFilter', '', false, false)]
local procedure OnBeforeSetLineFilterInXRechnungSalesInvoice(
    var SalesInvoiceLine: Record "Sales Invoice Line";
    SalesInvoiceHeader: Record "Sales Invoice Header";
    var ApplyLineTypeFilter: Boolean
)
begin
    ApplyLineTypeFilter := false;
end;

OnBeforeInsertXRechnungHeader

Mit diesem Event kann die Puffertabelle vor der Erzeugung der XML-Datei angepasst werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Sales Invoice", 'OnBeforeInsertXRechnungHeader', '', false, false)]
local procedure OnBeforeInsertXRechnungHeaderInXRechnungSalesInvoice(
    var SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SalesInvoiceHeader: Record "Sales Invoice Header";
    var TempSNCXVATAmountLine: Record "SNCX VAT Amount Line" temporary;
    var TempSNCXXRechnungTaxExemption: Record "SNCX XRechnung Tax Exemption" temporary;
    var TempSNCXXRechnungLineRounding: Record "SNCX XRechnung Line" temporary;
    var SNCXXRechnungLine: Record "SNCX XRechnung Line";
)
begin
end;

OnBeforeInsertXRechnungLine

Mit diesem Event kann die Puffertabelle vor der Erzeugung der XML-Datei angepasst werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Sales Invoice", 'OnBeforeInsertXRechnungLine', '', false, false)]
local procedure OnBeforeInsertXRechnungLineInXRechnungSalesInvoice(
    var SNCXXRechnungLine: Record "SNCX XRechnung Line";
    ZeroAmount: Boolean;
    var InsertLine: Boolean;
    SalesInvoiceHeader: Record "Sales Invoice Header";
    SalesInvoiceLine: Record "Sales Invoice Line"
)
begin
end;

Codeunit "SNCX XRechnung Sales Cr. Memo"

OnBeforeSetLineFilter

Mit diesem Event kann die Standardfilterung der Belegzeilen vor der Verarbeitung angepasst werden. Standardmäßig werden Kommentarzeilen mit leerem Type-Feld ausgeschlossen. Wird ApplyLineTypeFilter auf false gesetzt, wird dieser Standardfilter nicht angewendet. Anschließend können eigene Filter auf SalesCrMemoLine gesetzt werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Sales Cr. Memo", 'OnBeforeSetLineFilter', '', false, false)]
local procedure OnBeforeSetLineFilterInXRechnungSalesCrMemo(
    var SalesCrMemoLine: Record "Sales Cr.Memo Line";
    SalesCrMemoHeader: Record "Sales Cr.Memo Header";
    var ApplyLineTypeFilter: Boolean
)
begin
    ApplyLineTypeFilter := false;
end;

OnBeforeInsertXRechnungHeader

Mit diesem Event kann die Puffertabelle vor der Erzeugung der XML-Datei angepasst werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Sales Cr. Memo", 'OnBeforeInsertXRechnungHeader', '', false, false)]
local procedure OnBeforeInsertXRechnungHeaderInXRechnungSalesCrMemo(
    var SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SalesCrMemoHeader: Record "Sales Cr.Memo Header";
    var TempSNCXVATAmountLine: Record "SNCX VAT Amount Line" temporary;
    var TempSNCXXRechnungTaxExemption: Record "SNCX XRechnung Tax Exemption" temporary;
    var TempSNCXXRechnungLineRounding: Record "SNCX XRechnung Line" temporary;
    var SNCXXRechnungLine: Record "SNCX XRechnung Line";
)
begin
end;

OnBeforeInsertXRechnungLine

Mit diesem Event kann die Puffertabelle vor der Erzeugung der XML-Datei angepasst werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Sales Cr. Memo", 'OnBeforeInsertXRechnungLine', '', false, false)]
local procedure OnBeforeInsertXRechnungLineInXRechnungSalesInvoice(
    var SNCXXRechnungLine: Record "SNCX XRechnung Line";
    ZeroAmount: Boolean;
    var InsertLine: Boolean;
    SalesCrMemoHeader: Record "Sales Cr.Memo Header";
    SalesCrMemoLine: Record "Sales Cr.Memo Line"
)
begin
end;

Codeunit "SNCX XRechnung Service Invoice"

OnBeforeSetLineFilter

Mit diesem Event kann die Standardfilterung der Belegzeilen vor der Verarbeitung angepasst werden. Standardmäßig werden Kommentarzeilen mit leerem Type-Feld ausgeschlossen. Wird ApplyLineTypeFilter auf false gesetzt, wird dieser Standardfilter nicht angewendet. Anschließend können eigene Filter auf ServiceInvoiceLine gesetzt werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Service Invoice", 'OnBeforeSetLineFilter', '', false, false)]
local procedure OnBeforeSetLineFilterInXRechnungServiceInvoice(
    var ServiceInvoiceLine: Record "Service Invoice Line";
    ServiceInvoiceHeader: Record "Service Invoice Header";
    var ApplyLineTypeFilter: Boolean
)
begin
    ApplyLineTypeFilter := false;
end;

OnBeforeInsertXRechnungHeader

Mit diesem Event kann die Puffertabelle vor der Erzeugung der XML-Datei angepasst werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Service Invoice", 'OnBeforeInsertXRechnungHeader', '', false, false)]
local procedure OnBeforeInsertXRechnungHeaderInXRechnungServiceInvoice(
    var SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    ServiceInvoiceHeader: Record "Service Invoice Header";
    var TempSNCXVATAmountLine: Record "SNCX VAT Amount Line" temporary;
    var TempSNCXXRechnungTaxExemption: Record "SNCX XRechnung Tax Exemption" temporary;
    var TempSNCXXRechnungLineRounding: Record "SNCX XRechnung Line" temporary;
    var SNCXXRechnungLine: Record "SNCX XRechnung Line";
)
begin
end;

OnBeforeInsertXRechnungLine

Mit diesem Event kann die Puffertabelle vor der Erzeugung der XML-Datei angepasst werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Service Invoice", 'OnBeforeInsertXRechnungLine', '', false, false)]
local procedure OnBeforeInsertXRechnungLineInXRechnungServiceInvoice(
    var SNCXXRechnungLine: Record "SNCX XRechnung Line";
    ZeroAmount: Boolean;
    var InsertLine: Boolean;
    ServiceInvoiceHeader: Record "Service Invoice Header";
    ServiceInvoiceLine: Record "Service Invoice Line"
)
begin
end;

Codeunit "SNCX XRechnung Serv. Cr. Memo"

OnBeforeSetLineFilter

Mit diesem Event kann die Standardfilterung der Belegzeilen vor der Verarbeitung angepasst werden. Standardmäßig werden Kommentarzeilen mit leerem Type-Feld ausgeschlossen. Wird ApplyLineTypeFilter auf false gesetzt, wird dieser Standardfilter nicht angewendet. Anschließend können eigene Filter auf ServiceCrMemoLine gesetzt werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Serv. Cr. Memo", 'OnBeforeSetLineFilter', '', false, false)]
local procedure OnBeforeSetLineFilterInXRechnungServiceCrMemo(
    var ServiceCrMemoLine: Record "Service Cr.Memo Line";
    ServiceCrMemoHeader: Record "Service Cr.Memo Header";
    var ApplyLineTypeFilter: Boolean
)
begin
    ApplyLineTypeFilter := false;
end;

OnBeforeInsertXRechnungHeader

Mit diesem Event kann die Puffertabelle vor der Erzeugung der XML-Datei angepasst werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Serv. Cr. Memo", 'OnBeforeInsertXRechnungHeader', '', false, false)]
local procedure OnBeforeInsertXRechnungHeaderInXRechnungServiceCrMemo(
    var SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    ServiceCrMemoHeader: Record "Service Cr.Memo Header";
    var TempSNCXVATAmountLine: Record "SNCX VAT Amount Line" temporary;
    var TempSNCXXRechnungTaxExemption: Record "SNCX XRechnung Tax Exemption" temporary;
    var TempSNCXXRechnungLineRounding: Record "SNCX XRechnung Line" temporary;
    var SNCXXRechnungLine: Record "SNCX XRechnung Line";
)
begin
end;

OnBeforeInsertXRechnungLine

Mit diesem Event kann die Puffertabelle vor der Erzeugung der XML-Datei angepasst werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Serv. Cr. Memo", 'OnBeforeInsertXRechnungLine', '', false, false)]
local procedure OnBeforeInsertXRechnungLineInXRechnungServiceCrMemo(
    var SNCXXRechnungLine: Record "SNCX XRechnung Line";
    ZeroAmount: Boolean;
    var InsertLine: Boolean;
    ServiceCrMemoHeader: Record "Service Cr.Memo Header";
    ServiceCrMemoLine: Record "Service Cr.Memo Line"
)
begin
end;

Codeunit "SNCX XRechnung Purch. Invoice"

OnBeforeSetLineFilter

Mit diesem Event kann die Standardfilterung der Belegzeilen vor der Verarbeitung angepasst werden. Standardmäßig werden Kommentarzeilen mit leerem Type-Feld ausgeschlossen. Wird ApplyLineTypeFilter auf false gesetzt, wird dieser Standardfilter nicht angewendet. Anschließend können eigene Filter auf PurchInvLine gesetzt werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Purch. Invoice", 'OnBeforeSetLineFilter', '', false, false)]
local procedure OnBeforeSetLineFilterInXRechnungPurchInvoice(
    var PurchInvLine: Record "Purch. Inv. Line";
    PurchInvHeader: Record "Purch. Inv. Header";
    var ApplyLineTypeFilter: Boolean
)
begin
    ApplyLineTypeFilter := false;
end;

Codeunit "SNCX XRechnung Purch. Cr. Memo"

OnBeforeSetLineFilter

Mit diesem Event kann die Standardfilterung der Belegzeilen vor der Verarbeitung angepasst werden. Standardmäßig werden Kommentarzeilen mit leerem Type-Feld ausgeschlossen. Wird ApplyLineTypeFilter auf false gesetzt, wird dieser Standardfilter nicht angewendet. Anschließend können eigene Filter auf PurchCrMemoLine gesetzt werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Purch. Cr. Memo", 'OnBeforeSetLineFilter', '', false, false)]
local procedure OnBeforeSetLineFilterInXRechnungPurchCrMemo(
    var PurchCrMemoLine: Record "Purch. Cr. Memo Line";
    PurchCrMemoHdr: Record "Purch. Cr. Memo Hdr.";
    var ApplyLineTypeFilter: Boolean
)
begin
    ApplyLineTypeFilter := false;
end;

OnBeforeInsertXRechnungHeader

Mit diesem Event kann die Puffertabelle vor der Erzeugung der XML-Datei angepasst werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Purch. Cr. Memo", 'OnBeforeInsertXRechnungHeader', '', false, false)]
local procedure OnBeforeInsertXRechnungHeaderInXRechnungServiceCrMemo(
    var SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    PurchCrMemoHdr: Record "Purch. Cr. Memo Hdr.";
    var TempSNCXVATAmountLine: Record "SNCX VAT Amount Line" temporary;
    var TempSNCXXRechnungTaxExemption: Record "SNCX XRechnung Tax Exemption" temporary;
    var TempSNCXXRechnungLineRounding: Record "SNCX XRechnung Line" temporary;
    var SNCXXRechnungLine: Record "SNCX XRechnung Line";
)
begin
end;

OnBeforeInsertXRechnungLine

Mit diesem Event kann die Puffertabelle vor der Erzeugung der XML-Datei angepasst werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Purch. Cr. Memo", 'OnBeforeInsertXRechnungLine', '', false, false)]
local procedure OnBeforeInsertXRechnungLineInXRechnungServiceCrMemo(
    var SNCXXRechnungLine: Record "SNCX XRechnung Line";
    ZeroAmount: Boolean;
    var InsertLine: Boolean;
    PurchCrMemoHdr: Record "Purch. Cr. Memo Hdr.";;
    PurchCrMemoLine: Record "Purch. Cr. Memo Line"
)
begin
end;

Codeunit "SNCX XRechnung Management"

OnBeforeSaveXMLDocument

Mit diesem Event erhalten Partner Zugriff auf das vollständige XML-Dokument unmittelbar vor dem Speichern.

Das Event ist als generelles XML-Erweiterungsevent gedacht. Damit können beliebige XML-Knoten hinzugefügt, geändert oder entfernt werden. Diese Änderungen erfolgen auf eigene Verantwortung des Partners. Insbesondere können dadurch fachliche Regeln, XRechnung-Validierungen oder Peppol-Konformität verletzt werden.

Konkreter Hinweis zum Knoten InvoiceeTradeParty als technisches Beispiel:

  • In der offiziellen ZUGFeRD-/Factur-X-Dokumentation ist ram:InvoiceeTradeParty vorhanden, siehe https://www.ferd-net.de/.
  • Der Knoten taucht dort jedoch in den Extended-Artefakten auf, z. B. in Schema\4_Factur-X_1.09_EXTENDED\... sowie in Beispielen unter Beispiele\4. EXTENDED\....
  • Unsere App unterstützt ZUGFeRD mit Profil XRechnung beziehungsweise EN16931, nicht ZUGFeRD Extended.
  • Ein Partner kann den Knoten über dieses Event technisch trotzdem einfügen, dies erfolgt jedoch vollständig auf eigene Verantwortung.

Empfohlene Einsatzfälle:

  • zusätzliche eigene XML-Knoten ergänzen
  • bestehende Knotenwerte an Partneranforderungen anpassen
  • strukturierte Inhalte nachgelagert umsortieren oder entfernen

Hinweise:

  • Das Event wird zentral für UBL und CII aufgerufen.
  • Der Zugriff erfolgt auf das vollständige XmlDocument.
  • Änderungen wirken sich direkt auf die gespeicherte XML-Datei aus.
  • Das folgende Beispiel zeigt bewusst eine CII-/ZUGFeRD-Manipulation. Für UBL/XRechnung gibt es keinen InvoiceeTradeParty-Knoten.
Warnung

Dieses Beispiel zeigt bewusst eine technische XML-Manipulation. Das Einfügen von InvoiceeTradeParty führt nicht zu einer XRechnung-konformen Datei und kann die Erkennung durch XRechnung-Validatoren verhindern.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Management", OnBeforeSaveXMLDocument, '', false, false)]
local procedure OnBeforeSaveXMLDocumentInXRechnungManagement(
    var XMLDoc: XmlDocument;
    var SNCXXRechnungHeader: Record "SNCX XRechnung Header"
)
var
    CIINamespaceTok: Label 'urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100', Locked = true;
    CrossIndustryInvoiceTok: Label 'CrossIndustryInvoice', Locked = true;
    ExchangedDocumentContextNode: XmlNode;
    ExchangedDocumentContextXPathTok: Label 'rsm:ExchangedDocumentContext', Locked = true;
    ExistingInvoiceeNode: XmlNode;
    FacturXExtendedGuidelineTok: Label 'urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended', Locked = true;
    FoundNodeAfterInvoicee: Boolean;
    GuidelineContextNode: XmlElement;
    GuidelineSpecifiedDocumentContextParameterTok: Label 'GuidelineSpecifiedDocumentContextParameter', Locked = true;
    GuidelineIDNode: XmlElement;
    IDTok: Label 'ID', Locked = true;
    IsNodeAfterInvoicee: Boolean;
    InvoiceeNameNode: XmlElement;
    InvoiceeTradePartyTok: Label 'InvoiceeTradeParty', Locked = true;
    InvoiceeTradePartyNode: XmlElement;
    InvoiceeTradePartyXPathTok: Label 'rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:InvoiceeTradeParty', Locked = true;
    LocalName: Text;
    NameTok: Label 'Name', Locked = true;
    NamespaceMgr: XmlNamespaceManager;
    RootElement: XmlElement;
    Node: XmlNode;
    NodeAfterInvoiceeBillingSpecifiedPeriodTok: Label 'BillingSpecifiedPeriod', Locked = true;
    NodeAfterInvoiceeApplicableTradeTaxTok: Label 'ApplicableTradeTax', Locked = true;
    NodeAfterInvoiceeInvoiceReferencedDocumentTok: Label 'InvoiceReferencedDocument', Locked = true;
    NodeAfterInvoiceePayeeTradePartyTok: Label 'PayeeTradeParty', Locked = true;
    NodeAfterInvoiceePayerTradePartyTok: Label 'PayerTradeParty', Locked = true;
    NodeAfterInvoiceeReceivableSpecifiedTradeAccountingAccountTok: Label 'ReceivableSpecifiedTradeAccountingAccount', Locked = true;
    NodeAfterInvoiceeSpecifiedAdvancePaymentTok: Label 'SpecifiedAdvancePayment', Locked = true;
    NodeAfterInvoiceeSpecifiedFinancialAdjustmentTok: Label 'SpecifiedFinancialAdjustment', Locked = true;
    NodeAfterInvoiceeSpecifiedLogisticsServiceChargeTok: Label 'SpecifiedLogisticsServiceCharge', Locked = true;
    NodeAfterInvoiceeSpecifiedTradeAllowanceChargeTok: Label 'SpecifiedTradeAllowanceCharge', Locked = true;
    NodeAfterInvoiceeSpecifiedTradePaymentTermsTok: Label 'SpecifiedTradePaymentTerms', Locked = true;
    NodeAfterInvoiceeSpecifiedTradeSettlementHeaderMonetarySummationTok: Label 'SpecifiedTradeSettlementHeaderMonetarySummation', Locked = true;
    NodeAfterInvoiceeSpecifiedTradeSettlementPaymentMeansTok: Label 'SpecifiedTradeSettlementPaymentMeans', Locked = true;
    NodeAfterInvoiceeTaxApplicableTradeCurrencyExchangeTok: Label 'TaxApplicableTradeCurrencyExchange', Locked = true;
    i: Integer;
    SettlementChildNodes: XmlNodeList;
    SettlementChildNodesXPathTok: Label 'node()', Locked = true;
    SettlementNode: XmlNode;
    RAMPrefixTok: Label 'ram', Locked = true;
    RAMNamespaceTok: Label 'urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100', Locked = true;
    RSMPrefixTok: Label 'rsm', Locked = true;
    SettlementXPathTok: Label 'rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement', Locked = true;
begin
    // Diese Anpassung gilt nur fuer ZUGFeRD/Factur-X XML-Ausgaben.
    if SNCXXRechnungHeader."Data Format" <> SNCXXRechnungHeader."Data Format"::ZUGFeRD then
        exit;

    // Schutzpruefungen: Abbruch, falls das Dokument nicht als erwartete CII-Wurzel gelesen werden kann.
    if not XMLDoc.GetRoot(RootElement) then
        exit;

    if RootElement.LocalName() <> CrossIndustryInvoiceTok then
        exit;

    NamespaceMgr.NameTable(XMLDoc.NameTable());
    NamespaceMgr.AddNamespace(RSMPrefixTok, CIINamespaceTok);
    NamespaceMgr.AddNamespace(RAMPrefixTok, RAMNamespaceTok);

    // Die EXTENDED-Guideline wird im Kontext erzwungen, damit gegen die EXTENDED-Regeln validiert wird.
    if RootElement.SelectSingleNode(ExchangedDocumentContextXPathTok, NamespaceMgr, ExchangedDocumentContextNode) then begin
        ExchangedDocumentContextNode.AsXmlElement().RemoveNodes();
        GuidelineContextNode := XmlElement.Create(GuidelineSpecifiedDocumentContextParameterTok, RAMNamespaceTok);
        GuidelineIDNode := XmlElement.Create(IDTok, RAMNamespaceTok, FacturXExtendedGuidelineTok);
        GuidelineContextNode.Add(GuidelineIDNode);
        ExchangedDocumentContextNode.AsXmlElement().Add(GuidelineContextNode);
    end;

    // Idempotentes Verhalten: Wenn der Knoten bereits vorhanden ist, wird nichts mehr geaendert.
    if RootElement.SelectSingleNode(InvoiceeTradePartyXPathTok, NamespaceMgr, ExistingInvoiceeNode) then
        exit;

    // Settlement ist der Elternknoten, in den InvoiceeTradeParty in XSD-konformer Reihenfolge eingefuegt werden muss.
    if not RootElement.SelectSingleNode(SettlementXPathTok, NamespaceMgr, SettlementNode) then
        exit;

    InvoiceeTradePartyNode := XmlElement.Create(
        InvoiceeTradePartyTok,
        RAMNamespaceTok
    );

    // Fachlicher Kern: Hier wird der sichtbare Name des abweichenden Rechnungsempfaengers gesetzt.
    InvoiceeNameNode := XmlElement.Create(
        NameTok,
        RAMNamespaceTok,
        'Alternative invoice recipient' // Hier muss ein individuelles Feld mit dem fachlich passenden Wert des Kunden eingetragen werden.
    );

    InvoiceeTradePartyNode.Add(InvoiceeNameNode);
    // Alle Kindknoten (Elemente + Text/Kommentare) lesen, damit beim Neuaufbau keine Nicht-Elementknoten verloren gehen.
    if not SettlementNode.SelectNodes(SettlementChildNodesXPathTok, NamespaceMgr, SettlementChildNodes) then
        exit;

    // Neuaufbau ist notwendig, da die AL-XML-API kein verlaessliches Insert-Before bei bestehenden Geschwisterknoten bietet.
    SettlementNode.AsXmlElement().RemoveNodes();
    for i := 1 to SettlementChildNodes.Count() do begin
        SettlementChildNodes.Get(i, Node);

        // Formatierung/Kommentare erhalten, in dem Nicht-Elementknoten unveraendert uebernommen werden.
        if not Node.IsXmlElement() then begin
            SettlementNode.AsXmlElement().Add(Node);
            continue;
        end;

        LocalName := Node.AsXmlElement().LocalName();
        // Vorhandenes InvoiceeTradeParty entfernen und durch die unten erzeugte, kontrollierte Version ersetzen.
        if LocalName = InvoiceeTradePartyTok then
            continue;

        // Ersten Knoten erkennen, der laut EXTENDED-XSD hinter InvoiceeTradeParty stehen muss.
        IsNodeAfterInvoicee :=
            (LocalName = NodeAfterInvoiceePayeeTradePartyTok) or
            (LocalName = NodeAfterInvoiceePayerTradePartyTok) or
            (LocalName = NodeAfterInvoiceeTaxApplicableTradeCurrencyExchangeTok) or
            (LocalName = NodeAfterInvoiceeSpecifiedTradeSettlementPaymentMeansTok) or
            (LocalName = NodeAfterInvoiceeApplicableTradeTaxTok) or
            (LocalName = NodeAfterInvoiceeBillingSpecifiedPeriodTok) or
            (LocalName = NodeAfterInvoiceeSpecifiedTradeAllowanceChargeTok) or
            (LocalName = NodeAfterInvoiceeSpecifiedLogisticsServiceChargeTok) or
            (LocalName = NodeAfterInvoiceeSpecifiedTradePaymentTermsTok) or
            (LocalName = NodeAfterInvoiceeSpecifiedTradeSettlementHeaderMonetarySummationTok) or
            (LocalName = NodeAfterInvoiceeSpecifiedFinancialAdjustmentTok) or
            (LocalName = NodeAfterInvoiceeInvoiceReferencedDocumentTok) or
            (LocalName = NodeAfterInvoiceeReceivableSpecifiedTradeAccountingAccountTok) or
            (LocalName = NodeAfterInvoiceeSpecifiedAdvancePaymentTok);

        // Invoicee genau einmal an der fruehestmoeglichen gueltigen Position einfuegen.
        if (not FoundNodeAfterInvoicee) and IsNodeAfterInvoicee then begin
            SettlementNode.AsXmlElement().Add(InvoiceeTradePartyNode);
            FoundNodeAfterInvoicee := true;
        end;

        SettlementNode.AsXmlElement().Add(Node);
    end;

    // Fallback: Falls kein passender Nachfolge-Knoten existiert, Invoicee am Ende anhaengen.
    if not FoundNodeAfterInvoicee then
        SettlementNode.AsXmlElement().Add(InvoiceeTradePartyNode);

    // Alle Änderungen werden in die finale XML-Datei geschrieben.
end;

OnBeforeAddAdditionalDocumentReferenceToXRechnungXMLFile

Mit diesem Event können zusätzliche rechnungsbegleitende Anhänge in die XML Datei geschrieben werden.

Als Beispiel dient eine gebuchte Verkaufsrechnung.

Wenn eine Verkaufsgutschrift verwendet werden soll, dann muss diese Belegart entsprechend hinzugefügt werden.

Soll ein Servicebeleg hinzugefügt werden, dann muss die Tabelle "SNCX XRechnung SrvAddSuppDoc" gefüllt werden und der Parameter AttachSuppDocService auf true gesetzt werden.

Soll ein Beleg für eine Einkaufsgutschrift im Self Billing Verfahren hinzugefügt werden, dann muss die Tabelle "SNCX Add. Supp. Doc. Purchase" gefüllt werden und der Parameter AttachSuppDocPurchase auf true gesetzt werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Management", 'OnBeforeAddAdditionalDocumentReferenceToXRechnungXMLFile', '', false, false)]
    local procedure OnBeforeAddAdditionalDocumentReferenceToXRechnungXMLFileInXRechnungManagement(
        var SNCXXRechnungHeader: Record "SNCX XRechnung Header";
        var XRechnungErrorType: Option " ","Zero Amount","XML Data Generation","Add Additional Document Failure","Add Embedded Report Failure";
        var FileName: Text;
        var Base64EncodedString: Text;
        var AttachReport: Boolean;
        var SNCXXRechnungAddSuppDoc: Record "SNCX XRechnung Add. Supp. Doc.";
        var AttachSuppDocSales: Boolean;
        var SNCXXRechnungSrvAddSuppDoc: Record "SNCX XRechnung SrvAddSuppDoc";
        var AttachSuppDocService: Boolean;
        var IsHandled: Boolean;
        var AttachSuppDocPurchase: Boolean
    )
    var
        SalesInvoiceHeader: Record "Sales Invoice Header";
        DocumentAttachment: Record "Document Attachment";
        OutStream: OutStream;
        NextID: Integer;
    begin
        // Test example for sales invoices: Copy file from document attachment to XRechnung additional supporting document.
        // Check if there is no error in the process.
        if XRechnungErrorType <> XRechnungErrorType::" " then
            exit;

        case SNCXXRechnungHeader."Document Type" of
            SNCXXRechnungHeader."Document Type"::"Sales Invoice":
                SalesInvoiceHeader.Get(SNCXXRechnungHeader."Document No.");
        end;

        DocumentAttachment.SetRange("Table ID", Database::"Sales Invoice Header");
        DocumentAttachment.SetRange("No.", SalesInvoiceHeader."No.");
        if not DocumentAttachment.IsEmpty() then begin
            // Get the next id for the supported sales document.
            SNCXXRechnungAddSuppDoc.SetRange("Table ID", Database::"Sales Invoice Header");
            SNCXXRechnungAddSuppDoc.SetRange("Document Type", SNCXXRechnungAddSuppDoc."Document Type"::Invoice);
            SNCXXRechnungAddSuppDoc.SetRange("No.", SNCXXRechnungHeader."Document No.");
            if not SNCXXRechnungAddSuppDoc.IsEmpty() then
                if SNCXXRechnungAddSuppDoc.FindLast() then
                    NextID := SNCXXRechnungAddSuppDoc.ID
                else
                    NextID := 1;

            if DocumentAttachment.FindSet() then
                repeat
                    // Get the next id.
                    NextID += 1;
                    // Insert the XRechnung attachment from the document attachment example or any other table.
                    SNCXXRechnungAddSuppDoc.Init();
                    SNCXXRechnungAddSuppDoc.Validate(ID, NextID);
                    SNCXXRechnungAddSuppDoc.Validate("Table ID", Database::"Sales Invoice Header");
                    case SNCXXRechnungHeader."Document Type" of
                        SNCXXRechnungHeader."Document Type"::"Sales Invoice":
                            SNCXXRechnungAddSuppDoc.Validate("Document Type", SNCXXRechnungAddSuppDoc."Document Type"::Invoice);
                    end;
                    SNCXXRechnungAddSuppDoc.Validate("No.", SalesInvoiceHeader."No.");
                    SNCXXRechnungAddSuppDoc.Validate("Attached Date", CurrentDateTime());
                    SNCXXRechnungAddSuppDoc.Validate("Attached By", UserSecurityId());
                    SNCXXRechnungAddSuppDoc.Validate("File Type", DocumentAttachment."File Type");
                    SNCXXRechnungAddSuppDoc.Validate("File Name", DocumentAttachment."File Name");
                    SNCXXRechnungAddSuppDoc.Validate("File Extension", DocumentAttachment."File Extension");
                    SNCXXRechnungAddSuppDoc.Content.CreateOutStream(OutStream);
                    DocumentAttachment."Document Reference ID".ExportStream(OutStream);
                    SNCXXRechnungAddSuppDoc.Validate(Description, 'Added from event.');
                    SNCXXRechnungAddSuppDoc.Insert();
                    // Set the boolean to export the attachment to the xml file.
                    AttachSuppDocSales := true;
                until DocumentAttachment.Next() = 0;
        end;
    end;

OnAfterInsertAndCommitXRechnungExportHeader

Mit diesem Event kann der in die Datenbank eingefügte XRechnungskopf abgerufen werden und z.B. die XML Datei aus dem Feld "XML File" revisionssicher an ein Dokumentenmanagementsystem übertragen werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Management", 'OnAfterInsertAndCommitXRechnungExportHeader', '', false, false)]
local procedure OnAfterInsertAndCommitXRechnungExportHeader(SNCXXRechnungHeader: Record "SNCX XRechnung Header")
begin
end;

OnBeforeGetSEPADebitMandate

Mit diesem Event kann ein alternatives Lastschriftmandat für den Debitor, z.B. aus einer anderen App, übergeben werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Management", 'OnBeforeGetSEPADebitMandate', '', false, false)]
local procedure OnBeforeGetSEPADebitMandateInXRechnungManagement(
    BillToCustomerNo: Code[20];
    DueDate: Date;
    PostingDate: Date;
    var MandateID: Code[35];
    var IsHandled: Boolean;
    var CustomerBankIBAN: Code[50] 
)
begin
end;

OnBeforeAddNoteToXRechnungXMLFile

Mit diesem Event kann die Notiz (BT-22) überschrieben werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Management", 'OnBeforeAddNoteToXRechnungXMLFile', '', false, false)]
local procedure OnBeforeAddNoteToXRechnungXMLFile(
    var NoteText: Text;
    var SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    var DoNotInsertNote: Boolean
)
begin
end;

OnBeforeAddLineNoteToXRechnungXMLFile

Mit diesem Event kann die Notiz (BT-127) der Zeilen überschrieben werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Management", 'OnBeforeAddLineNoteToXRechnungXMLFile', '', false, false)]
local procedure OnBeforeAddLineNoteToXRechnungXMLFile(
    var NoteText: Text;
    var SNCXXRechnungLine: Record "SNCX XRechnung Line";
    var DoNotInsertNote: Boolean
)
begin
end;

OnBeforeGetLinePriceInfo

Mit diesem Event kann eingestellt werden, dass die Menge pro Einheit (BT-149) zur Berechnung des Preises (BT-146) mit herangezogen wird. Diese Berechnung findet im Peppol Export des Business Central Standard Exports nicht statt. Der Parameter UseQtyPerUnitOfMeasure muss dafür auf true gesetzt werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Management", 'OnBeforeGetLinePriceInfo', '', false, false)]
local procedure OnBeforeGetLinePriceInfoInSNCXXRechnungManagement(
    var SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    var SNCXXRechnungLine: Record "SNCX XRechnung Line";
    var UseQtyPerUnitOfMeasure: Boolean
)
begin
end;

OnAfterGetLinePriceInfo

Mit diesem Event können die Werte InvoiceLinePriceAmount (BT-146), BaseQuantity (BT-149) und der Einheitencode der BaseQuantity UnitCodeBaseQty (BT-149-1) angepasst werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Management", 'OnAfterGetLinePriceInfo', '', false, false)]
local procedure OnAfterGetLinePriceInfoInSNCXXRechnungManagement(
    var SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    var SNCXXRechnungLine: Record "SNCX XRechnung Line";
    var InvoiceLinePriceAmount: Text;
    var BaseQuantity: Text;
    var UnitCodeBaseQty: Text
)
begin
end;

OnBeforeInsertTempSNCXVATAmountLine

Mit diesem Event kann die benötigte TempSNCXVATAmountLine angepasst werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Management", OnBeforeInsertTempSNCXVATAmountLine, '', false, false)]
local procedure OnBeforeInsertTempSNCXVATAmountLine(
    VATPostingSetup: Record "VAT Posting Setup";
    var SNCXXRechnungLine: Record "SNCX XRechnung Line" temporary;
    var TempSNCXVATAmountLine: Record "SNCX VAT Amount Line" temporary
)
begin
end;

OnBeforeModifyTempSNCXVATAmountLine

Mit diesem Event kann die benötigte TempSNCXVATAmountLine angepasst werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung Management", OnBeforeModifyTempSNCXVATAmountLine, '', false, false)]
local procedure OnBeforeModifyTempSNCXVATAmountLine(var TempSNCXVATAmountLine: Record "SNCX VAT Amount Line" temporary)
begin
end;

Codeunit "SNCX XRechnung E-Mail Mgt"

OnBeforeSendEMail

Mit diesem Event können Sie die gesamte Logik zum Senden einer E-Mail vollständig übersteuern. Durch den IsHandled Parameter wird die Funktion zum Prüfen der Daten und Senden einer E-Mail an den Empfänger beendet.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnBeforeSendEMail', '', false, false)]
local procedure OnBeforeSendEMail(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    FromPosting: Boolean;
    var IsHandled: Boolean
)
begin
end;

OnGetSenderNameAndEMailAddress

Mit diesem Event können Sie bestimmen, welcher Name und welche E-Mail Adresse für die Versendung von SIEVERS XRechnung E-Mail verwendet werden sollen. ACHTUNG: Dieses Event ist nur gültig bis einschließlich BC 19 und auch nur, wenn die E-Mail Einrichtung über die SMTP Einrichtung gesteuert wird. Im neuen E-Mail Modul kann der Absender ausschließlich über das Szenario festgelegt werden. Hier gibt es per Code keinen Zugriff auf die Absenderadresse im Interface.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnGetSenderNameAndEMailAddress', '', false, false)]
local procedure OnGetSenderNameAndEMailAddress(
    var SenderName: Text;
    var SenderAddress: Text;
    var IsHandled: Boolean;
    SNCXXRechnungHeader: Record "SNCX XRechnung Header"
)
begin
end;

OnAfterGetRecipients

Mit diesem Event können Sie die Empfänger der E-Mail überschreiben. Die Variable SNCXXRechnungCustomer ist obsolet. Es muss die Variable Customer verwendet werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterGetRecipients', '', false, false)]
local procedure OnAfterGetRecipients(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    Contact: Record Contact;
    var Recipients: Text;
    Customer: Record Customer
)
begin
end;

local procedure OnAfterGetRecipientsForPurchase(

Mit diesem Event können Sie die Empfänger der E-Mail überschreiben.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'local procedure OnAfterGetRecipientsForPurchase(
', '', false, false)]
local procedure OnAfterGetRecipientsForPurchase(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    Vendor: Record Vendor;
    Contact: Record Contact;
    var Recipients: Text
)
begin
end;

OnAfterCreateSubjectTextForEMail

Mit diesem Event können Sie den Betreff von SIEVERS XRechnung E-Mails anpassen.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterCreateSubjectTextForEMail', '', false, false)]
local procedure OnAfterCreateSubjectTextForEMail(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    var SubjectText: Text
)
begin
end;

OnBeforeCreateBodyText

Mit diesem Event können Sie eine eigene Logik für den E-Mail Inhalt implementieren. Mit dem IsHandled Parameter wird die Funktion nach dem Event beendet. Der BodyText Parameter beeinhaltet den Text, der später in der E-Mail angezeigt wird. Es kann festgelegt werden, ob der Inhalt HTML-formatiert ist.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnBeforeCreateBodyText', '', false, false)]
local procedure OnBeforeCreateBodyText(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    var BodyText: Text;
    var BodyIsHTMLFormatted: Boolean;
    var IsHandled: Boolean
)
begin
end;

OnAfterCreateBodyTextForEMail

Mit diesem Event können Sie den Standard Text für E-Mails anpassen, wenn kein Text für E-Mails über die XRechnung Einrichtung gepflegt wurde.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterCreateBodyTextForEMail', '', false, false)]
local procedure OnAfterCreateBodyTextForEMail(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    var BodyText: Text;
    var BodyIsHTMLFormatted: Boolean
)
begin
end;

OnBeforeGetBodyTextFromStandardText

Mit diesem Event kann die Ermittlung des E-Mail-Textes aus dem konfigurierten Standardtext überschrieben werden. Wird IsHandled auf true gesetzt, wird die Standardlogik übersprungen. Der eigene Text wird über BodyText übergeben und das Ergebnis über Result festgelegt.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnBeforeGetBodyTextFromStandardText', '', false, false)]
local procedure OnBeforeGetBodyTextFromStandardTextInXRechnungEMailMgt(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    var BodyText: Text;
    var IsHandled: Boolean;
    var Result: Boolean
)
begin
    IsHandled := true;
    BodyText := 'Eigener E-Mail-Text';
    Result := true;
end;

OnAfterGetBodyTextFromStandardText

Mit diesem Event kann der aus dem Standardtext ermittelte E-Mail-Text nachträglich angepasst werden. Das Event wird auch aufgerufen, wenn kein Standardtext gefunden wurde.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterGetBodyTextFromStandardText', '', false, false)]
local procedure OnAfterGetBodyTextFromStandardTextInXRechnungEMailMgt(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    var BodyText: Text;
    var Result: Boolean
)
begin
    BodyText += '<br>Zusätzlicher Text';
    Result := BodyText <> '';
end;

OnBeforeAddAdditionalSupportingDocumentsToSMTPMail

Mit diesem Event können Sie rechnungsbegleitende Anlagen an die E-Mail übertragen. Der XRechnung Standard Code wird dadurch nicht mehr ausgeführt. Beispielhaft werden die rechnungsbegleitenden Anlagen für Verkauf und Service gesucht und in die Name/Value Buffer des BC Standards übertragen, so dass sie von dort aus in die E-Mail übergeben werden können.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnBeforeAddAdditionalSupportingDocumentsToSMTPMail', '', false, false)]
local procedure OnBeforeAddAdditionalSupportingDocumentsToSMTPMail(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    var TempNameValueBufferAddSuppDocuments: Record "Name/Value Buffer" temporary;
    var IsHandled: Boolean
)
var
    SNCXXRechnungAddSuppDoc: Record "SNCX XRechnung Add. Supp. Doc.";
    SNCXXRechnungSrvAddSuppDoc: Record "SNCX XRechnung SrvAddSuppDoc";
    NextID: Integer;
begin
    case SNCXXRechnungHeader."Document Type" of
        SNCXXRechnungHeader."Document Type"::"Sales Invoice":
            begin
                SNCXXRechnungAddSuppDoc.SetRange("Table ID", Database::"Sales Invoice Header");
                SNCXXRechnungAddSuppDoc.SetRange("Document Type", SNCXXRechnungAddSuppDoc."Document Type"::Invoice);
                SNCXXRechnungAddSuppDoc.SetRange("No.", SNCXXRechnungHeader."Document No.");
                if SNCXXRechnungAddSuppDoc.FindSet() then
                    repeat
                        NextID += 1;
                        TempNameValueBufferAddSuppDocuments.Init();
                        TempNameValueBufferAddSuppDocuments.ID := NextID;
                        TempNameValueBufferAddSuppDocuments.Name := SNCXXRechnungAddSuppDoc."File Name" + '.' + SNCXXRechnungAddSuppDoc."File Extension";
                        SNCXXRechnungAddSuppDoc.CalcFields(Content);
                        TempNameValueBufferAddSuppDocuments."Value BLOB" := SNCXXRechnungAddSuppDoc.Content;
                        TempNameValueBufferAddSuppDocuments.Insert(false);
                        IsHandled := true;
                    until SNCXXRechnungAddSuppDoc.Next() = 0;
            end;
        SNCXXRechnungHeader."Document Type"::"Sales Cr. Memo":
            begin
                SNCXXRechnungAddSuppDoc.SetRange("Table ID", Database::"Sales Cr.Memo Header");
                SNCXXRechnungAddSuppDoc.SetRange("Document Type", SNCXXRechnungAddSuppDoc."Document Type"::"Credit Memo");
                SNCXXRechnungAddSuppDoc.SetRange("No.", SNCXXRechnungHeader."Document No.");
                if SNCXXRechnungAddSuppDoc.FindSet() then
                    repeat
                        NextID += 1;
                        TempNameValueBufferAddSuppDocuments.Init();
                        TempNameValueBufferAddSuppDocuments.ID := NextID;
                        TempNameValueBufferAddSuppDocuments.Name := SNCXXRechnungAddSuppDoc."File Name" + '.' + SNCXXRechnungAddSuppDoc."File Extension";
                        SNCXXRechnungAddSuppDoc.CalcFields(Content);
                        TempNameValueBufferAddSuppDocuments."Value BLOB" := SNCXXRechnungAddSuppDoc.Content;
                        TempNameValueBufferAddSuppDocuments.Insert(false);
                        IsHandled := true;
                    until SNCXXRechnungAddSuppDoc.Next() = 0;
            end;
        SNCXXRechnungHeader."Document Type"::"Service Invoice":
            begin
                SNCXXRechnungSrvAddSuppDoc.SetRange("Table ID", Database::"Service Invoice Header");
                SNCXXRechnungSrvAddSuppDoc.SetRange("Document Type", SNCXXRechnungSrvAddSuppDoc."Document Type"::Invoice);
                SNCXXRechnungSrvAddSuppDoc.SetRange("No.", SNCXXRechnungHeader."Document No.");
                if SNCXXRechnungSrvAddSuppDoc.FindSet() then
                    repeat
                        NextID += 1;
                        TempNameValueBufferAddSuppDocuments.Init();
                        TempNameValueBufferAddSuppDocuments.ID := NextID;
                        TempNameValueBufferAddSuppDocuments.Name := SNCXXRechnungSrvAddSuppDoc."File Name" + '.' + SNCXXRechnungSrvAddSuppDoc."File Extension";
                        SNCXXRechnungSrvAddSuppDoc.CalcFields(Content);
                        TempNameValueBufferAddSuppDocuments."Value BLOB" := SNCXXRechnungSrvAddSuppDoc.Content;
                        TempNameValueBufferAddSuppDocuments.Insert(false);
                        IsHandled := true;
                    until SNCXXRechnungSrvAddSuppDoc.Next() = 0;
            end;
        SNCXXRechnungHeader."Document Type"::"Service Cr. Memo":
            begin
                SNCXXRechnungSrvAddSuppDoc.SetRange("Table ID", Database::"Service Cr.Memo Header");
                SNCXXRechnungSrvAddSuppDoc.SetRange("Document Type", SNCXXRechnungSrvAddSuppDoc."Document Type"::"Credit Memo");
                SNCXXRechnungSrvAddSuppDoc.SetRange("No.", SNCXXRechnungHeader."Document No.");
                if SNCXXRechnungSrvAddSuppDoc.FindSet() then
                    repeat
                        NextID += 1;
                        TempNameValueBufferAddSuppDocuments.Init();
                        TempNameValueBufferAddSuppDocuments.ID := NextID;
                        TempNameValueBufferAddSuppDocuments.Name := SNCXXRechnungSrvAddSuppDoc."File Name" + '.' + SNCXXRechnungSrvAddSuppDoc."File Extension";
                        SNCXXRechnungSrvAddSuppDoc.CalcFields(Content);
                        TempNameValueBufferAddSuppDocuments."Value BLOB" := SNCXXRechnungSrvAddSuppDoc.Content;
                        TempNameValueBufferAddSuppDocuments.Insert(false);
                        IsHandled := true;
                    until SNCXXRechnungSrvAddSuppDoc.Next() = 0;
            end;
    end;
end;

OnBeforeAddReportToSMTPMail

Mit diesen Events können Sie einen anderen Bericht als PDF anhängen, als den, der im Debitor oder Kreditor für XRechnung hinterlegt ist. In das Blob Feld der temporären TempBlob Tabelle (BC 14) oder die Codeunit (BC 15 bis BC 19) oder direkt in das Email Item (ab BC 18) wird der Inhalt der PDF geschrieben. Der Name der PDF muss, genau wie der IsHandled Parameter (true) übergeben werden, um den XRechnungs-Code nicht auszuführen.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnBeforeAddReportToSMTPMail', '', false, false)]
local procedure OnBeforeAddReportToSMTPMail(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    var TempBlob: Record TempBlob temporary; oder var TempBlob: Codeunit "Temp Blob"; oder var TempEmailItem: Record "Email Item" temporary; -> je nach Versionsstand beachten!
    var PDFFilename: Text;
    var IsHandled: Boolean;
    Customer: Record Customer
)
begin
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnBeforeAddReportToSMTPMailForPurchase', '', false, false)]
local procedure OnBeforeAddReportToSMTPMailForPurchase(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    Vendor: Record Vendor;
    var TempBlob: Record TempBlob temporary; oder var TempBlob: Codeunit "Temp Blob"; oder var TempEmailItem: Record "Email Item" temporary; -> je nach Versionsstand beachten!
    var PDFFilename: Text;
    var IsHandled: Boolean
)
begin
end;

Beispiel für BC 14 anhand einer Verkaufsrechnung:

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnBeforeAddReportToSMTPMail', '', false, false)]
local procedure OnBeforeAddReportToSMTPMail(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    var TempBlob: Record TempBlob temporary;
    var PDFFilename: Text;
    var IsHandled: Boolean;
    Customer: Record Customer
)
var
    SalesInvoiceHeader: Record "Sales Invoice Header";
    SNCXXRechnungManagement: Codeunit "SNCX XRechnung Management";
    RecordRef: RecordRef;
    ReportId: Integer;
    PDFInStream: InStream;
    PDFOutStream: OutStream;
begin
    case Customer."XRechnung E-Mail Option" of
        Customer."XRechnung E-Mail Option"::"Send xml and pdf file":
            case SNCXXRechnungHeader."Document Type" of
                SNCXXRechnungHeader."Document Type"::"Sales Invoice":
                    if SalesInvoiceHeader.Get(SNCXXRechnungHeader."Document No.") then begin
                        RecordRef.GetTable(SalesInvoiceHeader);
                        RecordRef.SetRecFilter();
                        ReportId := SNCXXRechnungCustomer."Report for Sales Invoice";
                        if ReportId <> 0 then begin
                            TempBlob.Blob.CreateOutStream(PDFOutStream);
                            SNCXXRechnungManagement.CreateOutStreamFromReport(
                                ReportId,
                                RecordRef,
                                PDFOutStream
                            );
                            TempBlob.Blob.CreateInStream(PDFInStream);
                            PDFFilename := SNCXXRechnungManagement.GetFilename(
                                SNCXXRechnungHeader."Document Type",
                                SalesInvoiceHeader."No."
                            );
                            IsHandled := true;
                        end;
                    end;
            end;
    end;
end;

OnAfterGetReportIDFromCustomerForXRechnungPostedSalesInvoice

Mit diesem Event können Sie die Berichts-ID und die Request-Page-Parameter des Berichts ändern. Übergeben Sie in RequestPageParameters das XML aus Report.RunRequestPage. Es wird beim Erzeugen des PDF-Anhangs an Report.SaveAs übergeben. Die Variable SNCXXRechnungCustomer ist obsolet. Es muss die Variable Customer verwendet werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterGetReportIDFromCustomerForXRechnungPostedSalesInvoice', '', false, false)]
local procedure OnAfterGetReportIDFromCustomerForXRechnungPostedSalesInvoiceInXRechnungEMailMgt(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SalesInvoiceHeader: Record "Sales Invoice Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    var ReportId: Integer;
    Customer: Record Customer;
    var RequestPageParameters: Text
)
begin
end;

OnAfterGetReportIDFromCustomerForXRechnungPostedSalesCreditMemo

Mit diesem Event können Sie die Berichts-ID und die Request-Page-Parameter des Berichts ändern. Übergeben Sie in RequestPageParameters das XML aus Report.RunRequestPage. Es wird beim Erzeugen des PDF-Anhangs an Report.SaveAs übergeben. Die Variable SNCXXRechnungCustomer ist obsolet. Es muss die Variable Customer verwendet werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterGetReportIDFromCustomerForXRechnungPostedSalesCreditMemo', '', false, false)]
local procedure OnAfterGetReportIDFromCustomerForXRechnungPostedSalesCreditMemoInXRechnungEMailMgt(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SalesCrMemoHeader: Record "Sales Cr.Memo Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    var ReportId: Integer;
    Customer: Record Customer;
    var RequestPageParameters: Text
)
begin
end;

OnAfterGetReportIDFromCustomerForXRechnungPostedServiceInvoice

Mit diesem Event können Sie die Berichts-ID und die Request-Page-Parameter des Berichts ändern. Übergeben Sie in RequestPageParameters das XML aus Report.RunRequestPage. Es wird beim Erzeugen des PDF-Anhangs an Report.SaveAs übergeben. Die Variable SNCXXRechnungCustomer ist obsolet. Es muss die Variable Customer verwendet werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterGetReportIDFromCustomerForXRechnungPostedServiceInvoice', '', false, false)]
local procedure OnAfterGetReportIDFromCustomerForXRechnungPostedServiceInvoiceInXRechnungEMailMgt(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    ServiceInvoiceHeader: Record "Service Invoice Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    var ReportId: Integer;
    Customer: Record Customer;
    var RequestPageParameters: Text
)
begin
end;

OnAfterGetReportIDFromCustomerForXRechnungPostedServiceCreditMemo

Mit diesem Event können Sie die Berichts-ID und die Request-Page-Parameter des Berichts ändern. Übergeben Sie in RequestPageParameters das XML aus Report.RunRequestPage. Es wird beim Erzeugen des PDF-Anhangs an Report.SaveAs übergeben. Die Variable SNCXXRechnungCustomer ist obsolet. Es muss die Variable Customer verwendet werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterGetReportIDFromCustomerForXRechnungPostedServiceCreditMemo', '', false, false)]
local procedure OnAfterGetReportIDFromCustomerForXRechnungPostedServiceCreditMemoInXRechnungEMailMgt(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    ServiceCrMemoHeader: Record "Service Cr.Memo Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    var ReportId: Integer;
    Customer: Record Customer;
    var RequestPageParameters: Text
)
begin
end;

OnAfterGetReportIDFromVendorForXRechnungPostedPurchaseCreditMemo

Mit diesem Event können Sie die Berichts-ID und die Request-Page-Parameter für eine gebuchte Einkaufsgutschrift ändern. Übergeben Sie in RequestPageParameters das XML aus Report.RunRequestPage. Es wird beim Erzeugen des PDF-Anhangs an Report.SaveAs übergeben.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterGetReportIDFromVendorForXRechnungPostedPurchaseCreditMemo', '', false, false)]
local procedure OnAfterGetReportIDFromVendorForXRechnungPostedPurchaseCreditMemoInXRechnungEMailMgt(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    PurchCrMemoHdr: Record "Purch. Cr. Memo Hdr.";
    Vendor: Record Vendor;
    var ReportId: Integer;
    var RequestPageParameters: Text
)
begin
end;

OnAfterGetReportIDFromVendorForXRechnungPostedPurchaseInvoice

Mit diesem Event können Sie die Berichts-ID und die Request-Page-Parameter für eine gebuchte Einkaufsrechnung ändern. Übergeben Sie in RequestPageParameters das XML aus Report.RunRequestPage. Es wird beim Erzeugen des PDF-Anhangs an Report.SaveAs übergeben.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterGetReportIDFromVendorForXRechnungPostedPurchaseInvoice', '', false, false)]
local procedure OnAfterGetReportIDFromVendorForXRechnungPostedPurchaseInvoiceInXRechnungEMailMgt(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    PurchInvHeader: Record "Purch. Inv. Header";
    Vendor: Record Vendor;
    var ReportId: Integer;
    var RequestPageParameters: Text
)
begin
end;

OnAfterCreatePDFStreamFromReportForPostedSalesInvoice

Mit diesem Event wird der erzeugte Bericht der Verkaufsrechnung anhand des Reports der Debitoreinstellung übergeben und kann durch den Partner manipuliert werden, falls benötigt. Die Variable SNCXXRechnungCustomer ist obsolet. Es muss die Variable Customer verwendet werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterCreatePDFStreamFromReportForPostedSalesInvoice', '', false, false)]
local procedure OnAfterCreatePDFStreamFromReportForPostedSalesInvoiceInXRechnungEMailMgt(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    SalesInvoiceHeader: Record "Sales Invoice Header";
    ReportId: Integer;
    var TempBlob: Record TempBlob temporary;
    var PDFFilename: Text;
    Customer: Record Customer
)
begin
end;

OnAfterCreatePDFStreamFromReportForPostedSalesCreditMemo

Mit diesem Event wird der erzeugte Bericht der Verkaufsgutschrift anhand des Reports der Debitoreinstellung übergeben und kann durch den Partner manipuliert werden, falls benötigt. Die Variable SNCXXRechnungCustomer ist obsolet. Es muss die Variable Customer verwendet werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterCreatePDFStreamFromReportForPostedSalesCreditMemo', '', false, false)]
local procedure OnAfterCreatePDFStreamFromReportForPostedSalesCreditMemoInXRechnungEMailMgt(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    SalesCrMemoHeader: Record "Sales Cr.Memo Header";
    ReportId: Integer;
    var TempBlob: Record TempBlob temporary;
    var PDFFilename: Text;
    Customer: Record Customer
)
begin
end;

OnAfterCreatePDFStreamFromReportForPostedServiceInvoice

Mit diesem Event wird der erzeugte Bericht der Servicerechnung anhand des Reports der Debitoreinstellung übergeben und kann durch den Partner manipuliert werden, falls benötigt. Die Variable SNCXXRechnungCustomer ist obsolet. Es muss die Variable Customer verwendet werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterCreatePDFStreamFromReportForPostedServiceInvoice', '', false, false)]
local procedure OnAfterCreatePDFStreamFromReportForPostedServiceInvoiceInXRechnungEMailMgt(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    ServiceInvoiceHeader: Record "Service Invoice Header";
    ReportId: Integer;
    var TempBlob: Record TempBlob temporary;
    var PDFFilename: Text;
    Customer: Record Customer
)
begin
end;

OnAfterCreatePDFStreamFromReportForPostedServiceCreditMemo

Mit diesem Event wird der erzeugte Bericht der Servicegutschrift anhand des Reports der Debitoreinstellung übergeben und kann durch den Partner manipuliert werden, falls benötigt. Die Variable SNCXXRechnungCustomer ist obsolet. Es muss die Variable Customer verwendet werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterCreatePDFStreamFromReportForPostedServiceCreditMemo', '', false, false)]
local procedure OnAfterCreatePDFStreamFromReportForPostedServiceCreditMemoInXRechnungEMailMgt(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    ServiceCrMemoHeader: Record "Service Cr.Memo Header";
    ReportId: Integer;
    var TempBlob: Record TempBlob temporary;
    var PDFFilename: Text;
    Customer: Record Customer
)
begin
end;

OnAfterCreatePDFStreamFromReportForPostedPurchaseCreditMemo

Mit diesem Event wird der erzeugte Bericht der Einkaufsgutschrift anhand des Reports der Kreditoreinstellung übergeben und kann durch den Partner manipuliert werden, falls benötigt.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX XRechnung E-Mail Mgt", 'OnAfterCreatePDFStreamFromReportForPostedPurchaseCreditMemo', '', false, false)]
local procedure OnAfterCreatePDFStreamFromReportForPostedPurchaseCreditMemoInXRechnungEMailMgt(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    Vendor: Record Vendor;
    PurchCrMemoHdr: Record "Purch. Cr. Memo Hdr.";
    ReportId: Integer;
    var TempBlob: Record TempBlob temporary;
    var PDFFilename: Text
)
begin
end;

Codeunit "SNCX ZUGFeRD Management"

OnBeforeCreatePDFStreamFromReportForZUGFeRD

Mit diesem Event können Sie die Request-Page-Parameter des für ZUGFeRD verwendeten Berichts festlegen. Übergeben Sie in RequestPageParameters das XML aus Report.RunRequestPage. Die App rendert den konfigurierten Bericht mit diesen Parametern und bettet anschließend das ZUGFeRD-XML in das PDF ein.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX ZUGFeRD Management", 'OnBeforeCreatePDFStreamFromReportForZUGFeRD', '', false, false)]
local procedure OnBeforeCreatePDFStreamFromReportForZUGFeRD(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    ReportId: Integer;
    var RequestPageParameters: Text
)
begin
end;

OnBeforeGetReportForZUGFeRD und OnBeforeGetReportForZUGFeRDForPurchase

Diese Events sind identisch zu dem Event OnBeforeAddReportToSMTPMail der Codeunit "SNCX XRechnung E-Mail Mgt" zu verwenden. Ein Beispiel, wie ein Bericht ermittelt und übergeben wird ist dort für BC 14 hinterlegt.

OnAfterCreatePDFStreamFromReportForPostedSalesInvoice

Mit diesem Event wird der erzeugte Bericht der Verkaufsrechnung anhand des Reports der Debitoreinstellung übergeben und kann durch den Partner manipuliert werden, falls benötigt.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX ZUGFeRD Management", 'OnAfterCreatePDFStreamFromReportForPostedSalesInvoice', '', false, false)]
local procedure OnAfterCreatePDFStreamFromReportForPostedSalesInvoiceInSNCXZUGFeRDManagement(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    SalesInvoiceHeader: Record "Sales Invoice Header";
    ReportId: Integer;
    var TempBlob: Record TempBlob temporary;
    var PDFFilename: Text[250]
)
begin
end;

OnAfterCreatePDFStreamFromReportForPostedSalesCreditMemo

Mit diesem Event wird der erzeugte Bericht der Verkaufsgutschrift anhand des Reports der Debitoreinstellung übergeben und kann durch den Partner manipuliert werden, falls benötigt.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX ZUGFeRD Management", 'OnAfterCreatePDFStreamFromReportForPostedSalesCreditMemo', '', false, false)]
local procedure OnAfterCreatePDFStreamFromReportForPostedSalesCreditMemoInSNCXZUGFeRDManagement(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    SalesCrMemoHeader: Record "Sales Cr.Memo Header";
    ReportId: Integer;
    var TempBlob: Record TempBlob temporary;
    var PDFFilename: Text[250]
)
begin
end;

OnAfterCreatePDFStreamFromReportForPostedServiceInvoice

Mit diesem Event wird der erzeugte Bericht der Servicerechnung anhand des Reports der Debitoreinstellung übergeben und kann durch den Partner manipuliert werden, falls benötigt.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX ZUGFeRD Management", 'OnAfterCreatePDFStreamFromReportForPostedServiceInvoice', '', false, false)]
local procedure OnAfterCreatePDFStreamFromReportForPostedServiceInvoiceInSNCXZUGFeRDManagement(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    ServiceInvoiceHeader: Record "Service Invoice Header";
    ReportId: Integer;
    var TempBlob: Record TempBlob temporary;
    var PDFFilename: Text[250]
)
begin
end;

OnAfterCreatePDFStreamFromReportForPostedServiceCreditMemo

Mit diesem Event wird der erzeugte Bericht der Servicegutschrift anhand des Reports der Debitoreinstellung übergeben und kann durch den Partner manipuliert werden, falls benötigt.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"SNCX ZUGFeRD Management", 'OnAfterCreatePDFStreamFromReportForPostedServiceCreditMemo', '', false, false)]
local procedure OnAfterCreatePDFStreamFromReportForPostedServiceCreditMemoInSNCXZUGFeRDManagement(
    SNCXXRechnungHeader: Record "SNCX XRechnung Header";
    SNCXXRechnungCustomer: Record "SNCX XRechnung Customer";
    ServiceCrMemoHeader: Record "Service Cr.Memo Header";
    ReportId: Integer;
    var TempBlob: Record TempBlob temporary;
    var PDFFilename: Text[250]
)
begin
end;

OnAfterModifyXRechnungHeaderAfterAddingZUGFeRDPDFFile

Mit diesem Event kann die ZUGFeRD Datei extern abgerufen werden, nach dem sie an die Puffertabelle angehangen wurde. Folgende beiden Felder wurden zuvor gefüllt:

  • SNCXXRechnungHeader."ZUGFeRD PDF File"
  • SNCXXRechnungHeader."ZUGFeRD PDF Filename"
[IntegrationEvent(false, false)]
local procedure OnAfterModifyXRechnungHeaderAfterAddingZUGFeRDPDFFile(SNCXXRechnungHeader: Record "SNCX XRechnung Header")
begin
end;