Rewards Extension

Neil HaddleyAugust 30, 2023

Rewards Extension

The Microsoft Dynamics 365 Business Central Extension described here allows users to create a list of "Rewards" and to associate rewards with Business Central Customers.

I added the idRange needed for the Rewards extension

I added the idRange needed for the Rewards extension

Rewards table

I created a Rewards.al file. In the Rewards.al file I added code to created a Business Central "Reward" table, a Business Central "Reward Card" page and a Business Central "Reward List" page.

I navigated to http://bcserver/BC/?tenant=default&page=50102 to view the Reward table using the Reward List page

I navigated to http://bcserver/BC/?tenant=default&page=50102 to view the Reward table using the Reward List page

I added a Reward item

I added a Reward item

The reward item has been stored in the Reward Table

The reward item has been stored in the Reward Table

I added the Minimum Purchase field to the Reward List page

I added the Minimum Purchase field to the Reward List page

I added the Minimum Purchase field to the Reward Card page

I added the Minimum Purchase field to the Reward Card page

I added a Customer Ext (table extension) and a Customer Card Ext (card extension) to associate a Reward value with an Business Central Customer

I added a Customer Ext (table extension) and a Customer Card Ext (card extension) to associate a Reward value with an Business Central Customer

Documentation

I used Meta's codellama language model to create the AL code documentation.

LM Studio code llama instruct 7B

LM Studio code llama instruct 7B

code llama instruct 7B

Please explain this Business Central AL code

This code creates a new table called "Reward" with four fields: "Reward ID", "Description", "Discount Percentage", and "Minimum Purchase". The "Reward ID" field is the primary key of the table. The "Description" field can contain a string with up to 250 characters, the "Discount Percentage" field is a Decimal numeric value that represents the discount that will be applied for this reward, and the "Minimum Purchase" field is also a Decimal numeric value that represents the minimum purchase amount required to qualify for this reward.

The code also creates two pages: "Reward Card" and "Reward List". The "Reward Card" page is of type "Card" and will render as a card, while the "Reward List" page is of type "List" and will render as a list. The source table for both pages is the "Reward" table.

The "Reward Card" page has a layout that includes a group called "Reward" with four fields: "Reward ID", "Description", "Discount Percentage", and "Minimum Purchase". The "Reward ID" field is a text box that displays the value of the "Reward ID" field from the "Reward" table, while the other three fields are also text boxes that display the corresponding values.

The "Reward List" page has a layout that includes a repeater called "Rewards". The repeater contains four fields: "Reward ID", "Description", "Minimum Purchase", and "Discount Percentage". Each record in the "Reward" table will be displayed as a separate row in the list.

The code also includes a table extension called "Customer Ext" that extends the "Customer" table with an additional field called "Reward ID". The "Reward ID" field is set to have a table relation to the "Reward ID" field in the "Reward" table, and it is also set to validate the table relationship.

Finally, the code includes a page extension called "Customer Card Ext" that extends the "Customer Card" page with an additional text box called "Reward ID". The "Reward ID" text box displays the value of the "Reward ID" field from the "Customer" table and allows users to select a reward from a lookup window. The "Rewards" action is also added to the Navigation group, which will run the "Reward List" page when activated.

Rewards.al

TEXT
1table 50100 Reward
2{
3    DataClassification = ToBeClassified;
4
5
6    fields
7    {
8        // The "Reward ID" field represents the unique identifier
9        // of the reward and can contain up to 30 Code characters.
10        field(1; "Reward ID"; Code[30])
11        {
12            DataClassification = ToBeClassified;
13        }
14
15
16        // The "Description" field can contain a string
17        // with up to 250 characters.
18        field(2; Description; Text[250])
19        {
20            // This property specified that
21            // this field cannot be left empty.
22            NotBlank = true;
23        }
24
25
26        // The "Discount Percentage" field is a Decimal numeric value
27        // that represents the discount that will
28        // be applied for this reward.
29        field(3; "Discount Percentage"; Decimal)
30        {
31            // The "MinValue" property sets the minimum value for the "Discount Percentage"
32            // field.
33            MinValue = 0;
34
35
36            // The "MaxValue" property sets the maximum value for the "Discount Percentage"
37            // field.
38            MaxValue = 100;
39
40
41            // The "DecimalPlaces" property is set to 2 to display discount values with  
42            // exactly 2 decimals.
43            DecimalPlaces = 2;
44        }
45    }
46
47
48    keys
49    {
50        // The field "Reward ID" is used as the primary key of this table.
51        key(PK; "Reward ID")
52        {
53            // Create a clustered index from this key.
54            Clustered = true;
55        }
56    }
57}
58
59
60page 50101 "Reward Card"
61{
62    // The page will be of type "Card" and will render as a card.
63    PageType = Card;
64
65
66    // The page will be part of the "Tasks" group of search results.
67    UsageCategory = Tasks;
68
69
70    // The source table shows data from the "Reward" table.
71    SourceTable = Reward;
72
73
74    // The layout describes the visual parts on the page.
75    layout
76    {
77        area(content)
78        {
79            group(Reward)
80            {
81                field("Reward Id"; Rec."Reward ID")
82                {
83                    // ApplicationArea sets the application area that
84                    // applies to the page field and action controls.
85                    // Setting the property to All means that the control
86                    // will always appear in the user interface.
87                    ApplicationArea = All;
88                }
89
90
91                field(Description; Rec.Description)
92                {
93                    ApplicationArea = All;
94                }
95
96
97                field("Discount Percentage"; Rec."Discount Percentage")
98                {
99                    ApplicationArea = All;
100                }
101            }
102        }
103    }
104}
105
106
107page 50102 "Reward List"
108{
109    // Specify that this page will be a list page.
110    PageType = List;
111
112
113    // The page will be part of the "Lists" group of search results.
114    UsageCategory = Lists;
115
116
117    // The data of this page is taken from the "Reward" table.
118    SourceTable = Reward;
119
120
121    // The "CardPageId" is set to the Reward Card previously created.
122    // This will allow users to open records from the list in the "Reward Card" page.
123    CardPageId = "Reward Card";
124
125
126    layout
127    {
128        area(content)
129        {
130            repeater(Rewards)
131            {
132                field("Reward ID"; Rec."Reward ID")
133                {
134                    ApplicationArea = All;
135                    ToolTip = 'Specifies the level of reward that the customer has at this point.';
136                }
137
138
139                field(Description; Rec.Description)
140                {
141                    ApplicationArea = All;
142                }
143
144
145                field("Discount Percentage"; Rec."Discount Percentage")
146                {
147                    ApplicationArea = All;
148                }
149            }
150        }
151    }
152}

Rewards.al updated

TEXT
1table 50100 Reward
2{
3    DataClassification = ToBeClassified;
4
5
6    fields
7    {
8        // The "Reward ID" field represents the unique identifier
9        // of the reward and can contain up to 30 Code characters.
10        field(1; "Reward ID"; Code[30])
11        {
12            DataClassification = ToBeClassified;
13        }
14
15
16        // The "Description" field can contain a string
17        // with up to 250 characters.
18        field(2; Description; Text[250])
19        {
20            // This property specified that
21            // this field cannot be left empty.
22            NotBlank = true;
23        }
24
25
26        // The "Discount Percentage" field is a Decimal numeric value
27        // that represents the discount that will
28        // be applied for this reward.
29        field(3; "Discount Percentage"; Decimal)
30        {
31            // The "MinValue" property sets the minimum value for the "Discount Percentage"
32            // field.
33            MinValue = 0;
34
35
36            // The "MaxValue" property sets the maximum value for the "Discount Percentage"
37            // field.
38            MaxValue = 100;
39
40
41            // The "DecimalPlaces" property is set to 2 to display discount values with  
42            // exactly 2 decimals.
43            DecimalPlaces = 2;
44        }
45
46
47        field(4; "Minimum Purchase"; Decimal)
48        {
49            MinValue = 0;
50            DecimalPlaces = 2;
51        }
52
53
54    }
55
56
57    keys
58    {
59        // The field "Reward ID" is used as the primary key of this table.
60        key(PK; "Reward ID")
61        {
62            // Create a clustered index from this key.
63            Clustered = true;
64        }
65    }
66}
67
68
69page 50101 "Reward Card"
70{
71    // The page will be of type "Card" and will render as a card.
72    PageType = Card;
73
74
75    // The page will be part of the "Tasks" group of search results.
76    UsageCategory = Tasks;
77
78
79    // The source table shows data from the "Reward" table.
80    SourceTable = Reward;
81
82
83    // The layout describes the visual parts on the page.
84    layout
85    {
86        area(content)
87        {
88            group(Reward)
89            {
90                field("Reward Id"; Rec."Reward ID")
91                {
92                    // ApplicationArea sets the application area that
93                    // applies to the page field and action controls.
94                    // Setting the property to All means that the control
95                    // will always appear in the user interface.
96                    ApplicationArea = All;
97                }
98
99
100                field(Description; Rec.Description)
101                {
102                    ApplicationArea = All;
103                }
104
105
106                field("Minimum Purchase"; Rec."Minimum Purchase")
107                {
108                    ApplicationArea = All;
109                }
110
111
112                field("Discount Percentage"; Rec."Discount Percentage")
113                {
114                    ApplicationArea = All;
115                }
116            }
117        }
118    }
119}
120
121
122page 50102 "Reward List"
123{
124    // Specify that this page will be a list page.
125    PageType = List;
126
127
128    // The page will be part of the "Lists" group of search results.
129    UsageCategory = Lists;
130
131
132    // The data of this page is taken from the "Reward" table.
133    SourceTable = Reward;
134
135
136    // The "CardPageId" is set to the Reward Card previously created.
137    // This will allow users to open records from the list in the "Reward Card" page.
138    CardPageId = "Reward Card";
139
140
141    layout
142    {
143        area(content)
144        {
145            repeater(Rewards)
146            {
147                field("Reward ID"; Rec."Reward ID")
148                {
149                    ApplicationArea = All;
150                    ToolTip = 'Specifies the level of reward that the customer has at this point.';
151                }
152
153
154                field(Description; Rec.Description)
155                {
156                    ApplicationArea = All;
157                }
158
159
160                field("Minimum Purchase"; Rec."Minimum Purchase")
161                {
162                    ApplicationArea = All;
163                }
164
165
166                field("Discount Percentage"; Rec."Discount Percentage")
167                {
168                    ApplicationArea = All;
169                }
170            }
171        }
172    }
173}
174
175
176tableextension 50103 "Customer Ext" extends Customer
177{
178    fields
179    {
180        field(50100; "Reward ID"; Code[30])
181        {
182            // Set links to the "Reward ID" from the Reward table.
183            TableRelation = Reward."Reward ID";
184
185
186            // Set whether to validate a table relationship.
187            ValidateTableRelation = true;
188
189
190            // "OnValidate" trigger executes when data is entered in a field.
191            trigger OnValidate();
192            begin
193
194
195                // If the "Reward ID" changed and the new record is blocked, an error is thrown.
196                if (Rec."Reward ID" <> xRec."Reward ID") and
197                    (Rec.Blocked <> Blocked::" ") then begin
198                    Error('Cannot update the rewards status of a blocked customer.')
199                end;
200            end;
201        }
202    }
203}
204
205
206pageextension 50104 "Customer Card Ext" extends "Customer Card"
207{
208    layout
209    {
210        // The "addlast" construct adds the field control as the last control in the General
211        // group.
212        addlast(General)
213        {
214            field("Reward ID"; Rec."Reward ID")
215            {
216                ApplicationArea = All;
217
218
219                // Lookup property is used to provide a lookup window for
220                // a text box. It is set to true, because a lookup for
221                // the field is needed.
222                Lookup = true;
223            }
224        }
225    }
226
227
228    actions
229    {
230        // The "addfirst" construct will add the action as the first action
231        // in the Navigation group.
232        addfirst(Navigation)
233        {
234            action("Rewards")
235            {
236                ApplicationArea = All;
237
238
239                // "RunObject" sets the "Reward List" page as the object
240                // that will run when the action is activated.
241                RunObject = page "Reward List";
242            }
243        }
244    }
245}