Skip to main content

How to Add Financial Dimensions to Sales Orders in Dynamics 365 F&O X++


When creating sales orders through X++ in Dynamics 365 F&O, you may need to assign
financial dimensions programmatically. This is useful for integrations, automation, or custom processes where dimensions should be applied automatically.

In this example, we create a SalesTable record and attach multiple financial dimensions.

1. Build the Financial Dimension Set

First, create a helper method that collects dimension values and returns a DefaultDimension.

 private DimensionDefault addFinancialDimension(  
                                                                                OMOperatingUnitNumber _businessUnit,  
                                                                                OMOperatingUnitNumber _department,  
                                                                                OMOperatingUnitNumber _employee,  
                                                                                OMOperatingUnitNumber _lc,  
                                                                                OMOperatingUnitNumber _purpose,  
                                                                                OMOperatingUnitNumber _region,  
                                                                                OMOperatingUnitNumber _retailChannel)
 {  
   DimensionAttributeValueSetStorage dimensionAttributeValueSetStorage;  
   DimensionAttribute         dimensionAttribute;  
   DimensionAttributeValue      dimensionAttributeValue;  
   container dimensionNames = ['BusinessUnit', 'Department', 'Employee', 'LC', 'Purpose', 'Region', 'RetailChannel'];  
   container dimensionValues = [_businessUnit, _department, _employee,  _lc, _purpose, _region, _retailChannel];  
   
   int i;  
   dimensionAttributeValueSetStorage = new DimensionAttributeValueSetStorage();  
   
   for (i = 1; i <= conLen(dimensionNames); i++)  
   {  
         Name dimName = conPeek(dimensionNames, i);  
         str dimValue = conPeek(dimensionValues, i);  
         if (!dimValue)  
         continue; // Skip empty values  
         dimensionAttribute = DimensionAttribute::findByName(dimName);  
         if (!dimensionAttribute)  
               throw error(strFmt("Financial dimension %1 not found.", dimName));  
       
         dimensionAttributeValue =  DimensionAttributeValue::findByDimensionAttributeAndValue(  
         dimensionAttribute,  
         dimValue,  
         false,  
         true);  
         
         if (!dimensionAttributeValue)  
                   throw error(strFmt("Value %1 not found for dimension %2.", dimValue, dimName));  
       
         dimensionAttributeValueSetStorage.addItem(dimensionAttributeValue);  
   }  
       return dimensionAttributeValueSetStorage.save();  
 }  

This method loops through each dimension, finds the corresponding value in the system, and builds a DefaultDimension that can be assigned to transactions.

2. Create the Sales Order

Now we create a sales order and apply the dimensions.

 static void CreateSalesOrderWithFinancialDimensions(Args _args)  
 {  
       SalesTable salesTable;  
       DimensionDefault defaultDimension;  
       ttsbegin;  
       defaultDimension = this.getFinancialDimension(  
                                                                                     "001",  
                                                                                     "022",  
                                                                                     "EMP01",  
                                                                                     "LC01",  
                                                                                     "Sales",  
                                                                                     "NORTH",  
                                                                                     "ONLINE"  
                                                                                     );  
       salesTable.clear();  
       salesTable.initValue();  
       salesTable.SalesId = NumberSeq::newGetNum(SalesParameters::numRefSalesId()).num();  
       salesTable.CustAccount = "US-001";  
       salesTable.initFromCustTable();  
       salesTable.DefaultDimension = defaultDimension;  
       salesTable.insert();  
       ttscommit;  
 }  

Result

The sales order is created with all required financial dimensions automatically assigned, ensuring consistent financial reporting and reducing manual work. This approach is commonly used in customizations and integrations within Dynamics 365 Finance and Operations.

Popular posts from this blog

Consuming an External REST API in Dynamics 365 Finance & Operations (X++) and Saving Data into a Custom Table

  Introduction In this blog, I will explain how I consumed an online REST API in Microsoft Dynamics 365 Finance & Operations (D365 FO) using X++ and CLR Interop , deserialized the JSON response using Data Contract classes , and finally stored the data in a custom table . This is a common real-world integration scenario where external systems expose data via REST APIs and D365 FO needs to consume and persist that data. For this demo, I used the following public REST API : API URL: https://api.restful-api.dev/objects Solution Overview The solution consists of four X++ classes : MZNFRConsumeRestAPI – Main logic class (API call, deserialization, DB insert) MZNFRConsumeRestAPIParentContract – Parent contract (wraps JSON list) MZNFRConsumeRestAPIHeaderContract – Header contract (id, name) MZNFRConsumeRestAPILinesContract – Child contract (nested data node) 📌 Class Structure Diagram API Response Structure The API returns a JSON array like this: [ { ...

How to Create a Custom Data Entity in Dynamics 365 Finance and Operations

  Creating a Data Entity in Dynamics 365 Finance and Operations (D365FO) is essential for enabling data import/export, integrations, and public APIs. In this blog, we’ll walk through both the basic shortcut method and the advanced method for creating a custom Data Entity, using a table named MZNFRCustomTable as our example. 🧩 Step 1: Create a Custom Table Start by creating a new table in your project. Go to Solution Explorer → Right-click your project → Add New Item Select Table under FinanceOperations > Data Model Name it MZNFRCustomTable 🧱 Step 2: Add Fields to Your Table Define the fields you need in your table. For example: CustomerAccount CustomerName Currency PaymentNote Balance  Step 3: Shortcut Method – Create Data Entity via Addins Right-click on your table → Addins → Create Data Entity This method is quick but limited in customization. ❗ Common Error If you haven’t created an index, you’ll get this error: "The natural key for the table MZNFRCusto...

Modified Field Method in X++

  In Dynamics 365 Finance and Operations, user experience is everything. If a user enters an ItemId , they shouldn't have to manually type the ItemName . We can automate this using the modifiedField override on the table level. The ModifiedField  method is a kernel method that triggers after a field's value has been changed. It's the perfect place to put logic for fetching related data or resetting dependent fields. The Implementation On your custom table MNZFRSalesLine , you will override the  ModifiedField  method. We use a switch  statement on the _fieldId parameter to ensure our code only runs when the ItemId is the field being touched. public void modifiedField(FieldId _fieldId) { super(_fieldId); switch (_fieldId) { case fieldNum(MNZFRSalesLine, ItemId): if (this.ItemId) { // Fetch the Item Name using the InventTable find method // inventTable.itemName() is a common helper method ...