练习 - 自定义函数

已完成

您是 CRONUS International Ltd 的业务系统开发人员。您正在学习如何为 Business Central 开发自定义项,以及如何在 AL 中进行编程来为客户自定义解决方案。 您想要通过以下方法自定义 Customer Card 页面:添加一项操作来根据客户以前的销售历史记录调整客户信用额度,或在未发生任何交易记录时将信用额度重置为零。

您了解到以下要求:

  • 客户的信用额度不能超过客户在过去 12 个月中的总销售收入的 50%。

  • 客户的信用额度必须始终舍入到最接近的 10,000。

  • 如果在流程期间舍入信用额度,则应用程序必须向用户发送通知。

  • 如果新信用额度与旧信用额度相同,则应用程序必须向用户发送通知。

  • 如果客户在过去 12 个月中没有销售历史记录,则信用额度必须重置为零。

  • 设置信用额度的函数必须适用于其他对象。

  • Customer Card 页面必须包含用于调用该函数的操作。

  • 如果通过页面操作调用了该函数,并且信用额度将会增加,则在更新信用额度之前,该函数必须要求用户进行确认。

任务

  • 创建一个新扩展。

  • 创建表扩展。

  • 创建一个页面扩展。

步骤

  1. 启动 Visual Studio Code。

  2. 创建新 AL 扩展项目。 选择视图 > 命令面板... (Ctrl+Shift+P)。

  3. 在搜索框中输入 AL: Go!,然后从列表中选择命令。

  4. 接受建议的路径,但将名称更改为 CreditLimit(或输入其他路径)。

  5. 选择最新的目标平台。

  6. 选择 Microsoft 云沙盒作为开发终结点。

  7. 下载应用程序符号。 选择视图 > 命令面板... (Ctrl+Shift+P)。

  8. 在搜索框中输入 AL: 下载符号,然后从列表中选择命令。

  9. 如果需要,请提供您的组织凭据(Microsoft 365 帐户/Microsoft Entra ID 帐户)。

  10. 打开 app.json 文件,将 name 设置更改为 Credit Limit。 将 publisher 设置更改为 Cronus International Ltd.

  11. idRanges50400 更改为 50450

  12. 删除 HelloWorld.al 文件。

  13. 添加一个文件夹,并命名为:src

  14. 在 src 文件夹中,创建一个名为 Customer.TableExt.al 的文件。

  15. 使用代码片段在本文件中创建一个新的表扩展。 输入 ttableext,然后按 Tab 键。

  16. ID 更改为 50400,将 name 更改为 Customer

  17. Extends 参数设置为 Customer 以扩展 Customer 表。

  18. 将一个非局部过程添加到 Customer 表扩展,并将其命名为 UpdateCreditLimit

  19. 修改 UpdateCreditLimit 函数,以便通过引用接收名为 NewCreditLimit 且类型为“小数”的参数。

  20. 添加另一个非局部过程,并将其命名为 CalculateCreditLimit,该函数返回“小数”类型的值。

  21. 在 src 文件夹中创建一个新文件,并命名为:CustomerCard.PageExt.al

  22. 使用代码片段在此文件中创建一个新的页面扩展。 输入 tpageext,然后按 Tab 键。

  23. ID 更改为 50130,将 name 更改为 CustomerCard

  24. Extends 参数设置为 Customer Card

  25. 创建一个局部过程并将其命名为 CallUpdateCreditLimit

  26. ActionItems 操作容器的函数操作组添加一个操作。 在 Actions 部分中,输入 addAfter("F&unctions)

  27. addafter 部分中添加名为 UpdateCreditLimit 的操作,然后将 Caption 和“Tooltip”属性设为 Update Credit Limit。 将 Image 属性设置为 CalculateCost

  28. OnAction 触发器中,调用 CallUpdateCreditLimit 操作。

  29. 修改表扩展的 CalculateCreditLimit 函数。 添加一个名为 Customer 且类型为“记录客户”的局部变量。

  30. CalculateCreditLimit 函数添加代码,以针对过去 12 个月计算 Sales (LCY) 字段的值。

    Cust := Rec;
    Cust.SetRange("Date Filter",CalcDate('<-12M>',WorkDate()),WorkDate());
    Cust.CalcFields("Sales (LCY)","Balance (LCY)");
    exit(Round(Cust."Sales (LCY)" * 0.5));
    

    一项要求为:客户的信用额度不能超过客户在过去 12 个月中的总销售收入的 50%。

  31. UpdateCreditLimit 函数添加代码以将 NewCreditLimit 形参舍入到最接近的 10,000,从而验证 Credit Limit (LCY) 字段中 NewCreditLimit 的值并修改记录。

    NewCreditLimit := Round(NewCreditLimit, 10000);
    Rec.Validate("Credit Limit (LCY)", NewCreditLimit);
    Rec.Modify();
    

    一项要求为:客户的信用额度必须始终舍入到最接近的 10,000。

  32. 将三个全局标签添加到页面扩展中并包含以下文本:

    • 确认消息

    • 有关舍入信用额度的信息

    • 有关最新信用额度的信息

    名称 ConstValue
    AreYouSureQst 是否确定要将 %1 设为 %2?
    CreditLimitRoundedTxt 信用额度已舍入到 %1 以遵守公司政策。
    CreditLimitUpToDateTxt 信用额度是最新的。
  33. 将两个局部小数变量添加到 CallUpdateCreditLimit 函数,并将其命名为 CreditLimitCalculatedCreditLimitActual,二者的类型均为“小数”。

  34. 将以下代码添加到 CallUpdateCreditLimit 函数中:

    CreditLimitCalculated := Rec.CalculateCreditLimit();
    if CreditLimitCalculated = Rec."Credit Limit (LCY)" then begin
        Message(CreditLimitUpToDateTxt);
        exit;
    end;
    
    if GuiAllowed() then
        if not Confirm(AreYouSureQst, false, FieldCaption("Credit Limit (LCY)"),CreditLimitCalculated) then
            exit;
    
    CreditLimitActual := CreditLimitCalculated;
    Rec.UpdateCreditLimit(CreditLimitActual);
    if CreditLimitActual <> CreditLimitCalculated then
        Message(CreditLimitROundedTxt, CreditLimitActual);
    

    如果新信用额度与旧信用额度相同,则应用程序必须向用户发送通知。

  35. Customer 表扩展现在如以下代码块所示:

    tableextension 50400 Customer extends Customer
    {
        procedure UpdateCreditLimit(var NewCreditLimit: Decimal)
        begin
            NewCreditLimit := Round(NewCreditLimit, 10000);
            Rec.Validate("Credit Limit (LCY)", NewCreditLimit);
            Rec.Modify();
        end;
    
        procedure CalculateCreditLimit(): Decimal
        var
            Customer: Record Customer;
        begin
            Customer := Rec;
            Customer.SetRange("Date Filter", CalcDate('<-12M>', WorkDate()), WorkDate());
            Customer.CalcFields("Sales (LCY)", "Balance (LCY)");
            exit(Round(Customer."Sales (LCY)" * 0.5));
        end;
    }
    
  36. CustomerCard 页面扩展现在如以下代码块所示:

    pageextension 50400 CustomerCard extends "Customer Card"
    {
        layout
        {
            // Add changes to page layout here
        }
    
        actions
        {
            // Add changes to page actions here
            addafter("F&unctions")
            {
                action(UpdateCreditLimit)
                {
                    ApplicationArea = All;
                    Caption = 'Update Credit Limit';
                    Image = CalculateCost;
                    ToolTip = 'Update Credit Limit';
    
                    trigger OnAction()
                    begin
                        CallUpdateCreditLimit();
                    end;
                }
            }
        }
        var
            AreYouSureQst: Label 'Are you sure that you want to set the %1 to %2?',  Comment = '%1 is Credit Limit caption and %2 is the new Credit Limit value.' ;
            CreditLimitRoundedTxt: Label 'The credit limit was rounded to %1 to comply with company policies.',  Comment = '%1 is new Credit Limit value';
            CreditLimitUpToDateTxt: Label 'The credit limit is up to date.';
    
        local procedure CallUpdateCreditLimit()
        var
            CreditLimitCalculated, CreditLimitActual : Decimal;
        begin
            CreditLimitCalculated := Rec.CalculateCreditLimit();
            if CreditLimitCalculated = Rec."Credit Limit (LCY)" then begin
                Message(CreditLimitUpToDateTxt);
                exit;
            end;
    
            if GuiAllowed() then
                if not Confirm(AreYouSureQst, false, Rec.FieldCaption("Credit Limit (LCY)"), CreditLimitCalculated) then
                    exit;
    
            CreditLimitActual := CreditLimitCalculated;
            Rec.UpdateCreditLimit(CreditLimitActual);
            if CreditLimitActual <> CreditLimitCalculated then
                Message(CreditLimitROundedTxt, CreditLimitActual);
        end;
    }
    

    如果客户在过去 12 个月中没有销售历史记录,则信用额度必须重置为零。

  37. 打开 .vscode 文件夹中的 launch.json 文件。 将 startupObjectId 设置为 22,将 startupObjectType 设置为 Page

  38. 将扩展发布到沙盒。 选择视图 > 命令面板... (Ctrl+Shift+P)。

  39. 在搜索框中输入 AL: 发布(或者按 F5 键),然后从列表中选择命令。

  40. 验证 Microsoft Dynamics 365 Business Central 应用程序是否会启动以及 Customer List 页面是否会显示。

  41. 此时将打开一个随机客户卡。 在 Customer Card 页面中,在操作菜单的“功能”后面找到 Update Credit Limit 操作。

  42. 测试该操作。