Saltar al contenido

Evento de Línea de Entrada

Los Portales de Negocios pueden activar un evento basado en la entrada en una línea en el frontend. Esta entrada se envía a Business Central, donde puede ser procesada por un código personalizado para recalcular valores o devolver un resultado específico.

Esta sección proporciona un ejemplo de cómo implementar un código personalizado que se activa por un evento basado en la entrada del usuario.

Ejemplo de Código

En este ejemplo, utilizaremos la tabla de Líneas de Pedido de Venta en un escenario donde el usuario puede ingresar una cantidad para los artículos listados en una línea. La entrada actualizará el precio del artículo multiplicando la cantidad por el precio unitario.

La entrada del usuario activa un evento al enviar el valor a Business Central, donde se procesa en un código 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', 'Se han deseleccionado todas las filas con el mismo número.');
        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);

                // Esto obtendrá el valor de lo que se ingresa en el frontend,
                if LocalLineRecordSIMDPSOL.FindSet() then
                    LocalInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'QUANTITY');

                // Filtrar en la línea exacta que activa el evento, y obtener el valor de otros campos para el cálculo, luego devolver el valor al frontend. Es solo un ejemplo basado en el campo Cantidad, puede ser cualquier otro campo y cualquier cálculo basado en el requisito. Se recomienda obtener directamente la línea que activa el evento y devolver el valor solo para esa línea, luego hacer el cálculo en el lado del cliente, si hay preocupaciones de rendimiento cuando hay muchas líneas con la misma cantidad.
                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
                    // Este bloque de código devolverá el valor de entrada al 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);

                    // Este bloque de código devolverá otros valores de campo, basados en el valor de entrada, al frontend para el cálculo. En este ejemplo, devuelve el Precio Unitario y realiza una multiplicación en el backend, luego devuelve el resultado al frontend, pero puede ser cualquier otro campo y cualquier cálculo basado en el requisito.
                    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;

Ejemplo de Código 2

Con un escenario similar al primer Ejemplo de Código, este ejemplo de código mostrará cómo actualizar todas las líneas en lugar de solo la línea seleccionada.

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

                // Esto obtendrá el valor de lo que se ingresa en el frontend,
                if LocalLineRecordSIMDPSOL.FindSet() then
                    LocalInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'QUANTITY');

                // Para recorrer todas las líneas con la misma cantidad, el código puede ser como el siguiente, pero puede tener problemas de rendimiento cuando hay muchas líneas, por lo que es mejor obtener directamente la línea que activa el evento y devolver el valor solo para esa línea, luego hacer el cálculo en el lado del cliente.

                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;

Ejemplo de Código 3

Con un escenario similar al primer Ejemplo de Código, este ejemplo mostrará cómo actualizar las líneas de la línea seleccionada con más campos, así como cómo bloquear una actualización cuando se modifica un campo específico.

En este ejemplo se añaden dos campos adicionales, llamados BRUTTO y NETTO. Estos campos utilizarán un número estático ficticio, ya que la tabla estándar Sales Order Line no contiene estos valores/campos en la base de datos. Estos campos pueden ser reemplazados por cualquier otra cosa.

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

            // Esto obtendrá el valor de lo que se introduce en el 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');

            // Salvaguarda para entradas vacías; si la entrada está vacía, se tratará como 0 en los cálculos. Esto aplica para entradas numéricas; para texto puede tratarse como cadena vacía y no es necesario convertir a 0.
            if LocalQuantityInputText = '' then
                LocalQuantityInputText := '0';
            if LocalBruttoInputText = '' then
                LocalBruttoInputText := '0';
            if LocalNettoInputText = '' then
                LocalNettoInputText := '0';
            if LocalPriceInputText = '' then
                LocalPriceInputText := '0';

            // Filtra exactamente la línea que dispara el evento y obtiene los valores de otros campos para el cálculo, luego devuelve el valor al frontend. Es solo un ejemplo basado en el campo Quantity; puede ser cualquier otro campo y cualquier cálculo según el requisito. Se recomienda obtener directamente la línea que dispara el evento y devolver solo ese valor, y realizar el cálculo en el cliente si hay problemas de rendimiento con muchas líneas con la misma cantidad.
            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
                // Este bloque de código devolverá el valor introducido al 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);

                // Evalúa el valor de entrada y lo transfiere a las variables locales
                Evaluate(LocalMultiplierDecimal, LocalQuantityInputText);
                Evaluate(LocalBruttoDecimal, LocalBruttoInputText);
                Evaluate(LocalNettoDecimal, LocalNettoInputText);
                Evaluate(LocalPriceDecimal, LocalPriceInputText);

                //PRICE
                // Este bloque devolverá otros valores de campos basados en la entrada para cálculo en el frontend. En este ejemplo devuelve el Unit Price y realiza una multiplicación en backend, luego devuelve el resultado al frontend, pero puede ser cualquier campo y cualquier cálculo según el requisito.
                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));

                // Comprueba si el campo QUANTITY ha cambiado o si otros campos no están inicializados; entonces devuelve los valores calculados de BRUTTO y NETTO al frontend, de lo contrario devuelve los valores introducidos sin cálculo
                if LocalQuantityChangeBoolean or (LocalBruttoDecimal = 0) or (LocalNettoDecimal = 0) then begin
                    //BRUTTO
                    // Este bloque de código devolverá el valor introducido al frontend
                    LocalInfoXmlElement := XmlElement.Create('INFO');
                    LocalEventXmlElement.Add(LocalInfoXmlElement);
                    LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

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

                    // La lógica de cálculo es solo un ejemplo y puede ajustarse según los requisitos
                    // Calcula el valor multiplicador basado en la QUANTITY introducida y lo multiplica por un valor (10 en este ejemplo) para obtener BRUTTO; si QUANTITY cambia o BRUTTO no está inicializado, se usa este valor, de lo contrario se devuelve el valor introducido sin cálculo
                    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
                    // Este bloque de código devolverá el valor introducido al frontend
                    LocalInfoXmlElement := XmlElement.Create('INFO');
                    LocalEventXmlElement.Add(LocalInfoXmlElement);
                    LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

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

                    // La lógica de cálculo es solo un ejemplo y puede ajustarse según los requisitos
                    // Calcula el valor multiplicador basado en la QUANTITY introducida y lo multiplica por un valor (5 en este ejemplo) para obtener NETTO; si QUANTITY cambia o NETTO no está inicializado, se usa este valor, de lo contrario se devuelve el valor introducido sin cálculo
                    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;