### AL HttpClient Example: Basic GET Request Source: https://github.com/microsoft/al/blob/master/News.md Demonstrates a basic GET request using the HttpClient data type in AL. Ensure AllowHttpClientRequests is enabled in your AL project settings. ```al local procedure GetRequest(Url: Text) var HttpClient: HttpClient; HttpResponseMessage: HttpResponseMessage; Content: Text; begin // Send GET request if HttpClient.Get(Url, HttpResponseMessage) then begin // Check response status if HttpResponseMessage.IsSuccessStatusCode() then begin // Read response content Content := HttpResponseMessage.Content().ReadAsText(); Message('Response: %1', Content); end else begin // Handle unsuccessful status code Error('Request failed with status code: %1', HttpResponseMessage.StatusCode()); end; end else begin // Handle network or other request errors Error('An error occurred during the request.'); end; end; ``` -------------------------------- ### AL HttpClient Example: Uploading a Binary File using multipart/form-data Source: https://github.com/microsoft/al/blob/master/News.md Demonstrates uploading a binary file using multipart/form-data with HttpClient.Post. This is suitable for non-textual file uploads. ```al local procedure UploadBinaryFile(Url: Text; FilePath: Text) var HttpClient: HttpClient; HttpResponseMessage: HttpResponseMessage; BinaryContent: BinaryContent; begin // Create binary content from file BinaryContent.Create(FilePath); BinaryContent.Headers.Add('Content-Disposition', 'form-data; name="file"; filename="' + FilePath + '"'); BinaryContent.Headers.Add('Content-Type', 'application/octet-stream'); // Send POST request with binary file content if HttpClient.Post(Url, BinaryContent, HttpResponseMessage) then begin // Check response status if HttpResponseMessage.IsSuccessStatusCode() then begin Message('Binary file upload successful.'); end else begin // Handle unsuccessful status code Error('Binary file upload failed with status code: %1', HttpResponseMessage.StatusCode()); end; end else begin // Handle network or other request errors Error('An error occurred during the binary file upload.'); end; end; ``` -------------------------------- ### AL HttpClient Example: POST Request with JSON Source: https://github.com/microsoft/al/blob/master/News.md Shows how to send a POST request with JSON content using the HttpClient data type. Remember to set the 'Content-Type' header appropriately. ```al local procedure PostRequest(Url: Text; Payload: Text) var HttpClient: HttpClient; HttpResponseMessage: HttpResponseMessage; StringContent: TextContent; begin // Create JSON content StringContent.Create(Payload); StringContent.Headers.Add('Content-Type', 'application/json'); // Send POST request if HttpClient.Post(Url, StringContent, HttpResponseMessage) then begin // Check response status if HttpResponseMessage.IsSuccessStatusCode() then begin Message('POST request successful.'); end else begin // Handle unsuccessful status code Error('POST request failed with status code: %1', HttpResponseMessage.StatusCode()); end; end else begin // Handle network or other request errors Error('An error occurred during the POST request.'); end; end; ``` -------------------------------- ### AL HttpClient Example: Sending a PATCH Request Source: https://github.com/microsoft/al/blob/master/News.md Demonstrates how to send an HTTP PATCH request using the generic HttpClient.Send method, as there is no specific wrapper for PATCH. Ensure the correct HTTP method and content are specified. ```al local procedure PatchRequest(Url: Text; Payload: Text) var HttpClient: HttpClient; HttpRequestMessage: HttpRequestMessage; HttpResponseMessage: HttpResponseMessage; StringContent: TextContent; begin // Create content StringContent.Create(Payload); StringContent.Headers.Add('Content-Type', 'application/json'); // Set up HttpRequestMessage for PATCH HttpRequestMessage.Method('PATCH'); HttpRequestMessage.RequestUri(Url); HttpRequestMessage.SetContent(StringContent); // Send the request if HttpClient.Send(HttpRequestMessage, HttpResponseMessage) then begin // Check response status if HttpResponseMessage.IsSuccessStatusCode() then begin Message('PATCH request successful.'); end else begin // Handle unsuccessful status code Error('PATCH request failed with status code: %1', HttpResponseMessage.StatusCode()); end; end else begin // Handle network or other request errors Error('An error occurred during the PATCH request.'); end; end; ``` -------------------------------- ### Key-Value Lookup with Dictionary in AL Source: https://context7.com/microsoft/al/llms.txt Implement in-memory key-value stores using the Dictionary data type for O(1) lookups. This example adds character-to-animal mappings and retrieves an animal by its starting letter. ```al codeunit 50133 DictionaryCode { trigger OnRun() var Dict: Dictionary of [Char, Text]; begin Dict.Add('A', 'Alligator'); Dict.Add('B', 'Bear'); Dict.Add('C', 'Crocodile'); Dict.Add('D', 'Dog'); Dict.Add('E', 'Elephant'); Message('Animal starting with letter ''C'': ' + Dict.Get('C')); // Output: Animal starting with letter 'C': Crocodile end; } ``` -------------------------------- ### AL HttpClient Example: Uploading a Text File using multipart/form-data Source: https://github.com/microsoft/al/blob/master/News.md Illustrates how to upload a text file using multipart/form-data with the HttpClient.Post method. This is useful for sending form submissions or files. ```al local procedure UploadTextFile(Url: Text; FilePath: Text) var HttpClient: HttpClient; HttpResponseMessage: HttpResponseMessage; FileContent: TextContent; begin // Create content from text file FileContent.Create(FilePath); FileContent.Headers.Add('Content-Disposition', 'form-data; name="file"; filename="' + FilePath + '"'); FileContent.Headers.Add('Content-Type', 'text/plain'); // Send POST request with file content if HttpClient.Post(Url, FileContent, HttpResponseMessage) then begin // Check response status if HttpResponseMessage.IsSuccessStatusCode() then begin Message('Text file upload successful.'); end else begin // Handle unsuccessful status code Error('Text file upload failed with status code: %1', HttpResponseMessage.StatusCode()); end; end else begin // Handle network or other request errors Error('An error occurred during the text file upload.'); end; end; ``` -------------------------------- ### VS Code Snippet for Codeunit Source: https://context7.com/microsoft/al/llms.txt Example output of the 'tcodeunit' VS Code snippet, which generates a basic codeunit structure. Placeholders are used for rapid filling of object names and logic. ```al // Example output of tcodeunit snippet (filled placeholders) codeunit 50200 MyCodeunit { trigger OnRun() begin // business logic here end; var myInt: Integer; } ``` -------------------------------- ### Page Extension to Add Actions Source: https://context7.com/microsoft/al/llms.txt Modifies an existing Business Central page by adding new actions. This example adds a 'Show Greeting' action to the 'Customer Card' page that runs a specific codeunit. ```al pageextension 50112 CustomerCardExtension extends "Customer Card" { layout { // Add new fields or rearrange existing ones here } actions { addlast("&Customer") { action("Show Greeting") { RunObject = codeunit HelloWorld; // runs HelloWorld.OnRun against current record RunPageOnRec = true; Image = CheckDuplicates; Promoted = true; PromotedCategory = Category8; ApplicationArea = All; } } } } ``` -------------------------------- ### Define Table with MediaSet Field for Image Storage Source: https://context7.com/microsoft/al/llms.txt Use MediaSet to store images directly in the database, enabling client caching and async loading. This example defines a table with a MediaSet field and configures a field group for tile views. ```al table 73332333 Pictures { fields { field(1; Id; Integer) { AutoIncrement = true; } field(2; Picture; MediaSet) { } } fieldgroups { fieldgroup(Brick; Id, Picture) { } // enables tile/card layout } } ``` -------------------------------- ### Efficient String Concatenation with TextBuilder in AL Source: https://context7.com/microsoft/al/llms.txt Utilize TextBuilder for efficient string concatenation, especially when combining five or more strings or building text within loops. This example demonstrates appending lines and bold text, followed by a replacement. ```al codeunit 50128 MarkdownWriter { var Builder: TextBuilder; procedure AppendHeadingLine(Heading: Text) begin Builder.Append('# '); Builder.AppendLine(Heading); end; procedure AppendBold(s: Text) begin Builder.Append('**'); Builder.Append(s); Builder.Append('**'); end; procedure Replace(Old: Text; New: Text) begin Builder.Replace(Old, New); end; procedure ToText(): Text begin exit(Builder.ToText); end; } // Usage codeunit 50131 TextBuilderCode { trigger OnRun() var Writer: codeunit MarkdownWriter; begin Writer.AppendHeadingLine('Hello World'); // # Hello World Writer.AppendBold('What a beautiful day'); // **What a beautiful day** Writer.Replace('day', 'week'); // **What a beautiful week** Message(Writer.ToText()); end; } ``` -------------------------------- ### Subscribe to Table Events in AL Source: https://context7.com/microsoft/al/llms.txt Use the [EventSubscriber] attribute to subscribe to events published by base application objects. This example shows subscribing to 'OnAfterValidateEvent' for 'Post Code' on Customer and Vendor tables, and registering a service connection. ```al codeunit 50102 "Address Service" { // Fires after the Post Code field is validated on the Customer table (table 18) [EventSubscriber(ObjectType::Table, 18, 'OnAfterValidateEvent', 'Post Code', false, false)] procedure OnCustomerPostCodeValidate(var Rec: Record Customer; var xRec: Record Customer; currFieldNo: Integer) begin CreateAddressLookupNotification(Rec); end; // Fires after the Post Code field is validated on the Vendor table (table 23) [EventSubscriber(ObjectType::Table, 23, 'OnAfterValidateEvent', 'Post Code', false, false)] procedure OnVendorPostCodeValidate(var Rec: Record Vendor; var xRec: Record Vendor; CurrFieldNo: Integer) begin CreateAddressLookupNotification(Rec); end; // Registers this extension in the Service Connections page (table 1400) [EventSubscriber(ObjectType::Table, 1400, 'OnRegisterServiceConnection', '', false, false)] local procedure HandleAddressLookupServiceConnection(var serviceConnection: Record "Service Connection") var serviceConnectionSetup: Record "Service Connection Setup"; recRef: RecordRef; begin if not serviceConnectionSetup.Get then begin serviceConnectionSetup.Init; serviceConnectionSetup."Service URL" := 'https://api.getAddress.io/v2/uk'; serviceConnectionSetup.Insert; end; recRef.GetTable(serviceConnectionSetup); serviceConnection.Status := serviceConnection.Status::Enabled; if (serviceConnectionSetup."Service URL" = '') or (serviceConnectionSetup."API Key" = '') then serviceConnection.Status := serviceConnection.Status::Disabled; serviceConnection.InsertServiceConnection( serviceConnection, recRef.RecordId, 'Get Address Service Setup', '', Page::"Service Setup"); end; } ``` -------------------------------- ### Embed and Communicate with Control Add-in on AL Page Source: https://context7.com/microsoft/al/llms.txt Embed a control add-in using the 'usercontrol' keyword on an AL page and handle its events. This example shows embedding 'TestAddIn' and triggering its 'CallJavaScript' procedure from an action. ```al // Hosting page — embeds the control add-in and wires up AL↔JS communication page 50300 PageWithAddIn { ApplicationArea = All; layout { area(Content) { usercontrol(ControlName; TestAddIn) { // Handle the JS→AL callback event trigger Callback(i: integer; s: text; d: decimal; c: char) begin Message('Got from JS: %1, %2, %3, %4', i, s, d, c); end; } } } actions { area(Creation) { action(CallJavaScript) { trigger OnAction() begin // AL → JS: passes typed parameters to the JS procedure CurrPage.ControlName.CallJavaScript(5, 'hello from AL', 6.3, 'c'); end; } } } } ``` -------------------------------- ### Extend Standard Table with Custom Field in AL Source: https://context7.com/microsoft/al/llms.txt Use table extensions to add fields to existing tables without modifying the base table. This example adds a 'Preferred Language' field to the standard Customer table. ```al // Adds a custom field to the standard Customer table tableextension 50300 CustomerTableExt extends Customer { fields { field(50100; "Preferred Language"; Code[10]) { DataClassification = CustomerContent; Caption = 'Preferred Language'; } } keys { // Additional keys can be added here } } ``` -------------------------------- ### Implement Interface - Casual Greeting Source: https://context7.com/microsoft/al/llms.txt Implements the 'IGreetingProvider' interface with a casual greeting. This codeunit provides the 'GetGreeting' procedure, fulfilling the contract defined by the interface. ```al codeunit 50151 CasualGreeting implements IGreetingProvider { procedure GetGreeting(): Text begin exit('Hey there!'); end; } ``` -------------------------------- ### Implement Interface - Formal Greeting Source: https://context7.com/microsoft/al/llms.txt Implements the 'IGreetingProvider' interface with a formal greeting. This codeunit provides the 'GetGreeting' procedure as required by the interface contract. ```al codeunit 50150 FormalGreeting implements IGreetingProvider { procedure GetGreeting(): Text begin exit('Good day, valued customer.'); end; } ``` -------------------------------- ### app.json - Extension Manifest Configuration Source: https://context7.com/microsoft/al/llms.txt Defines the identity, versioning, platform requirements, and object ID range for an AL extension. Ensure all fields are correctly populated for deployment. ```json { "id": "a7a49c61-7712-400a-9fc5-bc35f8e02aa0", "name": "Hello World", "publisher": "Microsoft", "brief": "Greet customers in multiple languages.", "description": "Demonstrates a minimal AL extension with codeunit and page extension.", "version": "1.0.0.0", "platform": "11.0.0.0", "application": "11.0.0.0", "idRange": { "from": 50100, "to": 50149 }, "dependencies": [], "screenshots": [], "capabilities": [], "privacyStatement": "", "EULA": "", "help": "", "url": "" } ``` -------------------------------- ### Build XML Documents with XmlDocument in AL Source: https://context7.com/microsoft/al/llms.txt Construct XML documents using XmlDocument, XmlElement, and XmlText. The Format function outputs the XML string, including namespaces and attributes. ```al codeunit 50132XmlCode { trigger OnRun() var Document: XmlDocument; begin Document := CreateBooks(); Message(Format(Document)); // Output: ... end; local procedure CreateBooks():XmlDocument var Document: XmlDocument; begin Document.Add( XmlElement.Create('books', 'http://www.contoso.com/books', CreateBook('Pride And Prejudice', 24.95, 'novel', '1-861001-57-8'), CreateBook('The Handmaid''s Tale', 29.95, 'novel', '1-861002-30-1'))); exit(Document); end; local procedure CreateBook(Title: Text; Price: Decimal; Genre: Text; ISBN: Text) Element: XmlElement begin Element := XmlElement.Create('book', XmlElement.Create('title', XmlText.Create(Title)), XmlElement.Create('price', XmlText.Create(Format(Price)))); Element.Attributes.Set('genre', Genre); Element.Attributes.Set('ISBN', ISBN); end; } ``` -------------------------------- ### Connect to Service and Fetch Addresses using HttpClient Source: https://context7.com/microsoft/al/llms.txt Fetches UK addresses from the getAddress.io REST API by postcode. Ensure 'AllowHttpClientRequests' is enabled and check 'IsSuccessStatusCode' before reading the response. ```AL local procedure ConnectToServiceAndFillBuffer(postCode: Code[20]; var addresses: JsonArray): Boolean var serviceConnectionSetup: Record "Service Connection Setup"; httpClient: HttpClient; httpResponse: HttpResponseMessage; tempBlob: Record TempBlob temporary; contentInStream: InStream; jsonResponse: JsonToken; addressesToken: JsonToken; begin if not serviceConnectionSetup.Get then exit(false); if (serviceConnectionSetup."Service URL" = '') or (serviceConnectionSetup."API Key" = '') then exit(false); // GET https://api.getAddress.io/v2/uk/SW1A2AA?api-key= if not httpClient.Get( serviceConnectionSetup."Service URL" + '/' + DelChr(postCode, '=') + '?api-key=' + serviceConnectionSetup."API Key", httpResponse) then Error('Failed to contact the address endpoint.'); if not httpResponse.IsSuccessStatusCode then exit(false); tempBlob.Init; tempBlob.Blob.CreateInStream(contentInStream); httpResponse.Content.ReadAs(contentInStream); jsonResponse.ReadFrom(contentInStream); if not jsonResponse.SelectToken('Addresses', addressesToken) then exit(false); addresses := addressesToken.AsArray(); exit(addresses.Count <> 0); end; ``` -------------------------------- ### Define Interface for Contract Source: https://context7.com/microsoft/al/llms.txt Defines an interface 'IGreetingProvider' that specifies a contract for greeting providers. Any codeunit implementing this interface must provide the 'GetGreeting' procedure. ```al interface IGreetingProvider { procedure GetGreeting(): Text; } ``` -------------------------------- ### Define Report with Dataset and Rendering Source: https://context7.com/microsoft/al/llms.txt Defines a report 'CustomerListReport' that includes a dataset for customer information and specifies an Excel layout for rendering. The 'DefaultRenderingLayout' property sets the primary output format. ```al report 50100 CustomerListReport { UsageCategory = ReportsAndAnalysis; ApplicationArea = All; DefaultRenderingLayout = ExcelLayout; dataset { dataitem(Customer; Customer) { column(CustomerNo; "No.") { } column(CustomerName; Name) { } column(Balance; "Balance (LCY)") { } } } requestpage { AboutTitle = 'Customer List Report'; AboutText = 'Lists all customers with their current balance.'; layout { area(Content) { group(Filters) { } } } } rendering { layout(ExcelLayout) { Type = Excel; LayoutFile = 'CustomerList.xlsx'; } } } ``` -------------------------------- ### Codeunit to Run Business Logic Against Table Record Source: https://context7.com/microsoft/al/llms.txt This codeunit is configured to run against the Customer table. Its OnRun trigger displays a random greeting along with the customer's name. ```al codeunit 70051001 HelloWorld { TableNo = Customer; trigger OnRun() var HelloText : Codeunit GreetingsManagement; begin // Displays e.g. "Danish: Hej verden, Fabrikam Inc." Message('%1, %2', HelloText.GetRandomGreeting(), Rec.Name); end; } ``` -------------------------------- ### Consume and Serialize Query Results to JSON in AL Source: https://context7.com/microsoft/al/llms.txt This procedure demonstrates how to consume a query, iterate through its results, and serialize them into a JsonArray. It opens the query, reads each record, and adds data to a JsonObject. ```al // Consuming the query and serialising results to a JsonArray local procedure CustomersPerCountryToJson() Result: JsonArray var CustomersQuery: query CustomersPerCountryQuery; JObject: JsonObject; begin CustomersQuery.Open(); while CustomersQuery.Read() do begin JObject.Add('code', CustomersQuery.CountryRegionCode); JObject.Add('value', CustomersQuery.CustomerCount); Result.Add(JObject); end; // Result = [{"code":"GB","value":42},{"code":"US","value":17},...] end; ``` -------------------------------- ### Codeunit for Localized Greetings Source: https://context7.com/microsoft/al/llms.txt Encapsulates reusable procedures for business logic. This codeunit provides a random localized greeting and is designed to be called from other AL objects. ```al codeunit 50110 GreetingsManagement { // Returns one of 38 localised "Hello World" strings at random procedure GetRandomGreeting() : Text begin Randomize; exit(GetHelloWorldText(Random(38))); end; local procedure GetHelloWorldText(GreetingNo : Integer) : Text begin case GreetingNo of 1: exit('Arabic: مرحبا بالعالم'); 9: exit('Danish: Hej verden'); 15: exit('French: Bonjour le monde'); 19: exit('German: Hallo Welt'); 28: exit('Español: Hola Mundo!'); else exit('Hello, World'); end; end; } ``` -------------------------------- ### Create Address Lookup Notification with Action Source: https://context7.com/microsoft/al/llms.txt Builds and sends a non-intrusive notification with an action button to look up addresses online. The action calls a specified codeunit procedure with embedded data. ```AL procedure CreateAddressLookupNotification(recVariant: Variant) var serviceConnectionSetup: Record "Service Connection Setup"; dataTypeManagement: Codeunit "Data Type Management"; addressNotification: Notification; recRef: RecordRef; postCodeFieldRef: FieldRef; begin dataTypeManagement.GetRecordRef(recVariant, recRef); postCodeFieldRef := recRef.Field(91); // Post Code field if not serviceConnectionSetup.Get then exit; if (serviceConnectionSetup."Service URL" = '') or (serviceConnectionSetup."API Key" = '') then exit; // Build and send notification with an action button addressNotification.Message := 'Would you like to look for addresses on this post code online?'; addressNotification.SetData('recID', Format(recRef.RecordId)); addressNotification.SetData('postCode', Format(postCodeFieldRef.Value)); addressNotification.AddAction( 'Yes, please', Codeunit::"Address Service", 'LookupAddresses'); // Calls Address Service.LookupAddresses(notification) addressNotification.Send; end; ``` -------------------------------- ### Upload File to MediaSet Field Source: https://context7.com/microsoft/al/llms.txt This codeunit uploads a file from the client into a MediaSet field. It uses File.UploadIntoStream to open a file picker and then imports the stream into the MediaSet. ```al codeunit 70000044 UploadPicture { trigger OnRun() var fileContent: InStream; filename: Text; picturesTable: Record Pictures; begin // Opens a file-picker dialog on the client side File.UploadIntoStream( 'Select a picture to upload', 'c:\', 'All files (*.*)|*.*', filename, fileContent); picturesTable.Init(); picturesTable.Picture.ImportStream(fileContent, filename); picturesTable.Insert(true); // Record is now stored with the image in the database end; } ``` -------------------------------- ### Customer Table Definition Source: https://github.com/microsoft/al/blob/master/highlightjs_al/test/default.txt Defines a base 'Customer' table with internal access and a primary key field 'P K'. This serves as a foundation for further extensions. ```al table 50100 Customer { Access = Internal; TableType = Normal; fields { field(1;"P K"; Integer) { } } } ``` -------------------------------- ### Define API Page for Data Access in AL Source: https://context7.com/microsoft/al/llms.txt This snippet defines an API page for exposing data. It includes essential API properties like Publisher, Group, Version, EntityName, and EntitySetName. The SourceTable property links it to the Item table. ```al // API page snippet — prefix: tpage (select "Page of type API") page 50400 ItemsAPI { PageType = API; Caption = 'items'; APIPublisher = 'myPublisher'; APIGroup = 'myGroup'; APIVersion = 'v1.0'; EntityName = 'item'; EntitySetName = 'items'; SourceTable = Item; DelayedInsert = true; layout { area(Content) { repeater(GroupName) { field(itemNo; "No.") { Caption = 'itemNo'; } field(description; Description) { Caption = 'description'; } } } } } ``` -------------------------------- ### Define PermissionSet for Extension Source: https://context7.com/microsoft/al/llms.txt Declares the minimum permissions required for an extension. This 'My Extension - Basic' permission set includes table data, table, page, and codeunit access, and inherits 'D365 BASIC' permissions. ```al permissionset 50100 "My Extension - Basic" { Assignable = true; IncludedPermissionSets = "D365 BASIC"; Permissions = tabledata Address = RIMD, table Address = X, page Addresses = X, codeunit "Address Service" = X; } ``` -------------------------------- ### AdjustForLoyalty Source: https://github.com/microsoft/al/blob/master/highlightjs_al/test/default.txt Adjusts a Sales Order by applying a discount based on the customer's loyalty level. It retrieves the customer's loyalty information and calculates the applicable discount. ```APIDOC ## AdjustForLoyalty ### Description Adjusts a Sales Order with loyalty level. This procedure takes a Sales Header record, retrieves the associated customer's loyalty information, calculates the discount, and applies it to the sales order. ### Method Signature `procedure AdjustForLoyalty(var SalesHeader: record "Sales Header"): Integer;` ### Parameters - **SalesHeader** (record "Sales Header") - Required - The Sales Header record to adjust based on Customer Loyalty. ### Returns - Integer - The result of the adjustment operation (details not specified in source). ### Internal Procedures Called - `ApplyDiscount(SalesHeader: record "Sales Header"; Discount: Decimal)` ``` -------------------------------- ### Define List Page for UI in AL Source: https://context7.com/microsoft/al/llms.txt This snippet defines a List page to display data, using a repeater for the layout. The PageType is set to 'List' and it's bound to a source table. ```al // List page showing uploaded pictures with a Brick field group layout page 70000005 ShowPictures { SourceTable = Pictures; PageType = List; layout { area(Content) { repeater(Pics) { field(Id; Id) { } field(PicSomething; Picture) { ShowCaption = false; } } } } } ``` -------------------------------- ### Define Full Custom Table with Triggers in AL Source: https://context7.com/microsoft/al/llms.txt This snippet shows a full table definition including DataClassification and standard triggers (OnInsert, OnModify, OnDelete, OnRename). The DataClassification property is mandatory for GDPR compliance. ```al // Full table with triggers — snippet prefix: ttable table 50200 MyTable { DataClassification = CustomerContent; fields { field(1; MyField; Integer) { DataClassification = CustomerContent; } } keys { key(Key1; MyField) { Clustered = true; } } trigger OnInsert() begin end; trigger OnModify() begin end; trigger OnDelete() begin end; trigger OnRename() begin end; } ``` -------------------------------- ### Define Minimal Custom Table in AL Source: https://context7.com/microsoft/al/llms.txt Use this minimal table definition for storing simple lookup results. Ensure the DataClassification property is set for GDPR compliance. ```al // Minimal custom table for storing address lookup results table 50100 Address { Caption = 'Address'; fields { field(1; Address; Text[50]) { Caption = 'Address'; } field(2; Locality; Text[30]) { Caption = 'Locality'; } field(3; "Town/City"; Text[30]) { Caption = 'Town/City'; } field(4; County; Text[30]) { Caption = 'Country'; } } keys { key(PrimaryKey; Address) { Clustered = true; } } } ``` -------------------------------- ### Bug Report Code Snippet Placeholder Source: https://github.com/microsoft/al/blob/master/CONTRIBUTING.md When reporting a bug, include a code snippet that demonstrates the issue. This allows developers to easily reproduce and fix the problem. ```AL ``` AL code snippet that demonstrates the issue or a link to a code repository the developers can easily pull down to recreate the issue locally ``` ``` -------------------------------- ### Define Control Add-in Contract in AL Source: https://context7.com/microsoft/al/llms.txt Declare the JavaScript/HTML component's contract, including scripts, stylesheets, images, and procedures callable from AL (AL → JS) and events raised from JavaScript back to AL (JS → AL). ```al // controladdin declaration — defines the JS↔AL contract controladdin TestAddIn { Scripts = 'https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-debug.js', './js/main.js'; StartupScript = 'js/startup.js'; StyleSheets = 'css/skins.css'; Images = './images/logo.png'; RequestedHeight = 500; MinimumHeight = 500; VerticalShrink = false; HorizontalStretch = true; procedure CallJavaScript(i: integer; s: text; d: decimal; c: char); // AL → JS event Callback (i: integer; s: text; d: decimal; c: char); // JS → AL } ``` -------------------------------- ### Build and Parse JSON with JsonObject in AL Source: https://context7.com/microsoft/al/llms.txt Use JsonObject and JsonArray to construct JSON data structures in AL. The Format function converts the JsonObject to a string representation. ```al codeunit 50130 JsonCode { trigger OnRun() var JObject: JsonObject; begin JObject := CreateBooks(); Message(Format(JObject)); // Output: {"books":[{"title":"Pride And Prejudice","price":"24.95","genre":"novel","ISBN":"1-861001-57-8"},...]} end; local procedure CreateBooks() JObject: JsonObject var JArray: JsonArray; begin JArray.Add(CreateBook('Pride And Prejudice', 24.95, 'novel', '1-861001-57-8')); JArray.Add(CreateBook('The Handmaid''s Tale', 29.95, 'novel', '1-861002-30-1')); JArray.Add(CreateBook('Sense and Sensibility', 19.95, 'novel', '1-861001-45-3')); JObject.Add('books', JArray); end; local procedure CreateBook(Title: Text; Price: Decimal; Genre: Text; ISBN: Text) JObject: JsonObject begin JObject.Add('title', Title); JObject.Add('price', Format(Price)); JObject.Add('genre', Genre); JObject.Add('ISBN', ISBN); end; } ``` -------------------------------- ### Loyalty Customer Extension Source: https://github.com/microsoft/al/blob/master/highlightjs_al/test/default.txt Extends the 'Customer' table to include a 'Loyalty' field of type 'LoyaltyLevel'. This adds loyalty information to existing customer records. ```al tableextension 50100 LoyaltyCustomerExt extends Customer { fields { /// /// Customer loyalty. /// field(50100; Loyalty; enum LoyaltyLevel) { } } } ``` -------------------------------- ### Define Query for Aggregating Data in AL Source: https://context7.com/microsoft/al/llms.txt This query aggregates customer data by 'Country/Region Code' and counts the number of customers in each region. It uses the 'Count' method for aggregation. ```al // Counts customers grouped by Country/Region Code query 50201 CustomersPerCountryQuery { elements { dataitem(Customer; Customer) { column(CountryRegionCode; "Country/Region Code") { } column(CustomerCount) { Method = Count; } } } } ``` -------------------------------- ### Update Record Fields Using RecordRef and FieldRef Source: https://context7.com/microsoft/al/llms.txt Use this procedure to update specific address-related fields on any record using its RecordRef. Ensure the record has fields corresponding to the numbers 5, 7, 35, and 92. ```al // Updates address fields on any record that has fields 5, 7, 35, 91, 92 local procedure UpdateRecordWithAddressInformation(recRef: RecordRef; tempAddress: Record Address temporary) var fieldRef: FieldRef; begin fieldRef := recRef.Field(5); // Address fieldRef.Value := tempAddress.Address; fieldRef := recRef.Field(7); // City fieldRef.Value := tempAddress."Town/City"; fieldRef := recRef.Field(92); // County fieldRef.Value := tempAddress.County; fieldRef := recRef.Field(35); // Country/Region Code fieldRef.Value := 'GB'; recRef.Modify; end; ``` -------------------------------- ### Interface Definition Source: https://github.com/microsoft/al/blob/master/highlightjs_al/test/default.txt Defines an interface named 'ISuperGreat' which specifies a contract for a procedure named 'YesSir'. This interface requires a codeunit of type 'FooBar' as a parameter. ```al interface ISuperGreat { procedure YesSir("c in c": codeunit FooBar); } ``` -------------------------------- ### Loyalty Benefits Management Codeunit Source: https://github.com/microsoft/al/blob/master/highlightjs_al/test/default.txt This codeunit manages loyalty benefits, including adjusting sales orders based on customer loyalty levels and applying discounts. It defines procedures for loyalty-based adjustments and discount application. ```al codeunit 50100 "Loyalty Benefits Management" var Vendor: record Vendor; begin end; /// /// Adjust a Sales Order with loyalty level /// /// Sales Header to adjust based on Customer Loyalty procedure AdjustForLoyalty(var SalesHeader: record "Sales Header"): Integer var Customer: record Customer; LoyaltyBenefits: interfcace ILoyaltyBenefits; Discount: Decimal; begin Customer.Get(SalesHeader."Sell-to Customer No."); LoyaltyBenefits := Customer.Loyalty; Discount := 1; Discount := LoyaltyBenefits.GetDiscount(); ApplyDiscount(SalesHeader, Discount); end; /// /// Applies the Discount to the Sales Order /// /// Sales Order /// Discount to apply local procedure "Apply Discount"(SalesHeader: record "Sales Header"; Discount: Decimal) begin // TODO: Implement end; ```