Aller au contenu

Événement de ligne d'entrée

Les portails d'entreprise peuvent déclencher un événement basé sur l'entrée dans une ligne sur le frontend. Cette entrée est envoyée à Business Central, où elle peut être traitée par un codeunit personnalisé pour recalculer des valeurs ou retourner un résultat spécifique.

Cette section fournit un exemple de la façon d'implémenter un codeunit personnalisé qui est déclenché par un événement basé sur l'entrée de l'utilisateur.

Exemple de code

Dans cet exemple, nous utiliserons la table des lignes de commande de vente dans un scénario où l'utilisateur peut saisir une quantité pour les articles listés dans une ligne. L'entrée mettra à jour le prix de l'article en multipliant la quantité par le prix unitaire.

L'entrée de l'utilisateur déclenche un événement en envoyant la valeur à Business Central, où elle est traitée dans un codeunit de Business Central.

AL
'INPUTLINE':
    begin
        LocalEventXmlElement := XmlElement.Create('EVENT');
        LocalRootXmlElement.Add(LocalEventXmlElement);
        LocalRootXmlElement.SetAttribute('EVENTTYPE', ParamRecordSIMDPSOL."Sub Function Event");
        LocalRootXmlElement.SetAttribute('EVENTVALUE', LocalEventValueText);
        LocalRootXmlElement.SetAttribute('EVENTMESSAGE', 'Toutes les lignes comportant le même nombre ont été désélectionnées.');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGETYPE', 'default');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILE', '');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILETYPE', 'default');

        if Evaluate(LocalRecordId, LocalEventValueText, 9) then
            if LocalRecordRef.Get(LocalRecordId) then begin
                LocalLineRecordSIMDPSOL.Reset();
                LocalLineRecordSIMDPSOL.SetRange("Entry No.", ParamRecordSIMDPSOL."Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Sub Entry No.", ParamRecordSIMDPSOL."Sub Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Code", ParamRecordSIMDPSOL."Dataset Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Code", ParamRecordSIMDPSOL."Dataset Table Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Type", ParamRecordSIMDPSOL."Dataset Table Type"::Line);
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Record", LocalRecordId);

                // Cela obtiendra la valeur de ce qui est saisi dans le frontend,
                if LocalLineRecordSIMDPSOL.FindSet() then
                    LocalInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'QUANTITY');

                // Filtrer à la ligne exacte qui déclenche l'événement, et obtenir la valeur d'autres champs pour le calcul, puis retourner la valeur au frontend. C'est juste un exemple basé sur le champ Quantité, cela peut être n'importe quel autre champ et tout calcul basé sur les exigences. Il est recommandé d'obtenir directement la ligne qui déclenche l'événement et de retourner la valeur pour cette ligne uniquement, puis de faire le calcul côté client, s'il y a des préoccupations de performance lorsqu'il y a beaucoup de lignes avec la même quantité.
                LocalRecordRef.SetTable(LocalRecordSalesLine);
                Local2RecordSalesLine.SetRange("Document Type", LocalRecordSalesLine."Document Type");
                Local2RecordSalesLine.SetRange("Document No.", LocalRecordSalesLine."Document No.");
                Local2RecordSalesLine.SetRange("Line No.", LocalRecordSalesLine."Line No.");
                Local2RecordSalesLine.SetRange(Quantity, LocalRecordSalesLine.Quantity);
                if Local2RecordSalesLine.FindFirst() then begin
                    // Ce bloc de code retournera la valeur d'entrée au frontend.
                    LocalInfoXmlElement := XmlElement.Create('INFO');
                    LocalEventXmlElement.Add(LocalInfoXmlElement);
                    LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                    LocalInputXmlElement := XmlElement.Create('INPUT');
                    LocalInfoXmlElement.Add(LocalInputXmlElement);
                    LocalInputXmlElement.SetAttribute('NAME', 'QUANTITY');
                    LocalInputXmlElement.SetAttribute('VALUE', LocalInputText);

                    // Ce bloc de code retournera d'autres valeurs de champ, basées sur la valeur d'entrée, au frontend pour le calcul. Dans cet exemple, il retourne le prix unitaire et effectue une multiplication en backend, puis retourne le résultat au frontend, mais cela peut être n'importe quel autre champ et tout calcul basé sur les exigences.
                    LocalInfoXmlElement := XmlElement.Create('INFO');
                    LocalEventXmlElement.Add(LocalInfoXmlElement);
                    LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                    LocalInputXmlElement := XmlElement.Create('INPUT');
                    LocalInfoXmlElement.Add(LocalInputXmlElement);
                    Evaluate(LocalMultiplierDecimal, LocalInputText);

                    LocalSumDecimal := LocalMultiplierDecimal * Local2RecordSalesLine."Unit Price";

                    LocalInputXmlElement.SetAttribute('NAME', 'PRICE');
                    LocalInputXmlElement.SetAttribute('VALUE', Format(LocalSumDecimal, 0, 9));
                end;
            end;
    end;

Exemple de code 2

Avec un scénario similaire au premier Exemple de code, cet exemple de code montrera comment mettre à jour toutes les lignes plutôt que seulement la ligne sélectionnée.

AL
 'INPUTLINE':
    begin
        LocalEventXmlElement := XmlElement.Create('EVENT');
        LocalRootXmlElement.Add(LocalEventXmlElement);
        LocalRootXmlElement.SetAttribute('EVENTTYPE', ParamRecordSIMDPSOL."Sub Function Event");
        LocalRootXmlElement.SetAttribute('EVENTVALUE', LocalEventValueText);
        LocalRootXmlElement.SetAttribute('EVENTMESSAGE', 'Alle Zeilen mit der gleichen Anzahl wurden abgewählt.');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGETYPE', 'default');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILE', '');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILETYPE', 'default');

        if Evaluate(LocalRecordId, LocalEventValueText, 9) then
            if LocalRecordRef.Get(LocalRecordId) then begin
                LocalLineRecordSIMDPSOL.Reset();
                LocalLineRecordSIMDPSOL.SetRange("Entry No.", ParamRecordSIMDPSOL."Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Sub Entry No.", ParamRecordSIMDPSOL."Sub Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Code", ParamRecordSIMDPSOL."Dataset Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Code", ParamRecordSIMDPSOL."Dataset Table Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Type", ParamRecordSIMDPSOL."Dataset Table Type"::Line);
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Record", LocalRecordId);

                // Cela obtiendra la valeur de ce qui est saisi dans le frontend,
                if LocalLineRecordSIMDPSOL.FindSet() then
                    LocalInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'QUANTITY');

                // Pour parcourir toutes les lignes avec la même quantité, le code peut être comme ci-dessous, mais cela peut avoir des problèmes de performance lorsqu'il y a beaucoup de lignes, donc il est préférable d'obtenir directement la ligne qui déclenche l'événement et de retourner la valeur pour cette ligne uniquement, puis de faire le calcul côté client.

                LocalRecordRef.SetTable(LocalRecordSalesLine);
                Local2RecordSalesLine.SetRange("Document Type", LocalRecordSalesLine."Document Type");
                Local2RecordSalesLine.SetRange("Document No.", LocalRecordSalesLine."Document No.");
                Local2RecordSalesLine.SetRange(Quantity, LocalRecordSalesLine.Quantity);
                if Local2RecordSalesLine.FindSet() then
                    repeat
                        LocalInfoXmlElement := XmlElement.Create('INFO');
                        LocalEventXmlElement.Add(LocalInfoXmlElement);
                        LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                        LocalInputXmlElement := XmlElement.Create('INPUT');
                        LocalInfoXmlElement.Add(LocalInputXmlElement);
                        LocalInputXmlElement.SetAttribute('NAME', 'QUANTITY');
                        LocalInputXmlElement.SetAttribute('VALUE', LocalInputText);

                        LocalInputXmlElement := XmlElement.Create('INPUT');
                        LocalInfoXmlElement.Add(LocalInputXmlElement);
                        Evaluate(LocalMultiplierDecimal, LocalInputText);

                        LocalSumDecimal := LocalMultiplierDecimal * Local2RecordSalesLine."Unit Price";

                        LocalInputXmlElement.SetAttribute('NAME', 'PRICE');
                        LocalInputXmlElement.SetAttribute('VALUE', Format(LocalSumDecimal, 0, 9));

                    until Local2RecordSalesLine.Next() = 0;
            end
    end;

Exemple de Code 3

Avec un scénario similaire au premier Exemple de Code, cet exemple montre comment mettre à jour les lignes de la ligne sélectionnée avec des champs supplémentaires, ainsi que comment bloquer une mise à jour lorsqu’un champ spécifique est modifié.

Dans cet exemple, deux champs supplémentaires sont ajoutés, à savoir BRUTTO et NETTO. Ces champs utiliseront une valeur statique fictive, car la table standard Sales Order Line ne contient pas ces valeurs/champs dans la base de données. Ces champs peuvent être remplacés par n’importe quoi d’autre.

AL
 'INPUTLINE':
    begin
    LocalEventXmlElement := XmlElement.Create('EVENT');
    LocalRootXmlElement.Add(LocalEventXmlElement);
    LocalRootXmlElement.SetAttribute('EVENTTYPE', ParamRecordSIMDPSOL."Sub Function Event");
    LocalRootXmlElement.SetAttribute('EVENTVALUE', LocalEventValueText);
    LocalRootXmlElement.SetAttribute('EVENTMESSAGE', 'Alle Zeilen mit der gleichen Anzahl wurden abgewählt.');
    LocalRootXmlElement.SetAttribute('EVENTMESSAGETYPE', 'default');
    LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILE', '');
    LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILETYPE', 'default');

    if Evaluate(LocalRecordId, LocalEventValueText, 9) then
        if LocalRecordRef.Get(LocalRecordId) then begin
            LocalLineRecordSIMDPSOL.Reset();
            LocalLineRecordSIMDPSOL.SetRange("Entry No.", ParamRecordSIMDPSOL."Entry No.");
            LocalLineRecordSIMDPSOL.SetRange("Sub Entry No.", ParamRecordSIMDPSOL."Sub Entry No.");
            LocalLineRecordSIMDPSOL.SetRange("Dataset Code", ParamRecordSIMDPSOL."Dataset Code");
            LocalLineRecordSIMDPSOL.SetRange("Dataset Table Code", ParamRecordSIMDPSOL."Dataset Table Code");
            LocalLineRecordSIMDPSOL.SetRange("Dataset Table Type", ParamRecordSIMDPSOL."Dataset Table Type"::Line);
            LocalLineRecordSIMDPSOL.SetRange("Dataset Table Record", LocalRecordId);

            // Cela récupère la valeur saisie dans le frontend
            if LocalLineRecordSIMDPSOL.FindSet() then
                LocalQuantityInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'QUANTITY');
            if LocalLineRecordSIMDPSOL.FindSet() then
                LocalBruttoInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'BRUTTO');
            if LocalLineRecordSIMDPSOL.FindSet() then
                LocalNettoInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'NETTO');
            if LocalLineRecordSIMDPSOL.FindSet() then
                LocalPriceInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'PRICE');

            // Protection pour les entrées vides : si l’entrée est vide, elle sera traitée comme 0 dans les calculs. Cela s’applique aux entrées numériques ; pour les entrées texte, elle peut être considérée comme une chaîne vide sans conversion en 0.
            if LocalQuantityInputText = '' then
                LocalQuantityInputText := '0';
            if LocalBruttoInputText = '' then
                LocalBruttoInputText := '0';
            if LocalNettoInputText = '' then
                LocalNettoInputText := '0';
            if LocalPriceInputText = '' then
                LocalPriceInputText := '0';

            // Filtre exactement la ligne qui déclenche l’événement et récupère les valeurs des autres champs pour le calcul, puis renvoie la valeur au frontend. Il s’agit simplement d’un exemple basé sur le champ Quantity ; cela peut être n’importe quel autre champ et n’importe quel calcul selon les besoins. Il est recommandé de récupérer directement la ligne qui déclenche l’événement et de renvoyer uniquement cette valeur, puis d’effectuer le calcul côté client s’il y a des problèmes de performance avec de nombreuses lignes ayant la même quantité.
            LocalRecordRef.SetTable(LocalRecordSalesLine);
            Local2RecordSalesLine.SetRange("Document Type", LocalRecordSalesLine."Document Type");
            Local2RecordSalesLine.SetRange("Document No.", LocalRecordSalesLine."Document No.");
            Local2RecordSalesLine.SetRange("Line No.", LocalRecordSalesLine."Line No.");
            Local2RecordSalesLine.SetRange(Quantity, LocalRecordSalesLine.Quantity);
            if Local2RecordSalesLine.FindFirst() then begin
                // Ce bloc de code renvoie la valeur saisie au frontend
                LocalInfoXmlElement := XmlElement.Create('INFO');
                LocalEventXmlElement.Add(LocalInfoXmlElement);
                LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                LocalInputXmlElement := XmlElement.Create('INPUT');
                LocalInfoXmlElement.Add(LocalInputXmlElement);
                LocalInputXmlElement.SetAttribute('NAME', 'QUANTITY');
                LocalInputXmlElement.SetAttribute('VALUE', LocalQuantityInputText);

                // Évalue la valeur saisie et la transfère aux variables locales
                Evaluate(LocalMultiplierDecimal, LocalQuantityInputText);
                Evaluate(LocalBruttoDecimal, LocalBruttoInputText);
                Evaluate(LocalNettoDecimal, LocalNettoInputText);
                Evaluate(LocalPriceDecimal, LocalPriceInputText);

                //PRICE
                // Ce bloc de code renvoie d’autres valeurs de champs, basées sur la valeur saisie, au frontend pour le calcul. Dans cet exemple, il renvoie le Unit Price et effectue une multiplication côté backend, puis renvoie le résultat au frontend, mais cela peut être n’importe quels champs et n’importe quel calcul selon les besoins.
                LocalInfoXmlElement := XmlElement.Create('INFO');
                LocalEventXmlElement.Add(LocalInfoXmlElement);
                LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                LocalInputXmlElement := XmlElement.Create('INPUT');
                LocalInfoXmlElement.Add(LocalInputXmlElement);

                LocalSumDecimal := LocalMultiplierDecimal * Local2RecordSalesLine."Unit Price";

                if LocalPriceDecimal <> LocalSumDecimal then
                    LocalQuantityChangeBoolean := true;

                LocalInputXmlElement.SetAttribute('NAME', 'PRICE');
                LocalInputXmlElement.SetAttribute('VALUE', Format(LocalSumDecimal, 0, 9));

                // Vérifie si le champ QUANTITY a été modifié ou si d’autres champs ne sont pas initialisés ; dans ce cas, renvoie les valeurs calculées de BRUTTO et NETTO au frontend, sinon renvoie simplement les valeurs saisies sans calcul
                if LocalQuantityChangeBoolean or (LocalBruttoDecimal = 0) or (LocalNettoDecimal = 0) then begin
                    //BRUTTO
                    // Ce bloc de code renvoie la valeur saisie au frontend
                    LocalInfoXmlElement := XmlElement.Create('INFO');
                    LocalEventXmlElement.Add(LocalInfoXmlElement);
                    LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                    LocalInputXmlElement := XmlElement.Create('INPUT');
                    LocalInfoXmlElement.Add(LocalInputXmlElement);

                    // La logique de calcul est donnée à titre d’exemple et peut être adaptée selon les besoins
                    // Calcule la valeur multiplicatrice basée sur la QUANTITY saisie, puis la multiplie par une valeur (10 dans cet exemple) pour obtenir BRUTTO ; si la QUANTITY est modifiée ou si BRUTTO n’est pas initialisé, cette valeur est utilisée, sinon la valeur saisie est renvoyée sans calcul
                    LocalSumDecimal := LocalMultiplierDecimal * 10;
                    if not LocalQuantityChangeBoolean then
                        if (LocalBruttoDecimal <> LocalSumDecimal) and (LocalBruttoDecimal <> 0) then
                            LocalSumDecimal := LocalBruttoDecimal;

                    LocalInputXmlElement.SetAttribute('NAME', 'BRUTTO');
                    LocalInputXmlElement.SetAttribute('VALUE', Format(LocalSumDecimal, 0, 9));

                    //NETTO
                    // Ce bloc de code renvoie la valeur saisie au frontend
                    LocalInfoXmlElement := XmlElement.Create('INFO');
                    LocalEventXmlElement.Add(LocalInfoXmlElement);
                    LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                    LocalInputXmlElement := XmlElement.Create('INPUT');
                    LocalInfoXmlElement.Add(LocalInputXmlElement);

                    // La logique de calcul est donnée à titre d’exemple et peut être adaptée selon les besoins
                    // Calcule la valeur multiplicatrice basée sur la QUANTITY saisie, puis la multiplie par une valeur (5 dans cet exemple) pour obtenir NETTO ; si la QUANTITY est modifiée ou si NETTO n’est pas initialisé, cette valeur est utilisée, sinon la valeur saisie est renvoyée sans calcul
                    LocalSumDecimal := LocalMultiplierDecimal * 5;

                    if not LocalQuantityChangeBoolean then
                        if (LocalNettoDecimal <> LocalSumDecimal) and (LocalNettoDecimal <> 0) then
                            LocalSumDecimal := LocalNettoDecimal;

                    LocalInputXmlElement.SetAttribute('NAME', 'NETTO');
                    LocalInputXmlElement.SetAttribute('VALUE', Format(LocalSumDecimal, 0, 9));
                end;
            end;
        end;
    end;