Zum Inhalt

Den B2Brouter-Kontakt-Page-Part einbinden

Mit dem Page Part B2Brouter verknüpfen Sie einen Business-Central-Debitor auf einer eigenen Debitorenseite mit einem Kontakt Ihres B2Brouter-Kontos. Wie auf der Standard-Debitorenkarte stehen Kontaktsuche, Erstellung und Aktualisierung, Peppol-Empfängerprüfung sowie Transport- und Dokumenttypeinstellungen zur Verfügung.

Voraussetzungen und Einsatzbereich

  • Installieren und lizenzieren Sie Document Dispatch und richten Sie den Benutzerzugriff ein. Referenzieren Sie Document Dispatch und CORE by Simova in der app.json Ihrer Erweiterung. Verwenden Sie IDs, Herausgeber und kompatible Versionen der installierten Apps und laden Sie deren Symbole herunter.
  • Hinterlegen Sie Konto-ID und API-Schlüssel in der B2Brouter-Moduleinrichtung. Der Testmodus verwendet Staging, andernfalls Produktion. Die Sichtbarkeitsprüfung im Beispiel prüft nur eine vorhandene Konto-ID und bestätigt keine gültige Verbindung zur ausgewählten Umgebung.
  • Benutzer benötigen Zugriff auf die Host-Seite und Customer sowie passende Document-Dispatch-Berechtigungen. SIM_EDS USER und SIM_EDS ADMIN enthalten den Page Part, seine Kontakttabelle und die Verwaltungscodeunit. Sichtbarkeit ersetzt keine Berechtigungsvergabe.
  • Verwenden Sie einen gespeicherten Debitor mit gefüllter Nummer. Passen Sie Objekt-ID 50100, Namen und Beschriftungen an Ihre Lösung an.

Eigene Seiten auf Basis von Customer

Der vollständige Ablauf setzt derzeit SourceTable = Customer voraus. Zwar nimmt SetContext eine Tabellen-ID entgegen, Kontakt erstellen, Kontakt aktualisieren und Änderungen der Routing-Einstellungen laden intern jedoch einen Customer anhand der übergebenen Nummer. Die Aktualisierungsbestätigung ermittelt die Verknüpfung ebenfalls mit Database::Customer. Die ID einer beliebigen eigenen Tabelle macht diese Aktionen nicht für diese Tabelle nutzbar. Ordnen Sie eine andere Entität zunächst einem tatsächlichen Debitor zu und übergeben Sie dessen Nummer, Tabellen-ID und Daten.

Objekte und gespeicherte Daten

Eingebunden wird Page 5492741, SIM_EDS B2Brouter Contact LP. Trotz des Suffixes LP ist ihr PageType CardPart. Sie verwendet Tabelle 5492683, SIM_EDS B2Brouter Contact, mit SourceTableTemporary = true.

Der Page Part arbeitet mit einer temporären Anzeigezeile und liest die dauerhafte Konfiguration über den zusammengesetzten Schlüssel No. + Table Id. Seiten mit demselben Debitorenschlüssel verwenden dieselbe Verknüpfung. Gespeichert werden Kontakt-ID, Verzeichniseinstellungen und Prüfergebnisse, Transport-/Dokumenttyp und ausstehende Routing-Änderungen. Der Schlüssel enthält weder Konto noch Umgebung: Ein Wechsel des Testmodus wählt nicht automatisch eine getrennte lokale Zuordnung. Prüfen Sie den verknüpften Kontakt im ausgewählten Konto.

Den Page Part mit SetContext befüllen

SubPageLink ordnet den Page Part dem Debitorenschlüssel zu. Zusätzlich muss die öffentliche Prozedur SetContext die temporäre Anzeigezeile und die Suchvariablen befüllen. SubPageLink allein genügt nicht.

procedure SetContext(ParamNoCode: Code[50]; ParamTableIdInteger: Integer;
    ParamNameText: Text; ParamCountryCodeText: Text;
    ParamSchemeCodeText: Text; ParamIdentifierText: Text; ParamEmailText: Text)
Parameter Typ Wert und Bedeutung
ParamNoCode Code[50] Rec."No.": Debitorennummer und erster Teil des gespeicherten Schlüssels.
ParamTableIdInteger Integer Database::Customer: zweiter Schlüsselteil; muss zum SubPageLink passen.
ParamNameText Text Rec.Name: Suchtext für die Kontaktsuche.
ParamCountryCodeText Text Rec."Country/Region Code": Land für die Verzeichnissuche.
ParamSchemeCodeText Text '' für die Suche mit USt-IdNr. und Land oder ein gültiger B2Brouter-Scheme-Code. Der Page Part akzeptiert bis zu 100 Zeichen.
ParamIdentifierText Text Rec."VAT Registration No.": Standardkennung für die Verzeichnissuche.
ParamEmailText Text Rec."E-Mail": wird für die Auswahl verfügbarer Transportarten berücksichtigt.

Jeder Aufruf baut die temporäre Zeile neu auf und lädt eine vorhandene Zuordnung. Ein gespeicherter Directory Scheme Code überschreibt das übergebene Scheme. Eine gefüllte gespeicherte Lookup Identifier wird bei ausgewähltem Scheme verwendet, andernfalls die übergebene Standardkennung. Scheme-Auswahl und -Validierung übernimmt der Page Part. Ein leer übergebenes Scheme setzt eine gespeicherte Auswahl nicht zurück.

Öffnen oder Wechseln eines Debitors erstellt noch keine dauerhafte Zuordnung. Diese kann beim Speichern von Verzeichniseinstellungen, Verknüpfen/Erstellen eines Kontakts oder Prüfen des Verzeichnisses entstehen. Bei verknüpften Kontakten kann SetContext Routing-Daten von B2Brouter abrufen. Der geladene Kontext wird zwischengespeichert, damit nicht jede Feldvalidierung einen erneuten Abruf auslöst. Der Aufruf ist daher nicht ausschließlich eine lokale Anzeigeoperation.

Vollständiges Beispiel: eigene Debitorenkarte

Diese eigenständige Seite verwendet Customer und bindet den Page Part in eine Gruppe B2Brouter ein. Sie aktualisiert den Kontext beim Datensatzwechsel und nach Änderungen. Die zehn übertragenen Felder fragen eine externe Aktualisierung nur bei tatsächlicher Wertänderung an.

page 50100 "My B2Brouter Customer Card"
{
    PageType = Card;
    SourceTable = Customer;
    ApplicationArea = All;
    Caption = 'My Customer Card';

    layout
    {
        area(Content)
        {
            group(General)
            {
                Caption = 'General';
                field(CustomerNo; Rec."No.")
                {
                    ApplicationArea = All;
                }
                field(Name; Rec.Name)
                {
                    ApplicationArea = All;
                    trigger OnValidate()
                    begin
                        HandleCustomerChange(Rec.Name <> xRec.Name);
                    end;
                }
                field(Address; Rec."Address")
                {
                    ApplicationArea = All;
                    trigger OnValidate()
                    begin
                        HandleCustomerChange(Rec."Address" <> xRec."Address");
                    end;
                }
                field(Address2; Rec."Address 2")
                {
                    ApplicationArea = All;
                    trigger OnValidate()
                    begin
                        HandleCustomerChange(Rec."Address 2" <> xRec."Address 2");
                    end;
                }
                field(PostCode; Rec."Post Code")
                {
                    ApplicationArea = All;
                    trigger OnValidate()
                    begin
                        HandleCustomerChange(Rec."Post Code" <> xRec."Post Code");
                    end;
                }
                field(City; Rec."City")
                {
                    ApplicationArea = All;
                    trigger OnValidate()
                    begin
                        HandleCustomerChange(Rec."City" <> xRec."City");
                    end;
                }
                field(County; Rec."County")
                {
                    ApplicationArea = All;
                    trigger OnValidate()
                    begin
                        HandleCustomerChange(Rec."County" <> xRec."County");
                    end;
                }
                field(CountryCode; Rec."Country/Region Code")
                {
                    ApplicationArea = All;
                    trigger OnValidate()
                    begin
                        HandleCustomerChange(Rec."Country/Region Code" <> xRec."Country/Region Code");
                    end;
                }
                field(VATRegistrationNo; Rec."VAT Registration No.")
                {
                    ApplicationArea = All;
                    trigger OnValidate()
                    begin
                        HandleCustomerChange(Rec."VAT Registration No." <> xRec."VAT Registration No.");
                    end;
                }
                field(Email; Rec."E-Mail")
                {
                    ApplicationArea = All;
                    trigger OnValidate()
                    begin
                        HandleCustomerChange(Rec."E-Mail" <> xRec."E-Mail");
                    end;
                }
                field(PhoneNo; Rec."Phone No.")
                {
                    ApplicationArea = All;
                    trigger OnValidate()
                    begin
                        HandleCustomerChange(Rec."Phone No." <> xRec."Phone No.");
                    end;
                }
            }
            group(B2Brouter)
            {
                Caption = 'B2Brouter';
                Visible = B2BrouterVisible;
                part(B2BrouterContact; "SIM_EDS B2Brouter Contact LP")
                {
                    ApplicationArea = All;
                    SubPageLink = "No." = field("No."),
                                  "Table Id" = const(Database::Customer);
                }
            }
        }
    }

    trigger OnOpenPage()
    var
        EDSSetup: Record "SIM_EDS Setup";
        COREManagement: Codeunit "SIM_CORE Mgt";
    begin
        if not COREManagement.CheckPermissions(
            UserSecurityId(), 'SIM_EDS USER | SIM_EDS ADMIN | SUPER')
        then
            exit;
        if not EDSSetup.Get() then
            exit;
        B2BrouterVisible := (EDSSetup."B2Brouter Account Id" <> '') or
            (EDSSetup."B2Brouter Account Id Staging" <> '');
    end;

    trigger OnAfterGetCurrRecord()
    begin
        UpdateB2BrouterContext();
    end;

    trigger OnModifyRecord(): Boolean
    begin
        UpdateB2BrouterContext();
        exit(true);
    end;

    local procedure UpdateB2BrouterContext()
    begin
        if not B2BrouterVisible then
            exit;
        CurrPage.B2BrouterContact.Page.SetContext(
            Rec."No.", Database::Customer, Rec.Name,
            Rec."Country/Region Code", '',
            Rec."VAT Registration No.", Rec."E-Mail");
    end;

    local procedure HandleCustomerChange(Changed: Boolean)
    begin
        UpdateB2BrouterContext();
        if B2BrouterVisible and Changed then
            CurrPage.B2BrouterContact.Page.ConfirmCustomerContactUpdate(Rec);
    end;

    var
        B2BrouterVisible: Boolean;
}

Das Beispiel in eine bestehende Seite übernehmen

  • Integrieren Sie Gruppe, Variablen, Prozeduren und Trigger in Ihre eigene Customer-Seite. Verwenden Sie bei einer Page Extension addlast(Content) oder einen passenden addafter(...)-Anker für die Gruppe. Ergänzen Sie Feldvalidierungen über modify(...) und OnAfterValidate mit HandleCustomerChange(Rec.<Feld> <> xRec.<Feld>).
  • CurrPage.B2BrouterContact.Page... bezieht sich auf den Steuerelementnamen in part(B2BrouterContact; ...), nicht auf den Objektnamen der eingebundenen Page.
  • Rufen Sie SetContext in OnAfterGetCurrRecord auf, damit beim Navigieren die richtige Verknüpfung erscheint. Aktualisieren Sie den Kontext nach Änderungen an Name, Land, USt-IdNr. oder E-Mail und nach dem Speichern. Erhalten Sie vorhandene Validierungs- und Speicherlogik.
  • Für das Verhalten der Standardkarte berücksichtigen Sie Name, Adresse, Adresse 2, PLZ, Ort, Bundesregion, Länder-/Regionscode, USt-IdNr., E-Mail und Telefonnummer. Nach der Kontextaktualisierung erhält die öffentliche Prozedur ConfirmCustomerContactUpdate(ParamRecordCustomer: Record Customer) den vollständigen aktuellen Debitor einschließlich noch nicht gespeicherter Feldänderungen. Sie fragt vor der Aktualisierung eines verknüpften Kontakts nach. Bei Ablehnung oder Fehler bleibt die BC-Änderung erhalten.
  • Rufen Sie die Bestätigung nicht allein beim Öffnen, Navigieren oder unveränderten Speichern auf. OnModifyRecord im Beispiel aktualisiert nur den Kontext. Die Aktionen verwaltet der Page Part selbst; die Host-Seite ruft keine internen Prozeduren aus SIM_EDS B2Brouter Contact Mgt auf.
  • Die Standard-Debitorenkarte enthält diesen Page Part bereits. Ergänzen Sie ihn auf Ihrer eigenen Seite, ohne ihn auf der Standardkarte zu duplizieren.

Verfügbare Funktionen

Kontakt suchen (Lookup Contact) wählt einen vorhandenen Kontokontakt. Kontakt erstellen (Create Contact) verwendet gespeicherte Debitorendaten einschließlich Adresse und Telefonnummer; speichern Sie den Debitor vorher. Kontakt aktualisieren (Update Contact) überträgt aktuelle Debitorendaten nach Bestätigung. Für die Host-Seite genügen die beiden oben beschriebenen öffentlichen Prozeduren.

Für Peppol-Empfänger prüfen (Check Peppol Receiver) bleibt das Scheme leer, um USt-IdNr. und Land zu verwenden. Alternativ wählen Sie ein Scheme mit passender Kennung. Ergebnis und Prüfzeitpunkt werden gespeichert. Nach Änderung von Land, Scheme oder Kennung zeigt der Empfängerstatus geänderte Daten an, bis erneut geprüft wird. Empfängerregistrierung und Verknüpfung zu einem Kontokontakt sind getrennte Ergebnisse.

Transportart und Dokumenttyp werden für einen verknüpften Kontakt geladen. Verwenden Sie die Lookups für unterstützte Werte und wählen Sie zuerst die Transportart. Für Peppol müssen die Empfängerformate der aktuellen Kennung bestätigt sein. Routing-Änderungen erfordern eine Bestätigung; abgelehnte oder fehlgeschlagene Änderungen bleiben ausstehend (Routing Changes Pending). Update Contact wiederholt die Übertragung. Refresh Contact lädt die externen Werte und fragt vor dem Verwerfen ausstehender Änderungen nach. Diese Einstellungen ersetzen weder Versandprofil noch JSON-Schema-Einrichtung.

Integration prüfen

  1. Öffnen Sie einen gespeicherten Debitor ohne Zuordnung: Der sichtbare Page Part zeigt den Kontext, ohne allein durch das Öffnen einen Kontakt anzulegen.
  2. Wechseln Sie zwischen zwei Debitoren und öffnen Sie die Seite erneut. Prüfen Sie jeweils Verknüpfung und gespeicherte Sucheinstellungen.
  3. Verknüpfen Sie einen Kontakt, prüfen Sie einen Empfänger und erstellen Sie für einen anderen gespeicherten Debitor einen Kontakt im eingerichteten Testkonto. Kontrollieren Sie die Daten in B2Brouter.
  4. Ändern Sie jedes übertragene Feld. Tatsächliche Änderungen eines verknüpften Debitors müssen eine Aktualisierung anbieten; Öffnen oder unverändertes Speichern darf keine Rückfrage auslösen. Prüfen Sie Zustimmung und Ablehnung.
  5. Ändern Sie das Routing, lehnen Sie ab und wiederholen Sie mit Update Contact. Prüfen Sie Refresh Contact bei ausstehenden Änderungen und den Empfängerstatus nach Änderung von Kennung/Land.
Symptom Prüfpunkte
Page Part ausgeblendet Berechtigungen, Einrichtungsdatensatz, Sichtbarkeitsvariable und Produktions-/Staging-Konto-IDs.
Leerer oder falscher Kontext Aktueller Rec, Steuerelementname, OnAfterGetCurrRecord, alle sieben SetContext-Parameter und passender SubPageLink-Schlüssel.
Debitor fehlt bei einer Aktion Gespeicherte Debitorennummer und Database::Customer; der vollständige Ablauf unterstützt keine beliebigen Tabellen-IDs.
Verbindungsfehler oder fehlende Routing-Auswahl Ausgewählte Umgebung samt Konto/API-Schlüssel, Kontakt, Land/Scheme/Kennung und unterstützte Empfängerformate.
Wiederholte Rückfragen Bestätigung nur bei tatsächlichen Feldänderungen aufrufen, nicht bei Navigation oder Speichervorgängen.

Siehe auch