Business Central (Part 26)

Neil HaddleyDecember 22, 2024

Integration Tables

In Dynamics 365 Business Central, an Integration Table is a specialized table used to facilitate the exchange of data between Business Central and external systems or services. These tables are often used in integration scenarios, such as connecting with Dynamics 365 Sales (CRM), Power Platform, or other third-party applications.

I clicked the Create AL Project button

I clicked the Create AL Project button

I updated the project name

I updated the project name

I entered DataverseIntegration

I entered DataverseIntegration

I selected the most recent platform

I selected the most recent platform

I selected the Microsoft cloud sandbox option

I selected the Microsoft cloud sandbox option

I clicked the Copy & Open button

I clicked the Copy & Open button

I pasted the code

I pasted the code

I selected Al: Download symbols

I selected Al: Download symbols

Symbols were downloaded

Symbols were downloaded

Initially the Develop Power Platform Environment was configured to access the Production Business Central Environment

Initially the Develop Power Platform Environment was configured to access the Production Business Central Environment

The Business Central AL project was configured to deploy to the Sandbox environment

The Business Central AL project was configured to deploy to the Sandbox environment

I clicked the Start Debugging menu option

I clicked the Start Debugging menu option

The AL code paused when the line 13 breakpoint was hit

The AL code paused when the line 13 breakpoint was hit

I clicked continue and the message was displayed

I clicked continue and the message was displayed

I deleted the HelloWorld.al file

I deleted the HelloWorld.al file

I navigated to the Azure portal to copy the Application (Client) Id

I navigated to the Azure portal to copy the Application (Client) Id

I navigated to an app running the Power Platform to copy the https://XXX.crm.dynamics.com url

I navigated to an app running the Power Platform to copy the https://XXX.crm.dynamics.com url

I ran the The AL Table Proxy Generator tool (altpgen.exe) to generate 6 files. AccountExt.al, ContactExt.al, Customer Order Line.al, Customer Order.al, TeamExt.al and UserExt.alI updated the object number in the generated AccountExt.al, Customer Order.al, TeamExt.al and UserExt.al files

I ran the The AL Table Proxy Generator tool (altpgen.exe) to generate 6 files. AccountExt.al, ContactExt.al, Customer Order Line.al, Customer Order.al, TeamExt.al and UserExt.alI updated the object number in the generated AccountExt.al, Customer Order.al, TeamExt.al and UserExt.al files

I ran the New AL File Wizard

I ran the New AL File Wizard

I selected the Page option

I selected the Page option

I entered list page details. I clicked the Next button

I entered list page details. I clicked the Next button

I selected 5 fields

I selected 5 fields

I deployed the AL code

I deployed the AL code

I clicked the magnifying glass menu item and entered Customer Orders

I clicked the magnifying glass menu item and entered Customer Orders

An error was generatedTable connection for table type CRM must be registered using RegisterTableConnection or cmdlet New-NAVTableConnection before it can be used.

An error was generatedTable connection for table type CRM must be registered using RegisterTableConnection or cmdlet New-NAVTableConnection before it can be used.

I added an OnInit() trigger

I added an OnInit() trigger

I navigated to the Customer Orders page again and received an error

I navigated to the Customer Orders page again and received an error

I ran the Dataverse Connection Setup wizard

I ran the Dataverse Connection Setup wizard

I accepted the conditions and clicked the Next button

I accepted the conditions and clicked the Next button

I selected the Develop Power Platform Environment

I selected the Develop Power Platform Environment

I clicked the Next button

I clicked the Next button

I clicked the Next button

I clicked the Next button

I clicked the Next button

I clicked the Next button

I clicked the Finish button

I clicked the Finish button

I clicked the Yes button

I clicked the Yes button

I clicked the magnifying glass menu item and entered Customer Orders

I clicked the magnifying glass menu item and entered Customer Orders

I received an error message. Business Central was unable to access the Dataverse Customer Orders table

I received an error message. Business Central was unable to access the Dataverse Customer Orders table

I reviewed the roles that the Business Central Integration Business Central t... application user had been assigned to

I reviewed the roles that the Business Central Integration Business Central t... application user had been assigned to

I updated the Business Central Dataverse Integration role

I updated the Business Central Dataverse Integration role

I selected the Customer Order table

I selected the Customer Order table

I clicked the Permission Settings option

I clicked the Permission Settings option

I selected Full Access and clicked the Save button

I selected Full Access and clicked the Save button

I selected the Customer Order Line table and clicked the Permission Settings option

I selected the Customer Order Line table and clicked the Permission Settings option

I selected Full Access and clicked the Save button

I selected Full Access and clicked the Save button

Any member of this role will now be able to access the Customer Order and Customer Order Line tables

Any member of this role will now be able to access the Customer Order and Customer Order Line tables

I selected the Customer Orders page

I selected the Customer Orders page

The Dataverse Customer Orders were displayed

The Dataverse Customer Orders were displayed

I ran the New AL File Wizard again

I ran the New AL File Wizard again

I selected the Table Extension option

I selected the Table Extension option

I wanted to create a Customer Order Extension

I wanted to create a Customer Order Extension

I added a flow field to the generated Customer Order Integration table using the Customer Order Extension file

I added a flow field to the generated Customer Order Integration table using the Customer Order Extension file

I updated the Customer Orders page to display the Account Name flow field rather than the GUID value

I updated the Customer Orders page to display the Account Name flow field rather than the GUID value

The Account column displayed the Account name

The Account column displayed the Account name

I updated the Customer Orders page to disable Insert, Modify and Delete and to enable RefreshOnActivate

I updated the Customer Orders page to disable Insert, Modify and Delete and to enable RefreshOnActivate

I ran the New AL File Wizard

I ran the New AL File Wizard

I ran the New AL File Wizard to create a Card page

I ran the New AL File Wizard to create a Card page

I selected the fields I wanted to display

I selected the fields I wanted to display

I added an OnDrillDown() trigger to the Customer Order's Name field

I added an OnDrillDown() trigger to the Customer Order's Name field

I clicked on a Customer Order

I clicked on a Customer Order

The Customer Order Card was displayed

The Customer Order Card was displayed

I added a DataCaptionFields value to the Customer Order (Extension)

I added a DataCaptionFields value to the Customer Order (Extension)

I reviewed the updated Card page

I reviewed the updated Card page

I added entity dyn365bc_Item_v2_0. I need to add this entity to ensure that the hadd_Item field is added to the generated Customer Order Lines Integration table.

I added entity dyn365bc_Item_v2_0. I need to add this entity to ensure that the hadd_Item field is added to the generated Customer Order Lines Integration table.

I updated the object number

I updated the object number

I added a Customer Order Lines ListPart

I added a Customer Order Lines ListPart

I added Name, Item (GUID) and Quantity fields to the ListPart

I added Name, Item (GUID) and Quantity fields to the ListPart

Notice that hadd_Item is a GUID

Notice that hadd_Item is a GUID

I added the ListPart to the Customer Order Card

I added the ListPart to the Customer Order Card

The Customer Order Line details are displayed

The Customer Order Line details are displayed

I updated the Customer Order Lines ListPart to lookup Item details. I was able to use the hadd_Item GUID to lookup records in the Business Central Item table.

I updated the Customer Order Lines ListPart to lookup Item details. I was able to use the hadd_Item GUID to lookup records in the Business Central Item table.

Item details and a calculated Amount value are displayed

Item details and a calculated Amount value are displayed

I added a GetTotalAmount() procedure

I added a GetTotalAmount() procedure

The Total Amount field was displayed on the Customer Order Card

The Total Amount field was displayed on the Customer Order Card

TEXT
1page 50100 "Customer Orders"
2{
3    ApplicationArea = All;
4    Caption = 'Customer Orders';
5    PageType = List;
6    SourceTable = "CDS hadd_CustomerOrder";
7    UsageCategory = Lists;
8
9    InsertAllowed = false;
10    ModifyAllowed = false;
11    DeleteAllowed = false;
12
13    RefreshOnActivate = true;
14
15    layout
16    {
17        area(Content)
18        {
19            repeater(General)
20            {
21                field(hadd_Name; Rec.hadd_Name)
22                {
23                    ToolTip = 'Specifies the value of the Name field.', Comment = '%';
24
25                    trigger OnDrillDown()
26                    var
27                        CustomerOrderPage: Page "Customer Order";
28                        CustomerOrder: Record "CDS hadd_CustomerOrder";
29                    begin
30                        if CustomerOrder.Get(Rec.hadd_CustomerOrderId) then begin
31                            CustomerOrder.SystemId := Rec.hadd_CustomerOrderId;
32                            CustomerOrderPage.SetRecord(CustomerOrder);
33                            CustomerOrderPage.Run();
34                        end;
35                    end;
36                }
37                field("Account Name"; Rec."Account Name")
38                {
39                    ToolTip = 'Specifies the value of the Account field.', Comment = '%';
40                }
41                field(hadd_RequestedDeliveryDate; Rec.hadd_RequestedDeliveryDate)
42                {
43                    ToolTip = 'Specifies the value of the Requested Delivery Date field.', Comment = '%';
44                }
45                field(statecode; Rec.statecode)
46                {
47                    ToolTip = 'Specifies the value of the Status field.', Comment = '%';
48                }
49                field(statuscode; Rec.statuscode)
50                {
51                    ToolTip = 'Specifies the value of the Status Reason field.', Comment = '%';
52                }
53            }
54        }
55    }
56
57    trigger OnInit()
58    begin
59        Codeunit.Run(Codeunit::"CRM Integration Management");
60    end;
61
62}

Tab-Ext50105.CustomerOrderExt.al

TEXT
1tableextension 50105 "Customer Order Ext" extends "CDS hadd_CustomerOrder"
2{
3    DataCaptionFields = hadd_Name, "Account Name";
4
5    fields
6    {
7        field(50100; "Account Name"; Text[160])
8        {
9            Caption = 'Account';
10            FieldClass = FlowField;
11            CalcFormula = lookup("CRM Account".Name where(AccountId = field(hadd_Account)));
12        }
13    }
14}

Pag50102.CustomerOrderLines.al

TEXT
1page 50102 "Customer Order Lines"
2{
3    ApplicationArea = All;
4    Caption = 'Customer Order Lines';
5    PageType = ListPart;
6    SourceTable = "CDS hadd_CustomerOrderLine";
7
8    layout
9    {
10        area(Content)
11        {
12            repeater(General)
13            {
14                field(hadd_Name; Rec.hadd_Name)
15                {
16                    ToolTip = 'Specifies the value of the Name field.', Comment = '%';
17                }
18                /*field(hadd_Item; Rec.hadd_Item)
19                {
20                    ToolTip = 'Specifies the value of the Item field.', Comment = '%';
21                }*/
22                field(ItemNo; GetItemNo()) //Rec.wiise_ItemNo)
23                {
24                    Caption = 'No.';
25                }
26                field(ItemDescription; GetItemDescription())
27                {
28                    Caption = 'Description';
29                }
30                field(ItemCategoryCode; GetItemCategoryCode()) //Rec.wiise_ItemCategoryCode)
31                {
32                    Caption = 'Category';
33                }
34                field("Unit Price"; GetUnitPrice())
35                {
36                    Caption = 'Unit Price';
37                }
38                field(hadd_Quantity; Rec.hadd_Quantity)
39                {
40                    ToolTip = 'Specifies the value of the Quantity field.', Comment = '%';
41                }
42                field("Unit of Measure"; GetUnitOfMeasure())
43                {
44                    Caption = 'Unit of Measure';
45                }
46
47                field("Amount"; GetAmount())
48                {
49
50                }
51            }
52        }
53    }
54
55    local procedure GetItemDescription(): Text[100]
56    var
57        Item: Record Item;
58    begin
59        if Item.GetBySystemId(Rec.hadd_Item) then
60            exit(Item.Description)
61        else
62            exit('')
63    end;
64
65    local procedure GetItemNo(): Text[20]
66    var
67        Item: Record Item;
68    begin
69        if Item.GetBySystemId(Rec.hadd_Item) then
70            exit(Item."No.")
71        else
72            exit('')
73    end;
74
75    local procedure GetItemCategoryCode(): Code[20]
76    var
77        Item: Record Item;
78    begin
79        if Item.GetBySystemId(Rec.hadd_Item) then
80            exit(Item."Item Category Code")
81        else
82            exit('')
83    end;
84
85    local procedure GetUnitPrice(): Decimal
86    var
87        Item: Record Item;
88    begin
89        if Item.GetBySystemId(Rec.hadd_Item) then
90            exit(Item."Unit Price")
91        else
92            Error('Price not found');
93    end;
94
95    local procedure GetUnitOfMeasure(): Text[50]
96    var
97        Item: Record Item;
98        Unit: Record "Unit of Measure";
99    begin
100        if Item.GetBySystemId(Rec.hadd_Item) then begin
101            if Unit.GetBySystemId(Item."Unit of Measure Id") then
102                exit(Unit.Description)
103            else
104                exit('')
105        end;
106        exit('');
107    end;
108
109    local procedure GetAmount(): Decimal
110    var
111        Item: Record Item;
112    begin
113        if Item.GetBySystemId(Rec.hadd_Item) then
114            exit(Item."Unit Price" * Rec.hadd_Quantity)
115        else
116            Error('Price not found');
117    end;
118
119}

Pag50101.CustomerOrder.al

TEXT
1page 50101 "Customer Order"
2{
3    ApplicationArea = All;
4    Caption = 'Customer Order';
5    PageType = Card;
6    SourceTable = "CDS hadd_CustomerOrder";
7
8    layout
9    {
10        area(Content)
11        {
12            group(General)
13            {
14                Caption = 'General';
15
16                field(hadd_Name; Rec.hadd_Name)
17                {
18                    ToolTip = 'Specifies the value of the Name field.', Comment = '%';
19                }
20                field("Account Name"; Rec."Account Name")
21                {
22                    ToolTip = 'Specifies the value of the Account field.', Comment = '%';
23                }
24                field(hadd_RequestedDeliveryDate; Rec.hadd_RequestedDeliveryDate)
25                {
26                    ToolTip = 'Specifies the value of the Requested Delivery Date field.', Comment = '%';
27                }
28                field(statecode; Rec.statecode)
29                {
30                    ToolTip = 'Specifies the value of the Status field.', Comment = '%';
31                }
32                field(statuscode; Rec.statuscode)
33                {
34                    ToolTip = 'Specifies the value of the Status Reason field.', Comment = '%';
35                }
36
37                field("Total Amount"; GetTotalAmount())
38                {
39
40                }
41            }
42
43            part("Customer Order Lines"; "Customer Order Lines")
44            {
45                SubPageLink = "hadd_Order" = FIELD("hadd_CustomerOrderId");
46            }
47
48        }
49    }
50
51
52    local procedure GetTotalAmount(): Decimal
53    var
54        Item: Record Item;
55        OrderLine: Record "CDS hadd_CustomerOrderLine";
56        TotalAmount: Decimal;
57    begin
58        TotalAmount := 0;
59
60        OrderLine.SetRange(OrderLine.hadd_Order, Rec."hadd_CustomerOrderId");
61
62        if OrderLine.FindSet() then
63            repeat
64                if Item.GetBySystemId(OrderLine.hadd_Item) then
65                    TotalAmount += Item."Unit Price" * OrderLine.hadd_Quantity;
66            until OrderLine.Next() = 0;
67
68        exit(TotalAmount);
69    end;
70
71
72    trigger OnInit()
73    begin
74        Codeunit.Run(Codeunit::"CRM Integration Management");
75    end;
76
77}