Aller au contenu

Intégrer le Page Part de contacts B2Brouter

Le Page Part B2Brouter lie un client Business Central à un contact de votre compte B2Brouter sur une page client personnalisée. Comme sur la Fiche client standard, il propose la recherche, la création et la mise à jour des contacts, la vérification des destinataires Peppol et les paramètres de transport et de type de document.

Conditions préalables et périmètre

  • Installez Document Dispatch, activez sa licence et configurez les accès utilisateurs. Référencez Document Dispatch et CORE by Simova dans les dépendances de app.json, avec les IDs, l'éditeur et les versions compatibles des applications installées. Téléchargez leurs symboles.
  • Configurez le compte et la clé API dans la Configuration du module B2Brouter. Le mode test utilise staging ; sinon, la production est utilisée. Le contrôle de visibilité de l'exemple vérifie uniquement la présence d'un ID de compte, sans valider la connexion sélectionnée.
  • Les utilisateurs ont besoin d'un accès à la page hôte et à Customer, ainsi que des autorisations Document Dispatch correspondantes. SIM_EDS USER et SIM_EDS ADMIN incluent le Page Part, sa table de contacts et la codeunit de gestion. La visibilité n'accorde aucune autorisation.
  • Utilisez un client enregistré avec un numéro renseigné. Adaptez l'ID d'objet 50100, les noms et les libellés à votre solution.

Pages personnalisées basées sur Customer

Le fonctionnement complet nécessite actuellement SourceTable = Customer. Bien que SetContext accepte un ID de table, Créer un contact, Mettre à jour le contact et les modifications de routage recherchent en interne un Customer à partir du numéro transmis. La confirmation recherche également le lien avec Database::Customer. Transmettre l'ID d'une autre table personnalisée n'adapte pas ces actions à cette table. Pour une autre entité, définissez d'abord sa correspondance avec un client réel et transmettez le numéro, l'ID de table et les données de ce client.

Objets et données enregistrées

L'objet intégré est la page 5492741, SIM_EDS B2Brouter Contact LP. Malgré le suffixe LP, son PageType est CardPart. Sa source est la table 5492683, SIM_EDS B2Brouter Contact, avec SourceTableTemporary = true.

Le Page Part utilise une ligne temporaire et lit la configuration persistante avec la clé composée No. + Table Id. Les pages utilisant la même clé client partagent le lien. L'enregistrement contient l'ID du contact, les paramètres et résultats de recherche, les types de transport/document et les modifications de routage en attente. La clé ne contient ni compte ni environnement : changer de mode test ne sélectionne pas automatiquement un autre lien local. Vérifiez le contact lié dans le compte sélectionné.

Renseigner le Page Part avec SetContext

SubPageLink associe le Page Part à la clé client. Appelez également la procédure publique SetContext pour renseigner la ligne temporaire et les variables de recherche. SubPageLink seul ne suffit pas.

procedure SetContext(ParamNoCode: Code[50]; ParamTableIdInteger: Integer;
    ParamNameText: Text; ParamCountryCodeText: Text;
    ParamSchemeCodeText: Text; ParamIdentifierText: Text; ParamEmailText: Text)
Paramètre Type Valeur et rôle
ParamNoCode Code[50] Rec."No." : numéro du client et première partie de la clé.
ParamTableIdInteger Integer Database::Customer : deuxième partie de la clé ; doit correspondre à SubPageLink.
ParamNameText Text Rec.Name : texte de recherche des contacts.
ParamCountryCodeText Text Rec."Country/Region Code" : pays pour la recherche dans l'annuaire.
ParamSchemeCodeText Text '' pour la recherche par TVA et pays, ou un schéma B2Brouter valide. Le Page Part accepte jusqu'à 100 caractères.
ParamIdentifierText Text Rec."VAT Registration No." : identifiant par défaut.
ParamEmailText Text Rec."E-Mail" : utilisé pour proposer les types de transport disponibles.

Chaque appel reconstruit la ligne temporaire et charge le lien existant. Directory Scheme Code enregistré remplace le schéma transmis. Lookup Identifier enregistré est utilisé s'il est renseigné et qu'un schéma est sélectionné ; sinon, l'identifiant par défaut transmis est utilisé. Le Page Part gère la sélection et la validation du schéma. Un schéma vide transmis à la procédure ne réinitialise pas une sélection enregistrée.

Ouvrir ou changer de client ne crée pas de lien persistant. Enregistrer les paramètres de recherche, lier/créer un contact ou vérifier l'annuaire peut en créer un. Pour un contact lié, SetContext peut charger les données de routage depuis B2Brouter. Le contexte chargé est mis en cache pour éviter un nouvel appel à chaque validation de champ ; cette procédure n'est donc pas exclusivement locale.

Exemple complet : fiche client personnalisée

Cette page autonome utilise Customer et intègre le Page Part dans un groupe B2Brouter. Elle actualise le contexte lors du changement d'enregistrement et après les modifications. Les dix champs transmis ne demandent une mise à jour distante que si leur valeur a réellement changé.

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;
}

Adapter l'exemple

  • Intégrez groupe, variables, procédures et déclencheurs à votre page Customer. Pour une Page Extension, utilisez addlast(Content) ou une ancre addafter(...) adaptée. Complétez les validations par modify(...) et OnAfterValidate, avec HandleCustomerChange(Rec.<champ> <> xRec.<champ>).
  • CurrPage.B2BrouterContact.Page... désigne le contrôle part(B2BrouterContact; ...), pas le nom de l'objet page intégré.
  • Appelez SetContext dans OnAfterGetCurrRecord pour afficher le bon lien lors de la navigation. Actualisez aussi le contexte après une modification du nom, du pays, du numéro de TVA ou de l'e-mail, et après l'enregistrement. Préservez les validations et la logique d'enregistrement existantes.
  • Pour reproduire la fiche standard, traitez Nom, Adresse, Adresse 2, Code postal, Ville, Région, Code pays/région, Numéro de TVA, E-mail et Téléphone. Après actualisation du contexte, transmettez le client actuel complet, y compris les modifications non enregistrées, à ConfirmCustomerContactUpdate(ParamRecordCustomer: Record Customer). Cette procédure publique demande confirmation avant de mettre à jour un contact lié. Un refus ou un échec conserve la modification BC.
  • Ne demandez pas confirmation à la simple ouverture, à la navigation ou lors d'un enregistrement sans modification. Le OnModifyRecord de l'exemple actualise uniquement le contexte. Le Page Part gère ses actions ; la page hôte n'appelle pas les procédures internes de SIM_EDS B2Brouter Contact Mgt.
  • La fiche client standard contient déjà ce Page Part. Ajoutez-le à votre propre page sans le dupliquer sur la fiche standard.

Fonctions disponibles

Lookup Contact sélectionne un contact existant du compte. Create Contact utilise les données client enregistrées, adresse et téléphone compris ; enregistrez le client au préalable. Update Contact transmet les données actuelles après confirmation. La page hôte n'a besoin que des deux procédures publiques décrites.

Pour Check Peppol Receiver, laissez le schéma vide pour utiliser le numéro de TVA et le pays, ou choisissez un schéma et son identifiant. Le résultat et la date de vérification sont enregistrés. Après modification du pays, du schéma ou de l'identifiant, l'état indique des données modifiées jusqu'à une nouvelle vérification. La présence du destinataire et le lien avec un contact du compte sont deux résultats distincts.

Les Type de transport et Type de document sont chargés pour un contact lié. Utilisez les listes de valeurs prises en charge et sélectionnez d'abord le transport. Pour Peppol, les formats du destinataire doivent être confirmés pour l'identifiant actuel. Les modifications de routage demandent confirmation ; un refus ou un échec les laisse en Routing Changes Pending. Update Contact permet de les renvoyer. Refresh Contact recharge les valeurs distantes et demande confirmation avant d'abandonner les modifications en attente. Ces paramètres ne remplacent pas le profil d'envoi ni la configuration du schéma JSON.

Vérifier l'intégration

  1. Ouvrez un client enregistré sans lien : le Page Part doit afficher son contexte sans créer de contact à la simple ouverture.
  2. Naviguez entre deux clients puis rouvrez la page. Vérifiez chaque lien et les paramètres enregistrés.
  3. Liez un contact, vérifiez un destinataire et créez un contact pour un autre client enregistré dans le compte de test configuré. Contrôlez les données dans B2Brouter.
  4. Modifiez chaque champ transmis. Une modification réelle d'un client lié doit proposer une mise à jour ; l'ouverture et l'enregistrement sans changement ne doivent pas le faire. Testez l'acceptation et le refus.
  5. Modifiez le routage, refusez l'envoi puis réessayez avec Update Contact. Testez Refresh Contact avec des modifications en attente et l'état du destinataire après modification de l'identifiant/pays.
Symptôme Points à vérifier
Page Part masqué Autorisations, configuration, variable de visibilité et IDs de compte production/staging.
Contexte vide ou incorrect Rec, nom du contrôle, OnAfterGetCurrRecord, les sept arguments de SetContext et clé correspondante dans SubPageLink.
Client introuvable lors d'une action Numéro du client enregistré et Database::Customer ; les autres tables ne sont pas prises en charge par le fonctionnement complet.
Erreur de connexion ou aucun choix de routage Environnement/compte/clé API, contact lié, pays/schéma/identifiant et formats du destinataire.
Confirmations répétées Confirmer uniquement les changements réels de champs, jamais depuis les déclencheurs de navigation ou d'enregistrement.

Voir aussi