<?xml version="1.0" encoding="UTF-8" standalone="no"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:georss="http://www.georss.org/georss" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-3112615091101096759</atom:id><lastBuildDate>Sat, 21 Feb 2026 13:02:41 +0000</lastBuildDate><category>d365fo</category><category>X++</category><category>Dynamics 365 Finance and Operations</category><category>ERP Systems</category><category>Data Management</category><category>API Integration</category><category>Add range on AOT query</category><category>Auto populate the values from QR string</category><category>D365FO Customization</category><category>Dimensions in separate column</category><category>How to do the customization in Warehouse management application.</category><category>How to send email in D365FO</category><category>Ignore error in D365Fo</category><category>LedgerDimensionFacade</category><category>Microsoft Dynamics</category><category>Postman</category><category>REST API</category><category>Warehouse management mobile device customization</category><category>X++ Programming</category><category>add range in view</category><category>custom range in view</category><category>$select</category><category>$top</category><category>AOT query range on createdDateTime</category><category>Add custom range on AOT Query in D365FO</category><category>Add dimensions to Excel templates</category><category>Add two column range on AOT Query</category><category>Add two column range on X++ Query</category><category>Automation</category><category>Batch Jobs</category><category>COC in D365FO forms</category><category>Computed column in D365FO</category><category>Create calculated column on view. x++ code for calculate date diffrence</category><category>Create offset ledger dimension using mainaccount id and defaultdimension in D365FO</category><category>Create table in email body in D365FO</category><category>Custom business event in D365FO</category><category>Customization</category><category>D365FO Development</category><category>Data Import</category><category>Database Integrity</category><category>Dependent Tasks</category><category>Deserialize JSON into Object</category><category>Dynamics 365
Finance and Operations</category><category>Export Package</category><category>Export SalesPackingSlip report</category><category>Find or create ledger dimension</category><category>Get all selected records</category><category>How  to  send Lasernet report PDF on email</category><category>How To Disable Country Specific Bank Validations ?</category><category>How do I deserialize JSON to an object?</category><category>How do you write a remittance advice email?</category><category>How to Add $filter</category><category>How to Create Multiselection Lookup in D365FO</category><category>How to access extension class method on data entity field property</category><category>How to add Personnel Number field on the data entity D365FO</category><category>How to apply custom range on AOT query</category><category>How to convert contract class to JSON</category><category>How to create computed column in D365FO</category><category>How to create field Id lookup in D365FO</category><category>How to create multiselection lookup in SSRS report dialog</category><category>How to mark the quantity in X++</category><category>How to post packing slip</category><category>How to send SSRS report on email</category><category>How to send standard SSRS report over email</category><category>How to serialize and deserialize JSON using C#</category><category>How to set background color for alternate row in SSRS report table D365FO</category><category>How to show default value for the field which is not part of group and returning more than one values</category><category>Import Package</category><category>Importing data through Data entities using X++</category><category>Inventory Management</category><category>LedgerDimensionFacade::getDefaultDimensionFromLedgerDimension</category><category>Manage International Bank Account Number (IBAN) account</category><category>Microsoft Dynamics
D365 Development</category><category>Microsoft Dynamics
Data Export</category><category>Microsoft Dynamics Customization</category><category>Multi selection</category><category>Multi selection lookup on form control</category><category>Number sequence in D365FO</category><category>Partial Product Receipt</category><category>Partition</category><category>Payment Advice</category><category>Post partial packing slip. how to post single line packing slip</category><category>Print management</category><category>Procurement Process</category><category>Project Hour Journal Creation and Invoice Posting using x++ code</category><category>Proposed vendor changes workflow</category><category>Purchase Order</category><category>Query expression in D365FO</category><category>RecId</category><category>RecVersion</category><category>SSRS report in PDF over email</category><category>SysLookupMultiSelectCtrl</category><category>Table Fields</category><category>Task Scheduling</category><category>Update tiles count from X++</category><category>Vendor amendment workflow</category><category>Way to email Payment Advice</category><category>What is vendor payment advice?</category><category>X++ Code</category><category>X++ code for range on createddateTime</category><category>X++ code to send packing slip pdf over email</category><category>add range of unbound control in query</category><category>auto click from x++ code</category><category>cannot be deleted while dependent Provisioned channel product attribute exist</category><category>create computed column using createdDateTime</category><category>create lookup on D365F&amp;O form</category><category>create multi select lookup in D365</category><category>create multi select lookup in ax 2012</category><category>cross-company=true and $orderby in in OData URL</category><category>deserialize JSON in x++</category><category>export contract class into JSON</category><category>get all selected records from datasource</category><category>get count from AOT Query in x++ code</category><category>get sql statement of your x++ query</category><category>get sql statement of your x++ query at runtime</category><category>getData()</category><category>if condition in computed column</category><category>list to JSON</category><category>lookup dimensions in D365FO excel add-in</category><category>lookup on form</category><category>modify email subject</category><category>multiselectionlookup</category><category>not creating project transactions</category><category>product receipt from x++ code</category><category>register purchase orders in D365FO</category><category>remove bank account number validation</category><category>select only records upto the last month.</category><category>show custom dimensions in D365FO in excel addin</category><category>update Tile count runtime.</category><category>vendor creation workflow</category><category>x++ code for create table in email body</category><category>x++ code for print packing slip journal</category><category>x++ code get Default dimensions from ledger dimensions in D365FO</category><category>x++ code to create ledger dimension using main account id and default dimension</category><category>x++ code to post packing slip</category><title>D365 Finance and Operations Technical blogs</title><description>Discover essential insights about D365 Finance and Operations (D365FO) through our user-friendly technical blog. Our content covers implementation, customization, troubleshooting, and key trends in D365FO. Stay informed about performance optimization, security updates, and X++ coding techniques. Learn efficient ways for data migration and workflow automation. Simplify your D365FO experience with our expert guidance. Your top resource for D365FO knowledge, designed for easy understanding.#Learn</description><link>https://d365fotechnicalblog.blogspot.com/</link><managingEditor>noreply@blogger.com (Vijay Yelmame)</managingEditor><generator>Blogger</generator><openSearch:totalResults>56</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><language>en-us</language><itunes:explicit>no</itunes:explicit><itunes:keywords>D365FO,D365,Finance,and,operation,Ax,X</itunes:keywords><itunes:summary>This blogs are for D365 FO Technical concepts.</itunes:summary><itunes:subtitle>D365 Technical finance and operations technical blogs</itunes:subtitle><itunes:category text="Technology"/><itunes:owner><itunes:email>noreply@blogger.com</itunes:email></itunes:owner><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-8806948080636001162</guid><pubDate>Mon, 12 May 2025 13:12:00 +0000</pubDate><atom:updated>2025-08-05T06:05:33.078-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">How to Create Multiselection Lookup in D365FO</category><title>How to Create Multiselection Lookup in D365FO</title><description>
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;&lt;/meta&gt;
    &lt;meta content="width=device-width, initial-scale=1.0" name="viewport"&gt;&lt;/meta&gt;
    &lt;title&gt;How to Create Multiselection Lookup in D365FO&lt;/title&gt;
    &lt;style&gt;
        pre {
            white-space: pre-wrap;       /* Since CSS 2.1 */
            white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
            white-space: -pre-wrap;      /* Opera 4-6 */
            white-space: -o-pre-wrap;    /* Opera 7 */
            word-wrap: break-word;       /* Internet Explorer 5.5+ */
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* Add shadow */
            padding: 10px;               /* Add padding */
            border-radius: 5px;          /* Add rounded corners */
            background-color: #f9f9f9;   /* Light background color */
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;How to Create Multiselection Lookup in D365FO&lt;/h1&gt;
    &lt;p&gt;In this blog post, we will walk through the steps to create a multiselection lookup in Dynamics 365 for Finance and Operations (D365FO). We will use a sample code to demonstrate the process. Also, you can refer to the standard class 'DemoMultiSelectionLookupUIBuilder'.&lt;/p&gt;
    
    &lt;h2&gt;Step 1: Create the Data Contract Class&lt;/h2&gt;
    &lt;p&gt;First, we need to create a data contract class. This class will hold the list of project IDs that we want to select.&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;
internal final class DemoMultiSelectionLookupContract implements SysOperationValidatable, SysOperationInitializable
{
    private List projIdList;

    [DataMemberAttribute("ProjectId"), 
    AifCollectionTypeAttribute("ProjectId", Types::String),
    SysOperationLabelAttribute(literalStr("@SYS103748")),
    SysOperationDisplayOrderAttribute('7')]
    public List parmProjIdList(List _listProjId = projIdList)
    {
        projIdList = _listProjId;
        return projIdList;
    }
    
    public void initialize()
    {

    }
}
    &lt;/code&gt;&lt;/pre&gt;

    &lt;h2&gt;Step 2: Create the UI Builder Class&lt;/h2&gt;
    &lt;p&gt;Next, we create a UI builder class to add the dialog field for the project ID selection.&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;
public final class DemoMultiSelectionLookupUIBuilder extends SysOperationAutomaticUIBuilder
{
    protected DialogField addDialogField(IdentifierName _methodName, Object _dataContract = this.dataContractObject())
    {
        DialogField dialogField;

        switch (_methodName)
        {
            case methodStr(DemoMultiSelectionLookupContract, parmProjIdList):
                projIdField = this.dialog().addField(extendedTypeStr(ProjId), "@SYS103748", "Select project id those invoice want to export");
                dialogField = projIdField;
                break;

            default:
                dialogField = super(_methodName, _dataContract);
                break;
        }

        return dialogField;
    }

    public void postRun()
    {
        DemoMultiSelectionLookupContract dataContract = this.dataContractObject() as DemoMultiSelectionLookupContract;
        container selectFieldSources = this.selectField();
        super();

        ctrlProjId = SysLookupMultiSelectCtrl::constructWithQueryRun(
            this.dialog().formRun(),
            projIdField.control(),
            new QueryRun(queryStr(ProjTable)),
            true,
            selectFieldSources);
    }

    public container selectField()
    {
        return [tableNum(ProjTable), fieldNum(ProjTable, ProjId)];
    }

   
}
    &lt;/code&gt;&lt;/pre&gt;

    &lt;h2&gt;Step 3: Create the Service Class&lt;/h2&gt;
    &lt;p&gt;Finally, we create a service class to handle the business logic for the multiselection lookup.&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;
internal final class DemoMultiSelectionLookupService extends SysOperationServiceBase
{
    System.Exception ex;
    internal void runExport(DemoMultiSelectionLookupContract _exportAttachmentsContract)
    {
        try
        {
            List projectList = _exportAttachmentsContract.parmProjIdList();
        }
        catch (ex)
        {
            this.logException(ex);
        }
    }
}
    &lt;/code&gt;&lt;/pre&gt;

    &lt;h2&gt;Step 4: Create the Controller Class&lt;/h2&gt;
    &lt;p&gt;Finally, we create a controller class to call the service class.&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;
public class DemoMultiSelectionLookupController extends SysOperationServiceController implements BatchRetryable
{
    public static void main(Args _args)
    {
        DemoMultiSelectionLookupController controller = DemoMultiSelectionLookupController::construct();
        controller.parmDialogCaption("@ApplicationFoundation:ExportAttachments");
        
        controller.startOperation();
    }

    public static DemoMultiSelectionLookupController construct(SysOperationExecutionMode _executionMode = SysOperationExecutionMode::Synchronous)
    {
        return new DemoMultiSelectionLookupController(
            classStr(DemoMultiSelectionLookupService),
            methodStr(DemoMultiSelectionLookupService, runExport),
            _executionMode);
    }

    [Hookable(false)]
    public final boolean isRetryable()
    {
        return false;
    }
}
    &lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;And that's it! You now have a multiselection lookup in D365FO. This example demonstrates how to create a data contract, UI builder, service class, and controller class to achieve this functionality.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2025/05/how-to-create-multiselection-lookup-in.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-7466966440393250447</guid><pubDate>Fri, 11 Apr 2025 12:08:00 +0000</pubDate><atom:updated>2025-04-11T06:06:17.857-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">How to show default value for the field which is not part of group and returning more than one values</category><title>How to show default value or first value for the field which is not part of group and returning more than one values</title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Grouping Data by Certain Fields and Handling Cases Where a Specific Field Returns More Than One Value in D365FO SSRS Reports&lt;/title&gt;
    &lt;style&gt;
        .highlight {
            background-color: #e0e0e0;
            padding: 10px;
            border-radius: 5px;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Grouping Data by Certain Fields and Handling Cases Where a Specific Field Returns More Than One Value in D365FO SSRS Reports&lt;/h1&gt;
    &lt;p&gt;When working with SQL Server Reporting Services (SSRS) in Dynamics 365 Finance and Operations (D365FO), you might encounter scenarios where you need to group data by certain fields and handle cases where a specific field, not part of the group, returns more than one value. In this blog post, we'll explore how to manage such scenarios by conditionally displaying default values for that field.&lt;/p&gt;
    
    &lt;h2&gt;Scenario&lt;/h2&gt;
    &lt;p&gt;Consider a report with the following fields:&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;Field 1&lt;/li&gt;
        &lt;li&gt;Field 2&lt;/li&gt;
        &lt;li&gt;Field 3&lt;/li&gt;
        &lt;li&gt;Field 4&lt;/li&gt;
    &lt;/ul&gt;
    &lt;p&gt;We want to group the data by certain fields: Field 2, Field 3, and Field 4. However, if a specific Field 1 that is not part of the group returns more than one value, in that case we want to display a default value, such as a blank or "Unknown".&lt;/p&gt;
    
    &lt;h2&gt;Solution&lt;/h2&gt;
    &lt;p&gt;To achieve this, we can use an SSRS expression to check if there are multiple values for the specific field within the group and conditionally display a default value.&lt;/p&gt;
    
    &lt;h3&gt;Expression for Blank Default Value&lt;/h3&gt;
    &lt;div class="highlight"&gt;
        &lt;pre&gt;&lt;code&gt;=IIF(CountDistinct(Fields!Field1.Value, "YourGroupName") &gt; 1, "", Fields!Field1.Value)&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
    
    &lt;h3&gt;Expression for "Unknown" Default Value&lt;/h3&gt;
    &lt;div class="highlight"&gt;
        &lt;pre&gt;&lt;code&gt;=IIF(CountDistinct(Fields!Field1.Value, "YourGroupName") &gt; 1, "Unknown", Fields!Field1.Value)&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
    
   &lt;h3&gt;Expression for FirstValue&lt;/h3&gt;
    &lt;div class="highlight"&gt;
        &lt;pre&gt;&lt;code&gt;=First(Fields!Field1.Value, "YourGroupName")&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  
    &lt;h2&gt;Conclusion&lt;/h2&gt;
    &lt;p&gt;By using these approaches, you can effectively manage the display of specific fields in your D365FO SSRS reports when dealing with multiple values within a group, ensuring that your report remains clear and easy to read.&lt;/p&gt;
    
    &lt;p&gt;We hope this solution helps you in your D365FO SSRS reporting tasks. If you have any questions or need further assistance, feel free to reach out!&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2025/04/how-to-show-default-value-for-field.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-2572390322766369560</guid><pubDate>Thu, 10 Apr 2025 06:18:00 +0000</pubDate><atom:updated>2025-04-09T23:37:16.562-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">$select</category><category domain="http://www.blogger.com/atom/ns#">$top</category><category domain="http://www.blogger.com/atom/ns#">cross-company=true and $orderby in in OData URL</category><category domain="http://www.blogger.com/atom/ns#">How to Add $filter</category><title>How to Add $filter, $top, $select, cross-company=true and $orderby in in OData URL</title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;How to Add $filter, $top, cross-company=true, and $select in OData URL&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            color: #333;
            background-color: #f4f4f4;
            margin: 0;
            padding: 20px;
        }
        h1 {
            color: #0056b3;
        }
        h2 {
            color: #007bff;
        }
        pre {
            background-color: #d4edda; /* Green background color */
            padding: 10px;
            border-radius: 5px;
            white-space: pre-wrap; /* Ensures long lines break within the pre element */
            word-break: break-all; /* Breaks long words to fit within the container */
        }
        code {
            color: #d63384;
        }
        p {
            margin-bottom: 15px;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;How to Add $filter, $top, $select, cross-company=true and $orderby in in OData URL&lt;/h1&gt;
    &lt;p&gt;OData URLs in Dynamics 365 Finance and Operations (D365FO) provide a flexible way to query data. In this blog post, we will demonstrate how to use the &lt;code&gt;$filter&lt;/code&gt;, &lt;code&gt;$top&lt;/code&gt;, &lt;code&gt;cross-company=true&lt;/code&gt;,&lt;code&gt;$select&lt;/code&gt; and &lt;code&gt;$orderby&lt;/code&gt;  query options to retrieve specific records based on certain criteria.&lt;/p&gt;
    
    &lt;h2&gt;Using $filter&lt;/h2&gt;
    &lt;p&gt;The &lt;code&gt;$filter&lt;/code&gt; query option allows you to specify criteria to filter the data returned by the OData service also you need to add "and" operator between 2 filter values and "&amp;" between 2 diffrent options ($filter, $orderby). Below is an example:&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;{{resource}}/data/PurchaseOrderHeadersV2?$filter=PurchaseOrderNumber eq 'PO12345' and dataAreaId eq 'USMF'&amp;Cross-company=true&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;This URL filters the &lt;code&gt;PurchaseOrderHeadersV2&lt;/code&gt; entity to only include records where &lt;code&gt;PurchaseOrderNumber&lt;/code&gt; is 'PO12345' and &lt;code&gt;dataAreaId&lt;/code&gt; is 'USMF', and includes data from all companies.&lt;/p&gt;
    
    &lt;h2&gt;Using $top&lt;/h2&gt;
    &lt;p&gt;The &lt;code&gt;$top&lt;/code&gt; query option specifies the maximum number of records to return in the response. It can be combined with other query options like &lt;code&gt;$filter&lt;/code&gt; and &lt;code&gt;$orderby&lt;/code&gt;. Below is an example:&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;{{resource}}/data/VendPackingSlipTransBiEntities?$top=2&amp;$filter=OrigPurchid eq 'PO12345' and dataAreaId eq 'USMF'&amp;Cross-company=true&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;This URL returns the top 2 records from the &lt;code&gt;VendPackingSlipTransBiEntities&lt;/code&gt; entity where &lt;code&gt;OrigPurchid&lt;/code&gt; is 'PO12345' and &lt;code&gt;dataAreaId&lt;/code&gt; is 'USMF', ordered by &lt;code&gt;DeliveryDate&lt;/code&gt; in descending order, and includes data from all companies.&lt;/p&gt;
    
    &lt;h2&gt;Using $select&lt;/h2&gt;
    &lt;p&gt;The &lt;code&gt;$select&lt;/code&gt; query option allows you to specify which properties to include in the response. This can help reduce the amount of data returned and improve performance. Below is an example:&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;{{resource}}/data/VendPackingSlipTransBiEntities?$select=dataAreaId,OrigPurchid,PackingSlipId&amp;$top=2&amp;$filter=OrigPurchid eq 'PO12345' and dataAreaId eq 'USMF'&amp;Cross-company=true&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;This URL returns only the &lt;code&gt;dataAreaId&lt;/code&gt;, &lt;code&gt;OrigPurchid&lt;/code&gt;, and &lt;code&gt;PackingSlipId&lt;/code&gt; properties from the &lt;code&gt;VendPackingSlipTransBiEntities&lt;/code&gt; entity where &lt;code&gt;OrigPurchid&lt;/code&gt; is 'PO12345' and &lt;code&gt;dataAreaId&lt;/code&gt; is 'USMF', and includes data from all companies.&lt;/p&gt;
    
    &lt;h2&gt;Using $orderby&lt;/h2&gt;
    &lt;p&gt;The &lt;code&gt;$orderby&lt;/code&gt; query option allows you to sort the data returned by the OData service based on specified properties. Below is an example:&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;{{resource}}/data/VendPackingSlipTransBiEntities?$top=2&amp;$filter=OrigPurchid eq 'PO12345' and dataAreaId eq 'USMF'&amp;$orderby=DeliveryDate desc&amp;Cross-company=true&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;This URL returns the top 2 records from the &lt;code&gt;VendPackingSlipTransBiEntities&lt;/code&gt; entity where &lt;code&gt;OrigPurchid&lt;/code&gt; is 'PO12345' and &lt;code&gt;dataAreaId&lt;/code&gt; is 'USMF', ordered by &lt;code&gt;DeliveryDate&lt;/code&gt; in descending order, and includes data from all companies.&lt;/p&gt;
    
    &lt;h2&gt;Conclusion&lt;/h2&gt;
    &lt;p&gt;Using OData URLs to query data in D365FO is a powerful and flexible method to retrieve the exact records you need. The &lt;code&gt;$filter&lt;/code&gt;, &lt;code&gt;$top&lt;/code&gt;, &lt;code&gt;cross-company=true&lt;/code&gt;, &lt;code&gt;$select&lt;/code&gt;, and &lt;code&gt;$orderby&lt;/code&gt; query options allow you to refine your queries and optimize data retrieval. By combining these options, you can efficiently manage and retrieve data to meet your specific requirements.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2025/04/how-to-add-filter-top-select-cross.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-8756700616556944502</guid><pubDate>Thu, 03 Apr 2025 08:30:00 +0000</pubDate><atom:updated>2025-04-03T01:45:43.159-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Project Hour Journal Creation and Invoice Posting using x++ code</category><title>Project Hour Journal Creation and Invoice Posting using x++ code</title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Project Hour Journal Creation and Invoice Posting&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
        }
        h1, h2, h3 {
            color: #333;
        }
        pre {
            background: #f4f4f4;
            border: 1px solid #ddd;
            padding: 10px;
            overflow-x: auto;
        }
        code {
            font-family: 'Courier New', Courier, monospace;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h2&gt;Project Hour Journal Creation, posting , Invoice proposal creation and Posting invoice&lt;/h2&gt;
   &lt;p&gt;&lt;/p&gt;
    &lt;h2&gt;Step-by-Step Guide&lt;/h2&gt;
&lt;p&gt;&lt;/p&gt;
    &lt;h3&gt;1. Creating the Project Hour Journal&lt;/h3&gt;
    &lt;p&gt;The first step is to create a project hour journal. This involves initializing the journal table and transaction data, setting various properties, and validating the entries before inserting them into the database.&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;
public journalId createJournal()
{
   
    ProjJournalTable jourTable;
    ProjJournalTableData jourTableData;
    ProjJournalTransData jourTransData;
    ProjJournalStatic jourStatic;
    ProjTable projtable;
    Qty qty;
    ProjLinePropertySetup projLinePropertySetup;
    TestSFIntegrationParameters TestSFIntegrationParameters = TestSFIntegrationParameters::find(); // Custom table.
    ProjLineProperty projLineProperty;
    ProjJournalTrans jourTrans;
    Amount totalAmount;
    JournalId journalId;

  
    select firstonly reverse projLinePropertySetup
        join projLineProperty
            where projLineProperty.LinePropertyId == projLinePropertySetup.LinePropertyId
            &amp;&amp; projLinePropertySetup.CategoryRelation == TestSFIntegrationParameters.RevenueCategory
            &amp;&amp; projLinePropertySetup.ProjCode == TableGroupAll::All;

    if (!projLineProperty.ToBeInvoiced)
    {
        throw error(strFmt("The chargeable line property is missing for the specified hour category '%1'.", TestSFIntegrationParameters.RevenueCategory));
    }

    jourTableData = JournalTableData::newTable(jourTable);
    jourTable.JournalId = jourTableData.nextJournalId();
    jourTable.JournalType = ProjJournalType::Hour;
    jourTable.JournalNameId = TestSFIntegrationParameters.RevenueJournalNameId;
    jourTableData.initFromJournalName(ProjJournalName::find(jourTable.JournalNameId));
    jourTable.Description = "Header description";
    jourStatic = jourTableData.journalStatic();

    if (jourtable.validatewrite())
    {
        jourtable.insert();
    }
    else
    {
        throw error("Validation failed to create journal header");
    }

    // Create journal transactions
    if (jourtable)
    {
        jourTransData = jourStatic.newJournalTransData(jourTrans, jourTableData);
        projtable = Projtable::find("ProjId0001");

        jourTrans.clear();
        jourTransData.initFromJournalTable();
        jourTrans.initValue();
        jourTrans.ProjId = projtable.ProjId;
        jourTrans.initFromProjTable(projtable);
        jourTrans.TransDate = DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone());
        jourTrans.ProjTransDate = jourTrans.TransDate;
        jourTrans.SalesPrice = 20.0;
        jourTrans.Txt = "Line description";
        jourTrans.Qty = 200;
        jourTrans.CurrencyId = 'CAN';
        jourTrans.CategoryId = TestSFIntegrationParameters.RevenueCategory;
        jourTrans.LinePropertyId = projLinePropertySetup.LinePropertyId;
        jourTrans.TaxItemGroupId = TestSFIntegrationParameters.TaxItemGroupId;

        if (jourTrans.validateWrite())
        {
            jourTransData.create(false);
            qty += jourTrans.Qty;
        }
        else
        {
            throw error("@ENG_Labels:ValidationFailedToCreateJournalLines");
        }

        jourTable.NumOfLines = real2int(jourTrans.LineNum);
        jourTable.ProjQty = qty;
        jourTable.doUpdate();
    }
    return jourTable.JournalId;
}
    &lt;/code&gt;&lt;/pre&gt;

    &lt;h3&gt;2. Posting the Journal&lt;/h3&gt;
    &lt;p&gt;Once the journal is created, the next step is to post it. This ensures that the journal entries are finalized and recorded in the system.&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;
public void postJournal(JournalId _journalId)
{
    ProjJournalCheckPost jourPost;
    jourPost = ProjJournalCheckPost::newJournalCheckPost(true, true, JournalCheckPostType::Post, tableNum(ProjJournalTable), _journalId);
    jourPost.runOperation();
}
    &lt;/code&gt;&lt;/pre&gt;

    &lt;h3&gt;3. Generating the Invoice Proposal&lt;/h3&gt;
    &lt;p&gt;After posting the journal, we generate an invoice proposal based on the journal entries. This involves selecting the appropriate funding source and creating the proposal data.&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;
public ProjProposalId invoiceProposalCreation(JournalId _journalId)
{
    ProjJournalTrans projJournalTrans;
    ProjTable projTable, parentprojTable;
    ProjFundingSourceRefId fundingSource;
    ProjFundingSource ProjFundingSource;
    ProjProposalId proposalId;

    select firstonly ParentId, defaultfundingsource, ProjInvoiceProjId from projTable
        join ProjId from projJournalTrans
            where projTable.ProjId == projJournalTrans.ProjId
               &amp;&amp; ProjJournalTrans.JournalId == _journalId
               &amp;&amp; ProjJournalTrans.LineNum == 1;

    select firstonly ProjInvoiceProjId, ProjGroupId, defaultfundingsource from parentprojTable
        where parentprojTable.ProjId == projTable.ParentId;

    fundingSource = projTable.DefaultFundingSource != 0 ? projTable.DefaultFundingSource : parentprojTable.DefaultFundingSource;

    if (!fundingSource)
    {
        select firstonly projFundingSource
            where projFundingSource.ContractId == projTable.ProjInvoiceProjId
            &amp;&amp; projFundingSource.CustAccount == projTable.CustAccount
            &amp;&amp; projFundingSource.FundingType == ProjFundingType::Customer;

        if (!projFundingSource)
        {
            throw error("Couldn't find funding source (Invoice account) for given parent and child project and on assigned contract.");
        }
        fundingSource = projFundingSource.RecId;
    }

    proposalId = TestCreateInvoiceProposal::createDataInTmp(fundingSource, _journalId);
    return proposalId;
}
    &lt;/code&gt;&lt;/pre&gt;

    &lt;h3&gt;4. Posting the Invoice Proposal&lt;/h3&gt;
    &lt;p&gt;Finally, we post the invoice proposal to generate the actual invoice. This involves updating the proposal journal and running the form letter operation.&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;
public InvoiceId postInvoiceProposal(ProjProposalId _proposalId)
{
    ProjProposalJour projProposalJour;
    ProjFormLetter projFormLetter;

    select forupdate projProposalJour order by RecId desc
        where projProposalJour.ProposalId == _proposalId;

    projProposalJour.PSAInvoiceTxtPre = "Invoice header text";
    projProposalJour.LineProperty = ProjLinePropertyCode::Approved;
    projProposalJour.editInvReportFormat(true, "PSAProjInvoice.Report");
    projProposalJour.update();

    projFormLetter = ProjFormLetter::construct(DocumentStatus::ProjectInvoice);
    projFormLetter.createParmLine(projProposalJour);
    projFormLetter.runOperation();

    projProposalJour = projProposalJour::find(projProposalJour.ProposalId);
    return projProposalJour.ProjInvoiceId;
}
    &lt;/code&gt;&lt;/pre&gt;

    &lt;h3&gt;Additional Class: TestCreateInvoiceProposal&lt;/h3&gt;
    &lt;p&gt;Below is the additional class code for creating invoice proposals:&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;
class TestCreateInvoiceProposal extends projInvoiceProposalInsertLines
{

    public void createInvoiceProposals(PSATmpProjProposalTrans _tmpProjProposalTrans)
    {
        int i;
        ProjProposalJour proposalJour;
        ProjTable projTable;

        this.progressInit("@SYS54552", 0);
        while select _tmpProjProposalTrans
        {
            if (i == 0)
            {
                this.parmDefaultDimension(_tmpProjProposalTrans.DefaultDimension);
                this.setProjProposalJour(_tmpProjProposalTrans.ProjInvoiceProjId, _tmpProjProposalTrans.ProjId,
                _tmpProjProposalTrans.FundingSourceRefId, _tmpProjProposalTrans.CurrencyCode, 
                _tmpProjProposalTrans.TaxInformation_IN, _tmpProjProposalTrans.FixedExchRate);
                i++;
            }

            this.setProjProposalJourPost(_tmpProjProposalTrans);

            select firstonly RecId from projTable
                where projTable.ProjId == _tmpProjProposalTrans.ProjId &amp;&amp;
                        projTable.ProjInvoiceProjId == _tmpProjProposalTrans.ProjInvoiceProjId
                exists join proposalJour
                    where proposalJour.ProjInvoiceProjId == projTable.ProjInvoiceProjId &amp;&amp;
                            proposalJour.ProposalId == projProposalJour.ProposalId;

            if (projTable.RecId)
            {
                this.doEmpl(_tmpProjProposalTrans.ProjInvoiceProjId, _tmpProjProposalTrans.RefRecId);
            }

            if (!this.parmSkipRecalculateProposalTotals())
            {
                this.updateInvoice();

                // When an invoice proposal is generated, the system will
                // automatically create retainage withholding records and/or retainage billing records at the project level.
                this.calcRetention();
            }
        }
    }

    public static ProjProposalId createDataInTmp(ProjFundingSourceRefId _fundingSource, JournalId _journalId)
    {
        ProjInvoiceProposalCreateLinesParams proposalCreateLinesParams = ProjInvoiceProposalCreateLinesParams::construct();
        ProjInvoiceProposalCreateLines proposalCreateLines;
        ProjInvoiceProposalInsertLines projInvoiceProposalInsertLines;
        ProjEmplTransSale ProjEmplTransSale;
        PSATmpProjProposalTrans tmpProjProposalTrans;
        ProjEmplTrans ProjEmplTrans;
        ProjJournalTrans projJournalTrans;
        TransDate invoiceDate = DateTimeUtil::getToday(DateTimeUtil::getUserPreferredTimeZone());
        ProjProposalId proposalId;

        proposalCreateLinesParams.parmInvoiceDate(invoiceDate);
        proposalCreateLinesParams.parmInvoiceTypeSelection(ProjInvoiceTypeSelection::Both);

        proposalCreateLines = ProjInvoiceProposalCreateLines::newStandard(proposalCreateLinesParams.pack());
        proposalCreateLines.parmProposalCreateLinesParams().parmInvoiceDate(invoiceDate);

        projInvoiceProposalInsertLines = new ProjInvoiceProposalInsertLines(proposalCreateLines, false);

        select firstonly Voucher from ProjJournalTrans
            where ProjJournalTrans.JournalId == _journalId;

        while select ProjEmplTrans
            where ProjEmplTrans.VoucherJournal == ProjJournalTrans.Voucher
        {
            select firstonly ProjEmplTransSale
                where ProjEmplTransSale.TransId == ProjEmplTrans.TransId
                   &amp;&amp; ProjEmplTransSale.FundingSource == _fundingSource;

            tmpProjProposalTrans.initFromProjEmplTrans(ProjEmplTrans);
            tmpProjProposalTrans.FundingSourceRefId = _fundingSource;
            tmpProjProposalTrans.LineAmount = ProjEmplTransSale.LineAmount * -1;
            tmpProjProposalTrans.SalesPrice = ProjEmplTransSale.SalesPrice;
            tmpProjProposalTrans.Selected = true;
            tmpProjProposalTrans.RefRecId = ProjEmplTransSale.RecId;
            tmpProjProposalTrans.RefTableId = ProjEmplTransSale.TableId;
            tmpProjProposalTrans.IndirectAmount = ProjEmplTransSale.PSAIndirectInvoice;
            tmpProjProposalTrans.insert();
        }

        new TestCreateInvoiceProposal(proposalCreateLines, false).createInvoiceProposals(tmpProjProposalTrans);

        select firstonly ProjEmplTrans
            where ProjEmplTrans.VoucherJournal == ProjJournalTrans.Voucher
        join ProjEmplTransSale
            where ProjEmplTransSale.TransId == ProjEmplTrans.TransId
               &amp;&amp; ProjEmplTransSale.FundingSource == _fundingSource;

        proposalId = ProjTrans::newProjEmplTransSale(ProjEmplTrans, ProjEmplTransSale).proposalId();

        return proposalId;
    }
}
    &lt;/code&gt;&lt;/pre&gt;

    &lt;h3&gt;Main Method to Call the Above Code&lt;/h3&gt;
    &lt;p&gt;Below is the main method to call the above code from a runnable class:&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;
public class TestCreateHourJournalPostAndCreateInvProposalAndPostInvoice
{
    public static void main(Args _args)
    {
        JournalId journalId;
        ProjProposalId 	proposalId;
        InvoiceId 	invoiceId;
        
        TestCreateHourJournalPostAndCreateInvProposalAndPostInvoice objCreateHourJourAndCreateAndPostInvoice = new TestCreateHourJournalPostAndCreateInvProposalAndPostInvoice();

        journalId = objCreateHourJourAndCreateAndPostInvoice.createJournal();
        objCreateHourJourAndCreateAndPostInvoice.postJournal(journalId);
        proposalId = objCreateHourJourAndCreateAndPostInvoice.invoiceProposalCreation(journalId);
        invoiceId = objCreateHourJourAndCreateAndPostInvoice.postInvoiceProposal(proposalId);
        info(strfmt("invoice %1 posted",invoiceId);
    }
}
    &lt;/code&gt;&lt;/pre&gt;    
&lt;/body&gt;
&lt;/html&gt;</description><link>https://d365fotechnicalblog.blogspot.com/2025/04/project-hour-journal-creation-and.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-948028306141658089</guid><pubDate>Thu, 03 Apr 2025 05:42:00 +0000</pubDate><atom:updated>2025-04-02T22:44:39.091-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">How to set background color for alternate row in SSRS report table D365FO</category><title>How to set background color for alternate row in SSRS report table D365FO</title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Setting Background Color for Alternate Rows in SSRS Report Table&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
        }
        .content {
            max-width: 800px;
            margin: auto;
            padding: 20px;
        }
        h1 {
            color: #333;
        }
        code {
            background-color: #f4f4f4;
            padding: 5px;
            border-radius: 5px;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class="content"&gt;
        &lt;h1&gt;Setting Background Color for Alternate Rows in SSRS Report Table&lt;/h1&gt;
        &lt;p&gt;In this blog post, we will explore how to set the background color for alternate rows in an SSRS report table in Dynamics 365 Finance and Operations. This can be achieved using two different expressions:&lt;/p&gt;
        
        &lt;h2&gt;1. Based on Unique Value in Table&lt;/h2&gt;
        &lt;p&gt;To set the background color based on a unique value in the table, you can use the following expression:&lt;/p&gt;
        &lt;code&gt;=IIF(RUNNINGVALUE(Fields!FieldName.Value, CountDistinct, Nothing) Mod 2, "#ffffff", "#f0f0f0")&lt;/code&gt;
        
        
        &lt;h2&gt;2. Based on Row Number&lt;/h2&gt;
        &lt;p&gt;To set the background color based on the row number, you can use the following expression:&lt;/p&gt;
        &lt;code&gt;=IIF(RowNumber(Nothing) Mod 2, "#ffffff", "#f0f0f0")&lt;/code&gt;
        
        
        &lt;h2&gt;Implementation&lt;/h2&gt;
        &lt;p&gt;To implement these expressions in your SSRS report:&lt;/p&gt;
        &lt;ol&gt;
            &lt;li&gt;Open your report in design in visual studio.&lt;/li&gt;
            &lt;li&gt;Select the table where you want to apply the alternate row background color.&lt;/li&gt;
            &lt;li&gt;Right-click on the data row (after table header) row and select &lt;strong&gt;Properties&lt;/strong&gt;.&lt;/li&gt;
            &lt;li&gt;In the &lt;strong&gt;BackgroundColor&lt;/strong&gt; property, enter one of the expressions mentioned above.&lt;/li&gt;
            &lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt; to apply the changes.&lt;/li&gt;
        &lt;/ol&gt;
        &lt;p&gt;By following these steps, you can easily set the background color for alternate rows in your SSRS report table.&lt;/p&gt;
      	&lt;p&gt;Please note - if you do the grouping on table then these background colors will also not show properly.&lt;/p&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</description><link>https://d365fotechnicalblog.blogspot.com/2025/04/how-to-set-background-color-for.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-1798088922855569370</guid><pubDate>Wed, 02 Apr 2025 09:24:00 +0000</pubDate><atom:updated>2025-04-02T02:24:09.140-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">How to access extension class method on data entity field property</category><title>How to access extension class method on data entity field property</title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;How to Use Extension Class Methods on Field Properties of Data Entity&lt;/title&gt;
    &lt;style&gt;
        pre {
            background-color: #f5f5f5;
            padding: 10px;
            border-radius: 5px;
            box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
            overflow-x: auto;
        }
        code {
            font-family: Consolas, "Courier New", monospace;
            color: #333;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;How to Use Extension Class Methods on Field Properties of Data Entity&lt;/h1&gt;
    &lt;p&gt;If you want to use your extension class method on your field property, then please use the following syntax:&lt;/p&gt;

    &lt;pre&gt;&lt;code&gt;extension class name :: method name&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;Example:&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;TestCustCustomerV3Entity_Extension::testCollectionAgent&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Brackets are not required.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description><link>https://d365fotechnicalblog.blogspot.com/2025/04/how-to-access-extension-class-method-on.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-3346490701777530955</guid><pubDate>Wed, 02 Apr 2025 09:09:00 +0000</pubDate><atom:updated>2025-04-02T02:33:54.248-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Custom business event in D365FO</category><title>Custom business event in D365FO</title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Implementing Custom Business Events in D365FO&lt;/title&gt;
    &lt;style&gt;
        pre {
            background-color: #f5f5f5;
            padding: 10px;
            border-radius: 5px;
            box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
            overflow-x: auto;
        }
        code {
            font-family: Consolas, "Courier New", monospace;
            color: #333;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Implementing Custom Business Events in D365FO&lt;/h1&gt;
    &lt;p&gt;In this blog post, we'll walk through the steps to implement custom business events in Dynamics 365 Finance and Operations (D365FO). We'll cover creating a contract, defining a business event class, triggering the business event, building the solution, and rebuilding the business event catalog. Let's dive in!&lt;/p&gt;

    &lt;h2&gt;Step 1: Create the Contract&lt;/h2&gt;
    &lt;p&gt;First, we need to create a contract class that will define the data structure for our business event. Here's an example:&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;
[BusinessEvents(classStr(TestCustTableUpdateBusinessEventContract), 'Test:TestCustTableUpdateBusinessEventContract', 'Test description', ModuleAxapta::AccountsReceivable)]
public class TestCustTableUpdateBusinessEventContract extends BusinessEventsContractBase
{
    CustTable custTable;

    public static TestCustTableUpdateBusinessEventContract newFromCustTable(CustTable _custTable)
    {
        TestCustTableUpdateBusinessEventContract contract = new TestCustTableUpdateBusinessEventContract();
        contract.parmcustTable(_custTable);
        return contract;
    }

    private CustTable parmcustTable(CustTable _custTable = custTable)
    {
        custTable = _custTable;
        return custTable;
    }
}
    &lt;/code&gt;&lt;/pre&gt;

    &lt;h2&gt;Step 2: Define the Business Event Class&lt;/h2&gt;
    &lt;p&gt;Next, we'll define the business event class that will handle the event logic. Here's an example:&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;
public class TestCustomerDataUpdateBusinessEvent extends BusinessEventsBase
{
    CustTable custTable;

    public static TestCustomerDataUpdateBusinessEvent newFromCustTable(CustTable _custTable)
    {
        TestCustomerDataUpdateBusinessEvent businessEvent = new TestCustomerDataUpdateBusinessEvent();
        businessEvent.parmcustTable(_custTable);
        return businessEvent;
    }

    private CustTable parmcustTable(CustTable _custTable = custTable)
    {
        custTable = _custTable;
        return custTable;
    }

    [Wrappable(true), Replaceable(true)]
    public BusinessEventsContract buildContract()
    {
        // Note: This method will be called only if the business event is activated.
        return TestCustTableUpdateBusinessEventContract::newFromCustTable(custTable);
    }
}
    &lt;/code&gt;&lt;/pre&gt;

    &lt;h2&gt;Step 3: Trigger the Business Event&lt;/h2&gt;
    &lt;p&gt;Finally, we'll trigger the business event from the &lt;code&gt;CustTable&lt;/code&gt; update method. Here's how you can do it:&lt;/p&gt;
    &lt;pre&gt;&lt;code&gt;
[ExtensionOf(tableStr(CustTable))]
final class TestCustTable_Extension
{
    void update(boolean _updateSmmBusRelTable, boolean _updateParty)
    {
        next update(_updateSmmBusRelTable, _updateParty);

        // Call business event
        if (BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(TestCustomerDataUpdateBusinessEvent)))
        {
            CustTable custTable = CustTable::find(this.AccountNum);
            TestCustomerDataUpdateBusinessEvent::newFromCustTable(custTable).send();
        }
    }
}
    &lt;/code&gt;&lt;/pre&gt;

    &lt;h2&gt;Step 4: Build the Solution&lt;/h2&gt;
    &lt;p&gt;After making the necessary changes, build the solution to ensure that all components are correctly compiled and integrated.&lt;/p&gt;

    &lt;h2&gt;Step 5: Rebuild the Business Event Catalog&lt;/h2&gt;
    &lt;p&gt;Now, go to &lt;strong&gt;System administration &gt; Setup &gt; Business events &gt; Business event catalog&lt;/strong&gt; form and rebuild the business event catalog. This step ensures that your new business event is registered and available for use.&lt;/p&gt;

    &lt;h2&gt;Conclusion&lt;/h2&gt;
    &lt;p&gt;By following these steps, you can implement custom business events in D365FO. This allows you to extend the functionality of your system and integrate with external systems or processes. Happy coding!&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description><link>https://d365fotechnicalblog.blogspot.com/2025/04/custom-business-event-in-d365fo.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-2881446055787935292</guid><pubDate>Tue, 01 Apr 2025 12:50:00 +0000</pubDate><atom:updated>2025-04-01T05:51:20.962-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">How to add Personnel Number field on the data entity D365FO</category><title>How to add Personnel Number field on the data entity D365FO</title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;How to Add Personnel Number Field on the Data Entity in D365FO&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
        }
        h1, h2 {
            color: #2c3e50;
        }
        code {
            background-color: #f4f4f4;
            padding: 5px;
            border-radius: 5px;
            display: block;
            white-space: pre-wrap;
        }
        img {
            max-width: 100%;
            height: auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;How to Add Personnel Number Field on the Data Entity in D365FO&lt;/h1&gt;
    &lt;p&gt;Follow these steps to add the Personnel Number field to the CustCustomerV3Entity data entity in Dynamics 365 Finance and Operations.&lt;/p&gt;

    &lt;h2&gt;Step 1: Create Extension for CustCustomerV3Entity&lt;/h2&gt;
   

    &lt;h2&gt;Step 2: Add New Fields&lt;/h2&gt;
    &lt;p&gt;Add two new fields: &lt;code&gt;TestHcmWorkerRecId,TestPersonnelNumber&lt;/code&gt;.&lt;/p&gt;
    
    &lt;p&gt;Repeat this step for the staging table as well.&lt;/p&gt;

    &lt;h2&gt;Step 3: Create Code Extension for CustCustomerV3Entity&lt;/h2&gt;
    &lt;p&gt;Create a new code extension for CustCustomerV3Entity and add the following code:&lt;/p&gt;
    &lt;code&gt;
[ExtensionOf(tableStr(CustCustomerV3Entity))]
final class TESTCustCustomerV3Entity_Extension
{
    /// &amp;lt;summary&amp;gt;
    /// Provides the query to be used to compute the value of TestPersonnelNumber field.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;A query to be used to compute the value of TestPersonnelNumber field.&amp;lt;/returns&amp;gt;
    public static str testCollectionAgent()
    {
        return smmUtility::workerPersonnelNumberQuery(
            tablestr(CustCustomerV3Entity), dataEntityDataSourceStr(CustCustomerV3Entity, CustTable), fieldstr(CustTable, TestHcmWorkerRecId));
    }

    public void mapEntityToDataSource(DataEntityRuntimeContext _entityCtx, DataEntityDataSourceRuntimeContext _dataSourceCtx)
    {
        if (_dataSourceCtx.name() == dataEntityDataSourceStr(CustCustomerV3Entity, CustTable))
        {
            this.TestHcmWorkerRecId = smmUtility::getEntityWorkerRecId(this.testCollectionAgent);
        }
        next mapEntityToDataSource(_entityCtx, _dataSourceCtx);
    }
}
    &lt;/code&gt;

    &lt;h2&gt;Step 4: Configure Field Properties&lt;/h2&gt;
    &lt;p&gt;On the &lt;b&gt;TestPersonnelNumber&lt;/b&gt; field, set the DataEntityViewMethod property to &lt;b&gt;TESTCustCustomerV3Entity_Extension::testCollectionAgent&lt;/b&gt;.&lt;/p&gt;
 

    &lt;h2&gt;Step 5: Build and Synchronize&lt;/h2&gt;
    &lt;p&gt;Build and synchronize the project.&lt;/p&gt;

    &lt;h2&gt;Step 6: Test Using Postman&lt;/h2&gt;
    &lt;p&gt;Test the changes using Postman to ensure everything is working correctly.&lt;/p&gt;

&lt;/body&gt;
&lt;/html&gt;</description><link>https://d365fotechnicalblog.blogspot.com/2025/04/how-to-add-personnel-number-field-on.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-4166741528624335815</guid><pubDate>Tue, 01 Apr 2025 10:48:00 +0000</pubDate><atom:updated>2025-04-01T03:50:20.136-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">register purchase orders in D365FO</category><title>How to register purchase orders in D365FO using X++ code</title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Registering a Purchase Order in X++&lt;/title&gt;
&lt;/head&gt;

    &lt;h2&gt;Code Explanation&lt;/h2&gt;
    
    &lt;pre&gt;
&lt;code&gt;
internal final class TESTJobToCheckRegistraion
{
    PurchFormLetterParmData          purchFormLetterParmData;
    PurchParmTable                   purchParmTable;
    PurchParmLine                    purchParmLine;
    PurchParmUpdate                  purchParmUpdate;
    PurchTable                       purchTable;
    PurchFormLetter                  purchFormLetter;
    TransDate                        packingSlipDate;
    PackingSlipId                    packingSlipId;

    public static void main(Args _args)
    {
        PurchTable    purchTable;
        PurchLine     purchLine;
        TransDate     packingSlipDate;
        PackingSlipId packingSlipId;
        container     lineNums;
        container     purchLineRecIds;
        container     inventBatchIds;
        container     qtys;
        int           i;

        purchTable      = PurchTable::find('002357-POR-UK01');
        packingSlipDate = DateTimeUtil::date(DateTimeUtil::utcNow());
        packingSlipId   = 'PK0001';

        lineNums       = [100]; // purch line numbers
        inventBatchIds = ['Batch001']; //batch numbers to register
        qtys           = [100]; // quantity to register

        for (i = 1; i &lt;= conLen(lineNums); i++)
        {
            purchLine = PurchLine::find(purchTable.PurchId, conPeek(lineNums, i));
            purchLineRecIds = conIns(purchLineRecIds, conLen(purchLineRecIds) + 1, purchLine.RecId);
        }

        TESTJobToCheckRegistraion TESTJobToCheckRegistraion = new TESTJobToCheckRegistraion();
        TESTJobToCheckRegistraion.insertParmLineData(purchLineRecIds, inventBatchIds, qtys);
    }

    private void registerInventory(PurchParmLine _purchParmline, InventDim _inventDim)
    {
        InventTransWMS_Register inventTransWMS_register;
        TmpInventTransWMS       tmpInventTransWMS;
        InventDim               inventBatchCheck;
        InventTrans             inventTranslocal;
        InventDim               inventDimlocal;

        inventTranslocal = InventTrans::findTransId(_purchParmline.InventTransId, true);
        inventDimlocal   = inventTranslocal.inventDim();
        inventDimlocal.inventBatchId    = _inventDim.inventBatchId;
        inventDimlocal.InventLocationId = _inventDim.InventLocationId;
        inventDimlocal.InventSiteId     = _inventDim.InventSiteId;
        inventDimlocal                  = InventDim::findOrCreate(inventDimlocal);
        inventTransWMS_register         = inventTransWMS_register::newStandard(tmpInventTransWMS);

        inventTranslocal.inventDimId    = inventDimlocal.inventDimId;
        tmpInventTransWMS.clear();
        tmpInventTransWMS.initFromInventTrans(inventTranslocal);
        tmpInventTransWMS.ItemId    = inventTranslocal.ItemId;
        tmpInventTransWMS.InventQty = _purchParmline.ReceiveNow;
        tmpInventTransWMS.insert();

        inventTransWMS_register.writeTmpInventTransWMS(tmpInventTransWMS, inventTranslocal, inventDimlocal);
        inventTransWMS_register.updateInvent(inventTranslocal);
    }

    private void insertParmLineData(container _purchLineRecIds, container _inventBatchIds, container _qtys)
    {
        PurchLine purchLine;
        InventDim inventDim;
        int       i;

        for (i = 1; i &lt;= conLen(_inventBatchIds); i++)
        {
            purchLine.clear();
            purchLine = PurchLine::findRecId(conPeek(_purchLineRecIds, i));
            purchParmLine.InitFromPurchLine(purchLine);
            inventDim = purchLine.inventDim();
            purchParmLine.ReceiveNow  = decRound(conPeek(_qtys, i), 2);
            purchParmLine.InventDimId = inventDim.inventDimId;
            purchParmLine.ParmId      = purchParmTable.ParmId;
            purchParmLine.TableRefId  = purchParmTable.TableRefId;
            purchParmLine.setQty(DocumentStatus::PackingSlip, false, true);
            purchParmLine.setLineAmount();
            purchParmLine.insert();
            inventDim.inventBatchId   = conPeek(_inventBatchIds, i);
            inventDim = inventDim::findOrCreate(inventDim);
            this.registerInventory(purchParmLine, inventDim);
        }
    }
}
&lt;/code&gt;
   
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2025/04/how-to-register-purchase-orders-in.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-102461547091583549</guid><pubDate>Sat, 29 Mar 2025 12:02:00 +0000</pubDate><atom:updated>2025-03-29T05:03:22.256-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">not creating project transactions</category><category domain="http://www.blogger.com/atom/ns#">product receipt from x++ code</category><title>After product receipt from x++ code system is not creating project transactions</title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Resolving Project Transactions Issue in X++&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            margin: 20px;
        }
        h1, h2, h3 {
            color: #333;
        }
        pre {
            background: #f4f4f4;
            padding: 10px;
            border-radius: 5px;
            overflow-x: auto;
        }
        code {
            font-family: Consolas, monospace;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Resolving Issue: Project Transactions Not Created After Product Receipt in X++&lt;/h1&gt;
    
    &lt;h2&gt;Introduction&lt;/h2&gt;
    &lt;p&gt;
        When receiving a product receipt in Microsoft Dynamics 365 Finance and Operations via X++ code, you might encounter a scenario where project transactions are not generated, even when a valid project ID is associated with the purchase order.
        Debugging revealed that the system is not calling the &lt;code&gt;runProjectPostings()&lt;/code&gt; method of the &lt;code&gt;PurchFormLetter_PackingSlip&lt;/code&gt; class, which prevents the project packing slip from being posted.
        
        To resolve this, I created the &lt;code&gt;runRemainProjectUpdates&lt;/code&gt; method in the code below.
    &lt;/p&gt;
    
    &lt;h2&gt;Code Implementation&lt;/h2&gt;
    
    &lt;h3&gt;Product Receipt Creation&lt;/h3&gt;
    &lt;pre&gt;&lt;code&gt;
private TestPOReceiptResponseContract createProductReceipt(TestPOReceiptRequestContract _requestContract)
{
    PurchFormLetter purchFormLetter;
    PurchParmTable purchParmTable;
    PurchParmLine purchParmLine;
    PurchFormletterParmData purchFormLetterParmData;
    TestOrderLineRequestContract orderLineContract = _requestContract.parmOrderLineContract();
    PurchTable purchTable = PurchTable::find(orderLineContract.parmPurchaseOrderId());
    PurchLine purchLine = PurchLine::find(purchTable.PurchId, orderLineContract.parmLineNumber());

    purchFormLetterParmData = PurchFormletterParmData::newData(DocumentStatus::PackingSlip, VersioningUpdateType::Initial);
    purchFormLetterParmData.parmOnlyCreateParmUpdate(true);
    purchFormLetterParmData.createData(false);

    PurchParmUpdate purchParmUpdate = purchFormLetterParmData.parmParmUpdate();

    purchParmTable.clear();
    purchParmTable.TransDate = _requestContract.parmProducReceiptDate();
    purchParmTable.Ordering = DocumentStatus::PackingSlip;
    purchParmTable.ParmJobStatus = ParmJobStatus::Waiting;
    purchParmTable.Num = _requestContract.parmCoupaId();
    purchParmTable.PurchId = purchTable.PurchId;
    purchParmTable.insert();
    
    purchParmLine.initFromPurchLine(purchLine);
    purchParmLine.ReceiveNow = _requestContract.parmTotal();
    purchParmLine.ParmId = purchParmTable.ParmId;
    purchParmLine.insert();

    purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);
    purchFormLetter.transDate(_requestContract.parmProducReceiptDate());
    purchFormLetter.run();

    // Generate project item transactions
    if (purchTable.ProjId != '')
    {
        this.runRemainProjectUpdates(purchFormLetter, purchParmTable.ParmId);
    }
    
    return this.getResponseContract("@ENG_Labels:ProductReceiptCreated", true);
}
    &lt;/code&gt;&lt;/pre&gt;
    
    &lt;h3&gt;Explicitly Calling &lt;code&gt;runRemainProjectUpdates&lt;/code&gt; to Create Project Transactions&lt;/h3&gt;
    &lt;pre&gt;&lt;code&gt;
public void runRemainProjectUpdates(PurchFormLetter _purchFormLetter, ParmId _parmId)
{
    FormletterOutputContract outputContract = _purchFormLetter.getOutputContract();
    VendPackingSlipVersion localVendPackingSlipVersion;
    VendPackingSlipJour localVendPackingSlipJour;
    VendPackingSlipTrans localVendPackingSlipTrans;
    PurchLine localPurchLine;
    SalesLine localSalesLine;
    SalesFormLetter salesFormLetter;

    if (ProjParameters::find().AutomaticItemConsumption == NoYes::Yes)
    {
        select firstonly RecId, AccountingDate from localVendPackingSlipVersion
            where localVendPackingSlipVersion.ParmId == _parmId
            exists join localVendPackingSlipJour
                where localVendPackingSlipVersion.VendPackingSlipJour == localVendPackingSlipJour.RecId
                exists join localVendPackingSlipTrans
                    where localVendPackingSlipTrans.VendPackingSlipJour == localVendPackingSlipJour.RecId
                    exists join localPurchLine
                        where localPurchLine.InventTransId == localVendPackingSlipTrans.InventTransId
                        &amp;&amp; localPurchLine.ItemRefType == InventRefType::Sales
                        exists join localSalesLine
                            where localSalesLine.InventTransId == localPurchLine.InventRefTransId
                            &amp;&amp; localSalesLine.ProjId;

        if (localVendPackingSlipVersion.RecId)
        {
            salesFormLetter = SalesFormLetter::newFromPurchFormLetter_PackingSlip(
                SysOperationHelper::base64Encode(outputContract.parmJournalLinesPacked()),
                DocumentStatus::ProjectPackingSlip);

            if (localVendPackingSlipVersion.AccountingDate)
            {
                salesFormLetter.transDate(localVendPackingSlipVersion.AccountingDate);
            }

            salesFormLetter.runOperation();
        }
    }
}
    &lt;/code&gt;&lt;/pre&gt;
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2025/03/after-product-receipt-from-x-code.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-3843250098639367611</guid><pubDate>Sat, 29 Mar 2025 10:55:00 +0000</pubDate><atom:updated>2025-03-29T04:20:04.315-07:00</atom:updated><title>How to register return sales order lines using X++ code</title><description>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;How to Register Return Sales Order Lines in X++&lt;/title&gt;
    &lt;style&gt;
        body 
        {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            margin: 20px;
            padding: 20px;
            background-color: #f4f4f4;
        }
        h1, h2 
        {
            color: #333;
        }
        pre 
        {
            background: #333;
            color: #fff;
            padding: 10px;
            overflow-x: auto;
            border-radius: 5px;
        }
        code 
        {
            font-family: Consolas, Monaco, 'Courier New', monospace;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;The &lt;code&gt;TestSalesReturnOrderLineRegister&lt;/code&gt; Class in X++&lt;/h1&gt;
    &lt;p&gt;The &lt;code&gt;TestSalesReturnOrderLineRegister&lt;/code&gt; class serves as an entry point to the product registration process, specialized for the sales return order process. It handles the return disposition code and manages sales return order specifics, such as creating inventory transactions.&lt;/p&gt;
    
    &lt;h2&gt;Code Overview&lt;/h2&gt;
    &lt;pre&gt;&lt;code&gt;

class TestSalesReturnOrderLineRegister extends TradeOrderLineRegister
{
    ReturnDispositionCodeId returnDispositionCodeId;
    DialogField dialogDispositionCodeId;
    SalesLine salesLine;
    boolean reverseInventTrans;
    boolean recreateReservationLine;
    boolean inRegistration;

    public boolean init()
    {
        boolean ret = super();
        salesLine = salesPurchLine;
        return ret;
    }

    public void run()
    {
        this.runPreSuper();
        super();
        this.runPostSuper();
    }

    public void runPostSuper()
    {
        salesLine = SalesLine::findInventTransId(salesLine.InventTransId, true);
        if (inRegistration)
        {
            if (salesLine.ReturnStatus == ReturnStatusLine::Awaiting)
            {
                if (reverseInventTrans &amp;&amp; !salesLine.ReturnAllowReservation)
                {
                    SalesLine::changeReturnOrderType(salesLine.InventTransId, null, true);
                    salesLine = SalesLine::findInventTransId(salesLine.InventTransId, true);
                }
                if (salesLine.ReturnDispositionCodeId)
                {
                    salesLine.ReturnDispositionCodeId = '';
                    salesLine.update();
                }
            }
        }
        else 
        {
            if (salesLine.ReturnStatus == ReturnStatusLine::Registered &amp;&amp; recreateReservationLine)
            {
                salesLine.createReturnReservationLine();
                salesLine = SalesLine::findInventTransId(salesLine.InventTransId, true);
            }
        }
    }
}
    &lt;/code&gt;&lt;/pre&gt;

    &lt;h2&gt;Calling the &lt;code&gt;TestSalesReturnOrderLineRegister&lt;/code&gt; Class&lt;/h2&gt;
    &lt;pre&gt;&lt;code&gt;
public void registerReturnSOLine(SalesId _salesId, ReturnDispositionCodeId _dispositionCode)
{
    TradeOrderLineRegister tradeOrderlineRegister;
    TestSalesReturnOrderLineRegister salesReturnOrderLineRegister;
    InventTransWMS_Register inventTransWMS_register;
    TmpInventTransWMS TmpInventTransWMS;
    SalesLine salesLine;
    InventTrans inventTrans;
    InventTransOrigin inventTransOrigin;
    returnDispositionCode returnDispositionCode;

    Args args = new Args();
    while select forUpdate salesLine where salesLine.SalesId == _returnSOTable.SalesId
    {
        args.record(salesLine);
        tradeOrderLineRegister = TestSalesReturnOrderLineRegister::construct();
        tradeOrderLineRegister.parmArgs(args);
        tradeOrderLineRegister.init();
        salesReturnOrderLineRegister = tradeOrderLineRegister;
        salesReturnOrderLineRegister.runPreSuper();
        
        select firstOnly returnDispositionCode
            where returnDispositionCode.DispositionAction == DispositionAction::Credit;
        
        salesLine.ReturnDispositionCodeId = returnDispositionCode.DispositionCodeId;
        salesLine.update();

        select firstOnly crossCompany inventTrans
            join RecId, InventTransId from inventTransOrigin
                where inventTransOrigin.InventTransId == salesLine.InventTransId
                &amp;&amp; inventTrans.InventTransOrigin == inventTransOrigin.RecId;

        inventTransWMS_register = inventTransWMS_register::newStandard(tmpInventTransWMS);
        tmpInventTransWMS.clear();
        tmpInventTransWMS.initFromInventTrans(inventTrans);
        tmpInventTransWMS.InventDimId = inventTrans.InventDimId;
        tmpInventTransWMS.insert();

        inventTransWMS_register.writeTmpInventTransWMS(tmpInventTransWMS, inventTrans, inventTrans.inventDim());
        if (!inventTransWMS_register.updateInvent(salesLine))
        {
            throw error("Error during registration of sales line.");
        }
    }
}
    &lt;/code&gt;&lt;/pre&gt;
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2025/03/how-to-register-return-sales-order.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-2354234355560065228</guid><pubDate>Wed, 26 Mar 2025 10:55:00 +0000</pubDate><atom:updated>2025-03-26T04:12:44.374-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">COC in D365FO forms</category><title>How to create COC for form methods , How to get formRun , How to make control visible false on form in D365FO</title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;How to create COC for form method in D365FO&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            margin: 40px;
            line-height: 1.6;
        }
        pre {
            background: #f4f4f4;
            padding: 10px;
            border-radius: 5px;
            overflow-x: auto;
        }
        code {
            font-family: "Courier New", monospace;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;How to create COC for form method in D365FO&lt;/h1&gt;
    
    
    &lt;h2&gt;Example Code&lt;/h2&gt;    
    
    &lt;pre&gt;&lt;code&gt;[ExtensionOf(formStr(ProjInvoiceListPage))]
final class TestProjInvoiceListPage_Extension
{
    public void init()
    {
        next init();

        FormRun formRun = this as FormRun;

        if(ProjParameters::find().TestPrintPGGDesignForProjectInvoice)
        {
            FormControl         stdViewCopyBtn   = formrun.design(0).controlName('PrintProjInvoiceCopyButton');
            FormControl         stdViewOrigBtn   = formrun.design(0).controlName('PrintProjInvoiceButton');
            stdViewCopyBtn.visible(false);
            stdViewOrigBtn.visible(false);
        }
        else
        {
            FormControl         customViewCopyBtn   = formrun.design(0).controlName('TestPSAProjInvoiceCopy');
            FormControl         customViewOrigBtn   = formrun.design(0).controlName('TestPSAProjInvoiceOriginal');

            customViewCopyBtn.visible(true);
            customViewOrigBtn.visible(true);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
    
   
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2025/03/how-to-create-coc-for-form-methods-how.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-1997741746124661715</guid><pubDate>Fri, 07 Feb 2025 06:05:00 +0000</pubDate><atom:updated>2025-02-06T22:30:07.915-08:00</atom:updated><title>Fix Dynamics 365FO Synchronization Error - Transaction Log Full </title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;meta name="description" content="Fix for Dynamics 365FO synchronization error: The transaction log for database is full due to 'log_backup'."&gt;
    &lt;title&gt;Fix Dynamics 365FO Synchronization Error - Transaction Log Full&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            max-width: 800px;
            margin: 20px auto;
            padding: 20px;
            border: 1px solid #ddd;
            border-radius: 5px;
            background-color: #f9f9f9;
        }
        pre {
            background: #eee;
            padding: 10px;
            border-radius: 5px;
            overflow-x: auto;
        }
        img {
            display: block;
            max-width: 100%;
            height: auto;
            margin-top: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Fix: The transaction log for database is full due to 'log_backup' - Dynamics 365FO&lt;/h1&gt;
    &lt;p&gt;If you're encountering the error &lt;strong&gt;"The transaction log for database is full due to 'log_backup'"&lt;/strong&gt; while working with Dynamics 365 Finance and Operations (D365FO), it means your SQL Server transaction log has reached its maximum capacity.&lt;/p&gt;
    &lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEgMMpBeb1bbDlTrPqGudUGF4EbN5oele5Na2p1jKcK03BR-Q5YAr5k8_8o06GCeUsuV_jICHrQcB1TVLfCWQ4qCNJnadWaA3d9J3w3q4I_HjnRGqFlf-KXB9XLbKc_ie_gb_jp3bhN_T2Hg5Y5njMp977ViVhgASuJSXXAwpsVrD741MMnaowajyehEf3w"&gt;
    &lt;h2&gt;Solution&lt;/h2&gt;
    &lt;p&gt;Follow these steps to resolve the issue:&lt;/p&gt;
    
    &lt;h3&gt;Step 1: Check the Database Files&lt;/h3&gt;
    &lt;p&gt;Run the following SQL query to check the database file details:&lt;/p&gt;
    &lt;pre&gt;
    SELECT * FROM sys.database_files
    &lt;/pre&gt;
    &lt;p&gt;Note down the log file name from the result and use that same name in the second statement of the step 2 SQL query.&lt;/p&gt;
    &lt;p&gt;Query result screenshot:&lt;/p&gt;
    &lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEgUgYzPwcWYB0njGP9E_XWPGQ9f_MYMevqVsjvpl70cs7V3oVZNnp9s4dDlvyfPwUUomoHDc9Nhd-h3tGASHIdCtpzxO8unjq04PPvSfyr_lvRijWoywoL3-VE9PuMis6gwscPiAEVzCb4J7U0N0ZzPqHdZC2CTcwBaozywK4bQ5gLSmil0cNVWWQYH49Y=w651-h213" alt="Database files query result"&gt;
    
    &lt;h3&gt;Step 2: Shrink the Transaction Log&lt;/h3&gt;
    &lt;p&gt;Execute the following commands to shrink the transaction log and free up space:&lt;/p&gt;
    &lt;pre&gt;
    ALTER DATABASE AxDB SET RECOVERY SIMPLE;
    DBCC SHRINKFILE('AxDb_New_log', 0, TRUNCATEONLY);
    ALTER DATABASE AxDB SET RECOVERY FULL;
    &lt;/pre&gt;
    &lt;p&gt;Replace &lt;code&gt;'AxDb_New_log'&lt;/code&gt; with the actual log file name you noted earlier.&lt;/p&gt;
 
    &lt;h3&gt;Step 3: Start DB synchronization again...this time it should work&lt;/h3&gt;
   &lt;p&gt;..&lt;/p&gt;
  &lt;a href="https://kishoredynamics11.blogspot.com/2023/10/the-transaction-log-for-database-is.html" target="_blank" rel="noopener noreferrer"&gt;
    Follow "Dynamics World" blog also for some other approach
&lt;/a&gt;
    &lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Always ensure you have proper database backups before making changes to recovery models.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2025/02/fix-dynamics-365fo-synchronization.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/a/AVvXsEgMMpBeb1bbDlTrPqGudUGF4EbN5oele5Na2p1jKcK03BR-Q5YAr5k8_8o06GCeUsuV_jICHrQcB1TVLfCWQ4qCNJnadWaA3d9J3w3q4I_HjnRGqFlf-KXB9XLbKc_ie_gb_jp3bhN_T2Hg5Y5njMp977ViVhgASuJSXXAwpsVrD741MMnaowajyehEf3w=s72-c" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-5197515421067416038</guid><pubDate>Wed, 22 Jan 2025 15:03:00 +0000</pubDate><atom:updated>2025-01-22T07:03:23.768-08:00</atom:updated><title>Get Description of financial dimension value from SQL DB of D365FO </title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;meta name="description" content="Learn how to retrieve the description of a financial dimension value using SQL in D365FO."&gt;
    &lt;title&gt;Retrieve Financial Dimension Value Description using SQL Query in D365FO&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            margin: 20px;
            background-color: #f9f9f9;
            color: #333;
        }

        h1, h2 {
            color: #0044cc;
        }

        p {
            font-size: 1.1em;
        }

        code {
            background-color: #f4f4f4;
            padding: 5px;
            border-radius: 5px;
            font-family: monospace;
        }

        pre {
            background-color: #eaeaea;
            padding: 20px;
            border-radius: 5px;
            font-family: monospace;
        }

        .note {
            background-color: #fff9c4;
            border-left: 5px solid #fbc02d;
            padding: 10px;
            margin-top: 20px;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

    &lt;header&gt;
        &lt;h1&gt;How to Retrieve Financial Dimension Value Description with SQL in D365FO&lt;/h1&gt;
        &lt;p&gt;In this post, we will explore how to retrieve the description of a financial dimension value in an ERP or financial management system using a specific SQL query in D365FO.&lt;/p&gt;
    &lt;/header&gt;  

    &lt;section&gt;
        &lt;h3&gt;The Query&lt;/h3&gt;
        &lt;pre&gt;&lt;code&gt;
SELECT DIMATTVALUE.DISPLAYVALUE AS 'DIMENSIONVALUE',
       DIMATT.NAME AS 'FINANCIALDIMENSION',
       DIMATTVALUE.ISSUSPENDED,
       HCMWORKER.PERSONNELNUMBER AS 'OWNER',
       DimFinTag.DESCRIPTION
FROM DIMENSIONATTRIBUTEVALUE AS DIMATTVALUE
LEFT JOIN HCMWORKER ON DIMATTVALUE.OWNER = HCMWORKER.RECID
JOIN DIMENSIONATTRIBUTE AS DIMATT ON DIMATT.RECID = DIMATTVALUE.DIMENSIONATTRIBUTE
JOIN DIMENSIONATTRIBUTEDIRCATEGORY dimAttDirCategory 
ON dimAttDirCategory.DIMENSIONATTRIBUTE = DIMATTVALUE.DIMENSIONATTRIBUTE
JOIN DIMENSIONFINANCIALTAG DimFinTag ON DIMATTVALUE.DISPLAYVALUE = DimFinTag.VALUE 
AND DimFinTag.FINANCIALTAGCATEGORY = dimAttDirCategory.DIRCATEGORY
WHERE DIMATTVALUE.ISDELETED = 0
  AND DIMATTVALUE.ISSUSPENDED = 0
        &lt;/code&gt;&lt;/pre&gt;

     
    &lt;/section&gt;    

    &lt;footer&gt;
        &lt;p&gt;Feel free to leave a comment below if you have any questions or need further clarification on the query or its results!&lt;/p&gt;
    &lt;/footer&gt;

&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2025/01/get-description-of-financial-dimension.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-1130191139332830961</guid><pubDate>Tue, 14 Jan 2025 05:20:00 +0000</pubDate><atom:updated>2025-01-13T21:20:08.809-08:00</atom:updated><title>Call custom service with JSON body in D365FO</title><description>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Call Custom Service with JSON Body in D365FO&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Call Custom Service with JSON Body in D365FO&lt;/h1&gt;
    &lt;pre style="background-color: #f4f4f4; padding: 10px; border-radius: 5px;"&gt;
        &lt;code&gt;
FileUploadTemporaryStorageResult fileUpload = File::GetFileFromUser() as FileUploadTemporaryStorageResult;
System.IO.Stream stream = fileUpload.openResult();
str responceJson;

using (var reader = new System.IO.StreamReader(stream))
{
    responceJson = reader.ReadToEnd();

    TESTPOReceiptRequestContract contract = FormJsonSerializer::deserializeObject(
        classnum(TESTPOReceiptRequestContract), responceJson);

    new TESTPOReceiptService().processRecord(contract);
}
        &lt;/code&gt;
    &lt;/pre&gt;
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2025/01/call-custom-service-with-json-body-in.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-4806389145927663678</guid><pubDate>Fri, 19 Jul 2024 11:33:00 +0000</pubDate><atom:updated>2024-07-19T04:33:45.729-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">d365fo</category><category domain="http://www.blogger.com/atom/ns#">Dynamics 365
Finance and Operations</category><category domain="http://www.blogger.com/atom/ns#">Inventory Management</category><category domain="http://www.blogger.com/atom/ns#">Microsoft Dynamics
D365 Development</category><category domain="http://www.blogger.com/atom/ns#">Partial Product Receipt</category><category domain="http://www.blogger.com/atom/ns#">Procurement Process</category><category domain="http://www.blogger.com/atom/ns#">Purchase Order</category><category domain="http://www.blogger.com/atom/ns#">X++ Code</category><title>How to Post Partial Product Receipt in D365FO Using X++ Code</title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;How to Post Partial Product Receipt in D365FO Using X++ Code&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;How to Post Partial Product Receipt in D365FO Using X++ Code&lt;/h1&gt;
    &lt;p&gt;Handling partial product receipts in Microsoft Dynamics 365 for Finance and Operations (D365FO) can be crucial for businesses that receive shipments in stages. In this blog, we'll explore how to post a partial product receipt using X++ code. We'll refer to a specific code example to guide us through the process.&lt;/p&gt;
    
    &lt;h2&gt;Introduction&lt;/h2&gt;
    &lt;p&gt;Partial product receipt refers to the process of receiving a portion of the goods ordered rather than the entire quantity. This is common in scenarios where suppliers deliver products in multiple shipments. Posting partial product receipts accurately in D365FO ensures that inventory records reflect the actual quantities received.&lt;/p&gt;
    
    &lt;h2&gt;Code Example Overview&lt;/h2&gt;
    &lt;p&gt;Here's an example of X++ code that demonstrates how to post a partial product receipt. This example focuses on receiving a specific quantity of a purchase order line.&lt;/p&gt;
    
    &lt;pre&gt;
&lt;code&gt;
internal final class POReceiptJobTest
{
    /// &lt;summary&gt;
    /// Class entry point. The system will call this method when a designated menu 
    /// is selected or when execution starts and this class is set as the startup class.
    /// &lt;/summary&gt;
    /// &lt;param name = "_args"&gt;The specified arguments.&lt;/param&gt;
    public static void main(Args _args)
    {
       PurchTable                  purchTable;
       PurchFormLetter             purchFormLetter;
       PurchFormletterParmData     purchFormLetterParmData;
       PurchParmTable              purchParmTable;
       PurchLine                   purchLine;
       PurchParmLine               purchParmLine;

       ttsBegin;

       // Find the purchase order
       purchTable = PurchTable::find('000039');

       // Create PurchParamUpdate table
       purchFormLetterParmData = PurchFormletterParmData::newData(
                        DocumentStatus::PackingSlip,
                        VersioningUpdateType::Initial);

       purchFormLetterParmData.parmOnlyCreateParmUpdate(true);
       purchFormLetterParmData.createData(false);
       PurchParmUpdate purchParmUpdate = purchFormLetterParmData.parmParmUpdate();

       // Set PurchParmTable table
       purchParmTable.clear();
       purchParmTable.TransDate                = SystemDateGet();
       purchParmTable.Ordering                 = DocumentStatus::PackingSlip;
       purchParmTable.ParmJobStatus            = ParmJobStatus::Waiting;
       
       purchParmTable.Num                      = 'Test234567'; // PR
       purchParmTable.PurchId                  = purchTable.PurchId;
       purchParmTable.PurchName                = purchTable.PurchName;
       purchParmTable.DeliveryName             = purchTable.DeliveryName;
       purchParmTable.DeliveryPostalAddress    = purchTable.DeliveryPostalAddress;
       purchParmTable.OrderAccount             = purchTable.OrderAccount;
       purchParmTable.CurrencyCode             = purchTable.CurrencyCode;
       purchParmTable.InvoiceAccount           = purchTable.InvoiceAccount;
       purchParmTable.ParmId                   = purchParmUpdate.ParmId;
       purchParmTable.insert();

       // Set PurchParmLine table
       select purchLine
           where purchLine.PurchId     == purchTable.PurchId &amp;&amp;
           purchLine.LineNumber  == 1;
    
       purchParmLine.initFromPurchLine(purchLine);

       purchParmLine.ReceiveNow    = 5; // Partial quantity received
       purchParmLine.ParmId        = purchParmTable.ParmId;
       purchParmLine.TableRefId    = purchParmTable.TableRefId;
       purchParmLine.setQty(DocumentStatus::PackingSlip, false, true);
       purchParmLine.setLineAmount();
       purchParmLine.insert();

       // Post the packing slip
       purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);
       purchFormLetter.transDate(systemDateGet());
       purchFormLetter.proforma(false);
       purchFormLetter.specQty(PurchUpdate::All);
       purchFormLetter.purchTable(purchTable);
       purchFormLetter.parmParmTableNum(purchParmTable.ParmId);
       purchFormLetter.parmId(purchParmTable.ParmId);
       purchFormLetter.purchParmUpdate(purchFormLetterParmData.parmParmUpdate());
       purchFormLetter.run();

       ttsCommit;
    }
}
&lt;/code&gt;
    &lt;/pre&gt;
   
    &lt;p&gt;If you have any questions or need further assistance, feel free to leave a comment below!&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2024/07/how-to-post-partial-product-receipt-in.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-8590395455287169138</guid><pubDate>Tue, 16 Jul 2024 05:35:00 +0000</pubDate><atom:updated>2024-07-15T22:44:24.166-07:00</atom:updated><title>How to Return Date Difference in Dynamics 365 Finance and Operations (D365FO) Computed Column</title><description>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;How to Return Date Difference in Dynamics 365 Finance and Operations (D365FO) Computed Column&lt;/title&gt;
    &lt;style&gt;
        pre.code-block {
            background-color: #f4f4f4;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
            box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.1);
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;p&gt;In Dynamics 365 Finance and Operations (D365FO), computed columns can dynamically calculate and display values derived from other fields or system values. This guide will show you how to create a computed column that calculates the difference in days between a record's creation date and the current date.&lt;/p&gt;
    
    &lt;h2&gt;Steps to Create a Computed Column and Method&lt;/h2&gt;
    
    &lt;h3&gt;1. Define the Computed Column in the AOT&lt;/h3&gt;
    &lt;ol&gt;
        &lt;li&gt;Open Visual Studio and navigate to the Application Object Tree (AOT).&lt;/li&gt;
        &lt;li&gt;Expand the Data Dictionary node.&lt;/li&gt;
        &lt;li&gt;Right-click on &lt;strong&gt;Views&lt;/strong&gt; and select the custom view / Extension of standad view, where you want to add the computed column (e.g., &lt;em&gt;AllPOLinesView&lt;/em&gt;).&lt;/li&gt;
        &lt;li&gt;Click on &lt;strong&gt;New &amp;gt; Computed Column&lt;/strong&gt;.&lt;/li&gt;
        &lt;li&gt;Name your computed column (e.g., &lt;em&gt;ApprovalDays&lt;/em&gt;).&lt;/li&gt;
        &lt;li&gt;Set the &lt;strong&gt;ComputedColumnExpression&lt;/strong&gt; property to the method you will define for calculating the date difference (e.g., &lt;em&gt;AllPOLinesView::compColumnApprovalDays()&lt;/em&gt;).&lt;/li&gt;
    &lt;/ol&gt;
    
    &lt;h3&gt;2. Implement the Computed Column Method (&lt;code&gt;compColumnApprovalDays&lt;/code&gt;)&lt;/h3&gt;
    &lt;p&gt;Add the following method to your view's code to calculate the date difference:&lt;/p&gt;
    
    &lt;pre class="code-block"&gt;
&lt;code&gt;private static server str compColumnApprovalDays()
{
    return SysComputedColumn::getDateDiff(
                SysComputedColumn::returnField(tableStr(AllPOLinesView), identifierStr(PurchLine),
                                        fieldId2name(tableNum(PurchLine), fieldNum(PurchLine, CreatedDateTime))),
                SysComputedColumn::getCurrentUtcDate(),
                SysComputedColumnDatePart::Day);
}&lt;/code&gt;
    &lt;/pre&gt;
    
    &lt;p&gt;&lt;strong&gt;Explanation of the Method:&lt;/strong&gt;&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;code&gt;SysComputedColumn::returnField(tableStr(AllPOLinesView), identifierStr(PurchLine), fieldId2name(tableNum(PurchLine), fieldNum(PurchLine, CreatedDateTime)))&lt;/code&gt;: Retrieves the &lt;code&gt;CreatedDateTime&lt;/code&gt; field from the &lt;code&gt;PurchLine&lt;/code&gt; data source in the &lt;code&gt;AllPOLinesView&lt;/code&gt;.&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;SysComputedColumn::getCurrentUtcDate()&lt;/code&gt;: Gets the current UTC date.&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;SysComputedColumn::getDateDiff(...)&lt;/code&gt;: Computes the difference in days between the &lt;code&gt;CreatedDateTime&lt;/code&gt; field and the current UTC date.&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;SysComputedColumnDatePart::Day&lt;/code&gt;: Specifies that the date difference should be calculated in days.&lt;/li&gt;
    &lt;/ul&gt;
    
    &lt;h3&gt;3. Compile and Synchronize&lt;/h3&gt;
    &lt;ul&gt;
        &lt;li&gt;Compile your changes in Visual Studio.&lt;/li&gt;
        &lt;li&gt;Synchronize your database to reflect the changes in D365FO.&lt;/li&gt;
    &lt;/ul&gt;
    
    &lt;h2&gt;Using the Computed Column&lt;/h2&gt;
    &lt;p&gt;After setting up the computed column, it will automatically calculate and display the approval days based on the creation date (&lt;code&gt;CreatedDateTime&lt;/code&gt; field) for each record in the &lt;code&gt;AllPOLinesView&lt;/code&gt;.&lt;/p&gt;
    
    &lt;h2&gt;Example Usage&lt;/h2&gt;
    &lt;p&gt;Here’s how you can use the computed column in a form or report:&lt;/p&gt;
    &lt;ol&gt;
        &lt;li&gt;Navigate to the form or report that displays the &lt;code&gt;AllPOLinesView&lt;/code&gt;, also make sure ApprovalDays is added on report/Form.&lt;/li&gt;
        &lt;li&gt;The &lt;code&gt;ApprovalDays&lt;/code&gt; computed column will show the number of days between the creation date and the current date for each purchase order line.&lt;/li&gt;
    &lt;/ol&gt;
    
    &lt;h2&gt;Summary&lt;/h2&gt;
    &lt;p&gt;By following these steps, you can create a computed column in D365FO to calculate date differences dynamically. This method enhances data presentation and provides valuable insights based on the computed values. Computed columns like this one can automate calculations and streamline your business processes in D365FO.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2024/07/how-to-return-date-difference-in.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-2209013297203588494</guid><pubDate>Tue, 16 Jul 2024 05:13:00 +0000</pubDate><atom:updated>2024-07-15T22:16:20.429-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Data Management</category><category domain="http://www.blogger.com/atom/ns#">Database Integrity</category><category domain="http://www.blogger.com/atom/ns#">Dynamics 365 Finance and Operations</category><category domain="http://www.blogger.com/atom/ns#">ERP Systems</category><category domain="http://www.blogger.com/atom/ns#">Microsoft Dynamics Customization</category><category domain="http://www.blogger.com/atom/ns#">Partition</category><category domain="http://www.blogger.com/atom/ns#">RecId</category><category domain="http://www.blogger.com/atom/ns#">RecVersion</category><category domain="http://www.blogger.com/atom/ns#">Table Fields</category><category domain="http://www.blogger.com/atom/ns#">X++ Programming</category><title>Understanding RecVersion, RecId, and Partition Fields in Dynamics 365FO Tables</title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Understanding RecVersion, RecId, and Partition Fields in Dynamics 365FO Tables&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            margin: 20px;
        }
        .container {
            max-width: 800px;
            margin: auto;
        }
        h1, h2 {
            color: #333;
        }
        code, pre {
            background: #f4f4f4;
            padding: 10px;
            border-radius: 3px;
            display: block;
            margin: 10px 0;
            white-space: pre-wrap;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class="container"&gt;
        
        &lt;p&gt;In Dynamics 365 Finance and Operations (D365FO), the RecVersion, RecId, and Partition fields play crucial roles in the data management and integrity of tables. Here’s a detailed explanation of each:&lt;/p&gt;

        &lt;h2&gt;RecVersion&lt;/h2&gt;
        &lt;p&gt;&lt;strong&gt;Purpose:&lt;/strong&gt; The RecVersion field, also known as the "row version" field, is used for optimistic concurrency control.&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;Functionality:&lt;/strong&gt; It ensures data integrity when multiple users or processes attempt to update the same record simultaneously.&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; When a record is updated, the system checks the RecVersion value. If the RecVersion in the database matches the RecVersion of the record being updated, the update proceeds, and the RecVersion is incremented. If the values do not match, it means another user has updated the record, and the update will be rejected or retried, depending on the application logic.&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
        &lt;pre&gt;&lt;code&gt;public void updateRecord(TableName tableName, int someRecId, int expectedRecVersion, anytype newValue) 
{
    select forupdate tableName where tableName.RecId == someRecId;
    if (tableName.RecVersion == expectedRecVersion) 
    {
        tableName.SomeField = newValue;
        tableName.doUpdate();
    } 
    else 
    {
        // Handle the conflict, e.g., by retrying or notifying the user
    }
}&lt;/code&gt;&lt;/pre&gt;

        &lt;h2&gt;RecId&lt;/h2&gt;
        &lt;p&gt;&lt;strong&gt;Purpose:&lt;/strong&gt; The RecId field is a unique identifier for each record in a table.&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;Functionality:&lt;/strong&gt; It acts as the primary key for the table and is automatically managed by the system.&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; When a new record is inserted, the system assigns a unique RecId. This ensures that each record can be uniquely identified and referenced.&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;Use cases:&lt;/strong&gt;&lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;Foreign key references in related tables.&lt;/li&gt;
            &lt;li&gt;Efficient lookups and indexing.&lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
        &lt;pre&gt;&lt;code&gt;public TableName findRecord(int someRecId) 
{
    select tableName where tableName.RecId == someRecId;
    if (tableName.RecId) 
    {
        // Record found, perform operations
    }
    return tableName;
}&lt;/code&gt;&lt;/pre&gt;

        &lt;h2&gt;Partition&lt;/h2&gt;
        &lt;p&gt;&lt;strong&gt;Purpose:&lt;/strong&gt; The Partition field is used for data partitioning in multi-tenant environments.&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;Functionality:&lt;/strong&gt; It allows for logical separation of data for different tenants within the same database.&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; Each tenant's data is tagged with a unique partition value. This enables the system to quickly segregate and manage data for different tenants.&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In the current versions of D365FO, the use of the Partition field has been deprecated, but it's still present for backward compatibility and in the underlying table structure.&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
        &lt;pre&gt;&lt;code&gt;public TableName findRecordByPartition(int currentPartition, int someRecId) 
{
    select tableName where tableName.Partition == currentPartition &amp;&amp; tableName.RecId == someRecId;
    return tableName;
}&lt;/code&gt;&lt;/pre&gt;

        &lt;h2&gt;Summary&lt;/h2&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;RecVersion:&lt;/strong&gt; Ensures data integrity by preventing conflicts during simultaneous updates.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;RecId:&lt;/strong&gt; Provides a unique identifier for each record, facilitating efficient data retrieval and relationships between tables.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Partition:&lt;/strong&gt; Used for data segregation in multi-tenant setups, though now deprecated in favor of other data isolation mechanisms.&lt;/li&gt;
        &lt;/ul&gt;

        &lt;p&gt;These fields are integral to maintaining the performance, scalability, and integrity of data in Dynamics 365 Finance and Operations.&lt;/p&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2024/07/understanding-recversion-recid-and.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-4736992882847971952</guid><pubDate>Thu, 04 Jul 2024 06:31:00 +0000</pubDate><atom:updated>2024-07-15T22:17:12.610-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">API Integration</category><category domain="http://www.blogger.com/atom/ns#">D365FO Customization</category><category domain="http://www.blogger.com/atom/ns#">Data Import</category><category domain="http://www.blogger.com/atom/ns#">Data Management</category><category domain="http://www.blogger.com/atom/ns#">Dynamics 365 Finance and Operations</category><category domain="http://www.blogger.com/atom/ns#">ERP Systems</category><category domain="http://www.blogger.com/atom/ns#">Import Package</category><category domain="http://www.blogger.com/atom/ns#">Microsoft Dynamics</category><category domain="http://www.blogger.com/atom/ns#">Postman</category><category domain="http://www.blogger.com/atom/ns#">REST API</category><title>Data management package REST API - Import package in dynamics 365FO using postman</title><description>
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;&lt;/meta&gt;
    &lt;meta content="width=device-width, initial-scale=1.0" name="viewport"&gt;&lt;/meta&gt;
    &lt;title&gt;Data Management Package REST API - Import Package in Dynamics 365FO Using Postman&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            margin: 20px;
        }
       
        pre {
            background: #f4f4f4;
            padding: 10px;
            border: 1px solid #ddd;
            overflow-x: auto;
            box-shadow: 0 4px 8px rgba(0,0,0,0.1);
        }

        img {
            max-width: 100%; /* Ensure images don't exceed their container */
            height: auto; /* Maintain aspect ratio */
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

    &lt;h1&gt;Data Management Package REST API - Import Package in Dynamics 365FO Using Postman&lt;/h1&gt;

    &lt;p&gt;Welcome to our comprehensive guide on using the Data Management Package REST API to import data into Dynamics 365 for Finance and Operations (Dynamics 365FO) efficiently. This tutorial will walk you through each step of the process using Postman.Please ensure your &lt;a href="https://learning.postman.com/docs/sending-requests/authorization/authorization-types/#bearer-token" target="_blank"&gt;Bearer token&lt;/a&gt; is generated before proceeding.&lt;/p&gt;
  
  &lt;p&gt;This same URL which i am going to use can be trigger from any third party system to integrate with dynamics D365 Finance and operations.&lt;/p&gt;

    &lt;h2&gt;Step 1: Create Import Project&lt;/h2&gt;
    &lt;p&gt;Create an import project in Data Management as shown below.&lt;/p&gt;
    &lt;img alt="Create Import Project" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_pbX7Qxq93las5vGB5-jBShj2JQ5uRPQGllm8Oh1OzD5vNdSOPOG-9eaboXru1DvFPdJ51xDbJi1kM0A8qPmERYDZnA4NS7365Tdta8bRtK5gawAWJUdJOyINgk5CplIdkK5gSEMXg0gxwL6qg5lUQzU82WECfp2b4NtwmrKakD7weiFVdonsiXyppnE/w640-h251/1.png" style="width: 640px;" /&gt;

    &lt;h2&gt;Step 2: Get Azure Write URL&lt;/h2&gt;
    &lt;p&gt;Post the &lt;code&gt;GetAzureWriteUrl&lt;/code&gt; request to the following endpoint:&lt;/p&gt;
    &lt;pre&gt;POST - {{resource}}/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetAzureWriteUrl&lt;/pre&gt;
    &lt;p&gt;Body:&lt;/p&gt;
    &lt;pre&gt;{
    "uniqueFileName": "CustomerGroupTestFile"
}&lt;/pre&gt;
    &lt;p&gt;A successful response from &lt;code&gt;GetAzureWriteUrl&lt;/code&gt; will provide the necessary URL for the next steps.&lt;/p&gt;
    &lt;img alt="Successful response of GetAzureWriteUrl" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7Rb687antI37Kxm7R8h_4be86QyH4kxWNg-9AFAxiOGYLDYaPAIPVec3-twMbnQTlL-JA3VirS5nF-2bRmgoP8G7CSMhQ6d6HXksT_3ZvZjJJVR3JBuqp339CpgEKTpCfJiO01YQUYXO2hNgrhsf6PC1KV9S3PbmSsgL31WzuTVt_uF4vhEcH8K1Q72c/w640-h328/3.png" style="width: 640px;" /&gt;

    &lt;h2&gt;Step 3: Generate Package&lt;/h2&gt;
    &lt;p&gt;You can generate the package in two ways:&lt;/p&gt;
    &lt;ol&gt;
        &lt;li&gt;Generate the package as shown in &lt;a href="https://d365fotechnicalblog.blogspot.com/2024/07/data-management-package-rest-api-export_3.html"&gt;this blog&lt;/a&gt;.&lt;/li&gt;
        &lt;li&gt;Generate the package by exporting it directly from the DMF project as shown below.&lt;/li&gt;
    &lt;/ol&gt;

    &lt;h3&gt;Steps to Export Package:&lt;/h3&gt;
    &lt;ol&gt;
        &lt;li&gt;Create an export project.&lt;/li&gt;
        &lt;li&gt;Run the export project.&lt;/li&gt;
        &lt;li&gt;Download the package as shown below.&lt;/li&gt;
    &lt;/ol&gt;
    &lt;img alt="Create Export Project" src="https://blogger.googleusercontent.com/img/a/AVvXsEg6lATyni7___RkW963C-HjXJ-EGUykE9iLbwkSliKDvA8JGaDPkfLzwLm7_8Igc6cWAnp2rF7bYU3TFUSP7eVkp5BBdpaHW7CPf06TUFT4AAFdJa1Eg3uEG5E45f6tpfwtK2fY5UO11u_CM840u-9d6QlDoPdqte-SW3HGV2Rr7F9LauC6bBgQDD7mfI4=w640-h436" style="width: 640px;" /&gt;

    &lt;img alt="Run Export Package" src="https://blogger.googleusercontent.com/img/a/AVvXsEiw-XHUWzIXk3zYKUGjiSZFwMeaQbjEygAJiQuk-LUpo4hYYXQnm_Qn580h0X_tv2VV8DAvSzBUAd94nQ0Yw8nBYopPiiXn6XAxASMlqSWZygoQxUYjAsYqYp9wrGDfGDXeJQAWfadn7bGbBSU8S2RnoQ_-XdLFsSffwZGnIAwRWoTEOXyMibU0Fr4IwRw=w640-h202" style="width: 640px;" /&gt;
  
  &lt;h3&gt;&lt;p&gt;Prepare your template in an Excel file.&lt;/p&gt;&lt;/h3&gt;
  
  &lt;img alt="Download Package" src="https://blogger.googleusercontent.com/img/a/AVvXsEi5jdpov5KpYxsr-futlyFdsjJh0P4L9tky_2SWvRyBE3xjBzobU0VDkvFFmkXzhLcFCk_NSgEyHbzymayTrPUllXBdWFsioIeD-F2xorF7_1ILCRFOX0yq__3XNJxjOAhXp52GYJf3ly7NlkB7k5G8eyblpNjphVDFVQ16KMYHBwJ7hOrb22_mWJrr6sM=w640-h76" style="width: 640px;" /&gt;

  &lt;h3&gt;&lt;p&gt;Save it as a Zip. Ensure the Zip contains only the three files shown below.&lt;/p&gt;&lt;/h3&gt;
   
    &lt;img alt="Extracted Files" src="https://blogger.googleusercontent.com/img/a/AVvXsEj0JsSDUcYUhK2jEVjbq1Py8N6fExJ0deher5Z0VVXrLxKPYJsyQbnggCcxqW6mjyinPQklE2Mi_ip_U4Zs72ainta8dExhytekQxQ4QTmqKkmYrwha1snAMMQONiOhyyPmPy_0t6PXk26RdXWYRK2Ze2Yx_duNn729Rw6j4kbJwVArCZt42QIVgCoQzhk=w640-h134" style="width: 640px;" /&gt;

    &lt;h2&gt;Step 4: Upload Package&lt;/h2&gt;
    &lt;h3&gt;&lt;p&gt;Copy the highlighted blob URL from the previous response of &lt;code&gt;GetAzureWriteUrl highlited in below screen response section.&lt;/code&gt;.&lt;/p&gt;&lt;/h3&gt;
    &lt;img alt="Highlighted Blob URL" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2pNmLg26FtNgasMV3URL5eKEFTCPc5g__-ZLE-CF34VbCjsVFTZxNhmLAWuArG5Ul05WTzz7YKSAlNcDX4nnVeBrWdKpCJLuLWxp_lqUvnlEL1_jjyYDCKQosanX8HanPmJ5Ul37oVRbWIbR_j8NsasslVngDXoDV28y5haIP88kDkdoA4YSYk3uykf0/w640-h290/4.png" style="width: 640px;" /&gt;

    &lt;h3&gt;&lt;p&gt;Paste the URL in the URL section select Put method.&lt;/p&gt;&lt;/h3&gt;
    &lt;img alt="Paste URL and Set Parameters" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOkQUycHvsk3LWniAILo-IT2d5qkq8dbdaC-zZ2O76xwDpYp93MoYGn1rFlDjaLIBintSyZm0gw4gMadTKzktQqYX1BF-d-FpIWb0EL_N9VCznn16Nfqq44LQmdEfBPC4Xe6LA4c5n6e48KJ6Lcrk6OeRQaCq87rYO6qXnGB85nZUqlpUv-FI2eqWp3-M/w640-h160/5.png" style="width: 640px;" /&gt;

    &lt;h3&gt;&lt;p&gt;Set the below parameter &lt;code&gt;x-ms-blob-type to BlockBlob&lt;/code&gt;.&lt;/p&gt;&lt;/h3&gt;
    &lt;img alt="Set Blob Type" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihnmdyT-ooacFBNg04-GifY046PZUF5xmDIwWX-o-LZxahcEYoFa_E07fyFJj8mYDz9PWdhGgSVQLvcXGAh64tjmrfAUTWVfxHFjFdYPo5CwEdF7qChBNlp3_1c7ji2HjfTdu0rsv_Fbspfv2nJT2q5F3XoWDfp2XoE_O4gnsDIh4MZsXFuAKEqWL921s/w640-h246/6.png" style="width: 640px;" /&gt;

   &lt;h3&gt; &lt;p&gt;After sending the request, you will receive the response shown below:&lt;/p&gt;&lt;/h3&gt;
    &lt;img alt="Response After Send" src="https://blogger.googleusercontent.com/img/a/AVvXsEguKwYH6ejULCzhKOnjScfnrHZrVbjZJqHnba2C5mF8RZTf4-aapkE9v5rbtn0p76-x2nH4tTC0Jt6ZjNTDRGEeiydOHRpYrXuPUtr0kEBHVT3PmX1IdIufHr4D4QxhRhdyTo8xzIxDiUp7K6rNp_SXj0OBGP-xNna4XCThSfp5a6uucRzbk8xylBdmX8w=w640-h284" style="width: 640px;" /&gt;

    &lt;h2&gt;Step 5: Import From Package&lt;/h2&gt;
    &lt;p&gt;Post the &lt;code&gt;ImportFromPackage&lt;/code&gt; request with the following body:&lt;/p&gt;
    &lt;pre&gt;POST : {{resource}}/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.ImportFromPackage

Body:
{
    "packageUrl": "URL on which we have uploaded the package.",
    "definitionGroupId": "VendorGroupsFileImport",
    "executionId": "",
    "execute": true,
    "overwrite": true,
    "legalEntityId": "USMF"
}&lt;/pre&gt;

  &lt;img alt="Import From Package" src="https://blogger.googleusercontent.com/img/a/AVvXsEhTWOE4kzSLCgFZGGTKn33QnCWwtPQWe25uAooYNycsFC_ydvT4YdAZNDfmpeB8lnB-VNypAMqkqs6bAjUVc14jvMW3377IymDG8Oi3lvNzPDtSU3HKZFNaCayrwCCg4ysqsNotMQIRkhvk_kfHishW8_RaujfpMDw2W5EmJ6tc1h7TrRYKAUJXhCb__PE=w640-h206" style="width: 640px;" /&gt;
  
    &lt;h3&gt;Headers for ImportFromPackage&lt;/h3&gt;
    &lt;img alt="Headers for ImportFromPackage" src="https://blogger.googleusercontent.com/img/a/AVvXsEhGhAhkkmxDDUoup1Cm7HBM2eeaN055N7v5Kx3ZAA7ID_gq3oIpm6-GAVUE_SVHOpJPPCZlhwnJHL709FCpREDTINP_Fn-rfZWVNRZrMs4GlyPmS7CXwhjc-H1qqXn9pUfNabE1518Z3HbxxGZaMR1puN4A4NZrFCNnVP_HAPgvMmKzKcKx9T5OGBamEA4=w640-h180" style="width: 640px;" /&gt;

  &lt;h3&gt;The response of ImportFromPackage &lt;/h3&gt;
    &lt;img alt="Response of ImportFromPackage" src="https://blogger.googleusercontent.com/img/a/AVvXsEjt5AP1jSH-6ngozLDCKNfve8dcJHaRq4a444N5-uiD5z_2FARu8e5Ur4uSCzZLO1ErFiRyJzXd20BAPp7bhNJnIFRomPsssoCljaDQRNodTA_6xwZzuIxYV9h8RaT0HtyPur4Q_Q6bSkccMNlyZLJb1rSeBZJUxw86pX_rk9QTsqnrjr1v3-7JXuGeIrk=w640-h308" style="width: 640px;" /&gt;
  
  &lt;h3&gt; New batch history record created under the import group.&lt;/h3&gt;
   &lt;img alt="Headers for ImportFromPackage" src="https://blogger.googleusercontent.com/img/a/AVvXsEi0BPdKGKbGfUISA1Dv3IJUlAUsst7bT8gh3wPc1evbYuMt47cAaJIHWAzLT2LN4VtBt7cV1aoe5jgdSLq5TqzYqvIQABFTiZTdPVnaYwkxp6Ugy2blvaTcdNtuXB_PobnWWyTBoGlFDYeNQdBTDSiKgNf3kb8dEO59JTWj-ZZ0GqcglpvP-dzUT2EGVP4=w640-h196" style="width: 640px;" /&gt;

    &lt;h2&gt;Conclusion&lt;/h2&gt;
    &lt;p&gt;By following these detailed steps, you can effectively manage data imports using the Data Management Package REST API in Dynamics 365FO. This approach not only ensures accuracy but also enhances the efficiency of handling large data sets within your organization.&lt;/p&gt;

&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2024/07/data-management-package-rest-api-import.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_pbX7Qxq93las5vGB5-jBShj2JQ5uRPQGllm8Oh1OzD5vNdSOPOG-9eaboXru1DvFPdJ51xDbJi1kM0A8qPmERYDZnA4NS7365Tdta8bRtK5gawAWJUdJOyINgk5CplIdkK5gSEMXg0gxwL6qg5lUQzU82WECfp2b4NtwmrKakD7weiFVdonsiXyppnE/s72-w640-h251-c/1.png" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-4182097402490915041</guid><pubDate>Wed, 03 Jul 2024 10:58:00 +0000</pubDate><atom:updated>2024-07-15T22:17:57.680-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">API Integration</category><category domain="http://www.blogger.com/atom/ns#">D365FO Customization</category><category domain="http://www.blogger.com/atom/ns#">Data Management</category><category domain="http://www.blogger.com/atom/ns#">Dynamics 365 Finance and Operations</category><category domain="http://www.blogger.com/atom/ns#">ERP Systems</category><category domain="http://www.blogger.com/atom/ns#">Export Package</category><category domain="http://www.blogger.com/atom/ns#">Microsoft Dynamics
Data Export</category><category domain="http://www.blogger.com/atom/ns#">Postman</category><category domain="http://www.blogger.com/atom/ns#">REST API</category><title>Data management package REST API - Export package in dynamics 365FO using postman</title><description>
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;&lt;/meta&gt;
    &lt;meta content="width=device-width, initial-scale=1.0" name="viewport"&gt;&lt;/meta&gt;
    &lt;title&gt;How to Export Data Packages in Microsoft Dynamics 365 finance and operations &lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;How to Export Data Packages in Microsoft Dynamics 365 finance and operations &lt;/h1&gt;
    &lt;p&gt;Hi All,&lt;/p&gt;
    &lt;p&gt;In this tutorial, we will guide you through the process of exporting data packages in Microsoft Dynamics 365. Please ensure your &lt;code&gt;&lt;a href="https://learning.postman.com/docs/sending-requests/authorization/authorization-types/#bearer-token" target="_blank"&gt;Bearer token&lt;/a&gt;&lt;/code&gt; is generated before proceeding.&lt;/p&gt;
     &lt;p&gt;This same URL which i am going to use can be trigger from any third party system to integrate with dynamics D365 Finance and operations.&lt;/p&gt;
    &lt;h2&gt;Step 1: Create a New Export Project in Data Management&lt;/h2&gt;
    &lt;p&gt;First, navigate to the Data Management workspace in Dynamics 365 and create a new export project. This project will define the data you wish to export.&lt;/p&gt;
    &lt;p&gt;&lt;img alt="Data Management Workspace" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoMyPY93CvFyEnTipa00LEblumnK_FfFUu_JFh0sjO7Kaj0RCh_xxbIHrpcZfn_CubHp1Lc4bWixFoml_Ok-HWutHCRvFE4CJbZ7aCZJw0QwXZ_efc8tew-wT6I7GW4v0HKcse-ebBt7XYzXa8VW4uI0LaQuP3blN_BHvFa7GJlQ3n3NKjr44PUN4XzvM/w640-h286/Untitled.jpg" width="640" width="640" /&gt;&lt;/p&gt;
    
    &lt;h2&gt;Step 2: ExportToPackage Request via Postman&lt;/h2&gt;
    &lt;p&gt;To export a package, you need to send a request from Postman. Here are the details you need:&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;strong&gt;{{resource}}&lt;/strong&gt;: Your Dynamics 365 URL&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;definitionGroupId&lt;/strong&gt;: Group name from the previous screenshot&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;packageName&lt;/strong&gt;: Desired name for the package&lt;/li&gt;
    &lt;/ul&gt;
    
    &lt;p&gt;&lt;strong&gt;POST :&lt;/strong&gt; {{resource}}/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.ExportToPackage&lt;/p&gt;
    &lt;pre&gt;
      Body:
      {
          "definitionGroupId":"VendorGroupsFileExport",
          "packageName":"VendorGroupPackage",
          "executionId":"VendorGroupExecutionId-1",
          "reExecute":false,
          "legalEntityId":"USMF"   
      }
    &lt;/pre&gt;
    
    &lt;p&gt;&lt;img alt="ExportToPackage Request in Postman" src="https://blogger.googleusercontent.com/img/a/AVvXsEgbThYUkm-ujl3S9heQ6CPnvHseyBcTLqtrrV7HUz35t18UIl_phqVynI7heg_U_Fw-A-RHU_wKddgupWMZFIBbjN3Gxj_Wql-mIwUw9OpUUumyrynGrQUdFJybHLRlWBpeL348qoctui4eOcmCbde7CBRTaz8-Vpe6UDrG1hnGZLx-OdJIfNUb9gb-TYI=w660-h246" width="640" /&gt;&lt;/p&gt;
    
    &lt;h2&gt;Successful Response of ExportToPackage request&lt;/h2&gt;
    &lt;p&gt;Upon successful execution, you will receive a response indicating that the export has been initiated.&lt;/p&gt;
    &lt;p&gt;&lt;img alt="Successful ExportToPackage Response" src="https://blogger.googleusercontent.com/img/a/AVvXsEisqxDlihS7IEyJTGN-3CpN2VsPZMcoc83OgFvtUWooFI4nMhPtDWjqwLY3PSxJMbMqW3uFE5NwyP8hFVfNwbt6cucCrLJScetJHfmU4hPHF33-6WGZA0XvZELeySxeMy8KRgskenYKVCemm3rmzsoP0yauFo1Y2XjGfsmO1oexyPhmxyklmlcCYQWX5p0=w590-h284" width="640" /&gt;&lt;/p&gt;
    
    &lt;h2&gt;Step 3: Check Export Status with GetExecutionSummaryStatus&lt;/h2&gt;
    &lt;p&gt;Next, check the status of your export by sending a GetExecutionSummaryStatus request.&lt;/p&gt;
    
    &lt;p&gt;&lt;strong&gt;POST Request:&lt;/strong&gt;&lt;/p&gt;
    &lt;pre&gt;
{{resource}}/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetExecutionSummaryStatus

Body:
{
    "executionId": "VendorGroupExecutionId-1"
}
    &lt;/pre&gt;
    
    &lt;p&gt;&lt;img alt="GetExecutionSummaryStatus Request in Postman" src="https://blogger.googleusercontent.com/img/a/AVvXsEg1sRBGxRFZwrd_HqIeRYxGi69lBWlkmauV38auEnz96iqysECMzM3yMJSIqlTkFat-HTzqUf2V9oMtUh06rYMnXvzvFBrivOGtJ_yPiVYPANI3ldW3l2V_nmAj4V1uHt_cEw3KkXZFhka23W5ZWb-mTEGQS9Fm3wqHNIjF5Ip6hrS6evfUnDN9a1EnCF8=w640-h162" width="640" /&gt;&lt;/p&gt;
    
    &lt;h2&gt;Successful Response of GetExecutionSummaryStatus request&lt;/h2&gt;
    &lt;p&gt;You will receive a response indicating the current status of your export.&lt;/p&gt;
    &lt;p&gt;&lt;img alt="Successful Check Export Status Response" src="https://blogger.googleusercontent.com/img/a/AVvXsEgeK2imqajiQr7UsDwYBw0w59m_I98KZ8vIT5ZNCFMMJgMCC0FihPcdww0pb_Dp6jRGAJaJh6cfVaEs7Re407Ofew0dX5nHtaa_A8EEdy5JIFCS7_sEM8xmBGxyzLq6SCFXg9_5B5dZS7OSpwv8Q4qiBM561URFgEFlscFi-pd4i-bBq7PNvyIpQnqascU=w591-h303" width="640" /&gt;&lt;/p&gt;
    
    &lt;h2&gt;Step 4: Retrieve the Exported Package URL&lt;/h2&gt;
    &lt;p&gt;Finally, retrieve the URL of the exported package with a GetExportedPackageUrl request.&lt;/p&gt;
    
    &lt;p&gt;&lt;strong&gt;POST Request:&lt;/strong&gt;&lt;/p&gt;
    &lt;pre&gt;
{{resource}}/data/DataManagementDefinitionGroups/Microsoft.Dynamics.DataEntities.GetExportedPackageUrl

Body:
{
    "executionId": "VendorGroupExecutionId-1"
}
    &lt;/pre&gt;
    
    &lt;p&gt;&lt;img alt="GetExportedPackageUrl Request in Postman" src="https://blogger.googleusercontent.com/img/a/AVvXsEhss4_z4yokVPFZvsYEk6qAeEA5YoZxD42yoDNu6f6vCmD_AV8fbtsT8rcSKrI_gTtSwmO5X0cFHnhN0u_AM8__sp08wgUOyEm4mPa5iXVrc1aPTZ7v9In6-_0qiZ0iimk72mQFRjUbQ1-gyDYCN21QBV4MXzfxBXgvt3-2wNIwhS7SicRsTcv-qYqQ0ek=w635-h151" width="640" /&gt;&lt;/p&gt;
    
    &lt;h2&gt;Successful Response of GetExportedPackageUrl request&lt;/h2&gt;
    &lt;p&gt;You will receive a response with a URL to download the exported package.&lt;/p&gt;
    &lt;p&gt;&lt;img alt="Successful GetExportedPackageUrl Response" src="https://blogger.googleusercontent.com/img/a/AVvXsEisKGYguqo-wCbl6zjCT8RqtaN3XxWi0Yhl_juiph7bp4MyN_hLxNkJWHdWPOdZYVY0gIP4CrdEpNPX-7L88LdhF3dButl9TBimsW0DmA5oLcUYs584a74AMDYgTkkxtu0nEOB4yGCvGFf7ExXEdlDBjqLvLw3L3-9oTYjX8iNvtI80fuDKZ6kCxk-1Ky0=w640-h340" width="640" /&gt;&lt;/p&gt;
    
    &lt;h2&gt;Download the Package&lt;/h2&gt;
    &lt;p&gt;Copy and paste the URL from the response into your browser to download the package.&lt;/p&gt;
    &lt;p&gt;&lt;img alt="Downloaded Package" src="https://blogger.googleusercontent.com/img/a/AVvXsEicKkT3TQSb6u7I5y-HL1yBahmgwhzTzPwuaPgeSJqdlXfFPcEl34fCcdGBxsizEX2sKpEDiubCQxFhc7mZAedQ8P0aa4GKrGG6ssfjyfF9mAgr1QBM1hFsY8fkkdS24yENQ54f-df4nwATY50n5zWsTdl917_wLowHoJaXBQwM8TdYPrJ5KhjNcNDVXh8=w640-h162" width="640" /&gt;&lt;/p&gt;
    
    &lt;p&gt;By following these steps, you can successfully export data packages in Microsoft Dynamics 365. If you have any questions, feel free to reach out in the comments below.&lt;/p&gt;
    
    &lt;p&gt;Happy exporting!&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2024/07/data-management-package-rest-api-export_3.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoMyPY93CvFyEnTipa00LEblumnK_FfFUu_JFh0sjO7Kaj0RCh_xxbIHrpcZfn_CubHp1Lc4bWixFoml_Ok-HWutHCRvFE4CJbZ7aCZJw0QwXZ_efc8tew-wT6I7GW4v0HKcse-ebBt7XYzXa8VW4uI0LaQuP3blN_BHvFa7GJlQ3n3NKjr44PUN4XzvM/s72-w640-h286-c/Untitled.jpg" width="72"/><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-1706336639387814370</guid><pubDate>Wed, 14 Feb 2024 06:04:00 +0000</pubDate><atom:updated>2024-04-04T05:10:51.592-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">How to post packing slip</category><category domain="http://www.blogger.com/atom/ns#">Post partial packing slip. how to post single line packing slip</category><category domain="http://www.blogger.com/atom/ns#">x++ code to post packing slip</category><title>Post partial packing slip in D365FO </title><description>
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;&lt;/meta&gt;
&lt;meta content="width=device-width, initial-scale=1.0" name="viewport"&gt;&lt;/meta&gt;
&lt;title&gt;How to Post a Partial Packing Slip in D365FO and AX 2012&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;h1&gt;How to Post a Partial Packing Slip in D365FO and AX 2012&lt;/h1&gt;

&lt;h2&gt;Understanding the Code&lt;/h2&gt;

&lt;p&gt;Below is the X++ code snippet demonstrating how to post a partial packing slip for a sales order:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public void postPartialPackingSlip(SalesId _salesId)
{
    SalesFormLetter_PackingSlip     salesFormLetter_PackingSlip;
    salesFormLetter                 salesFormLetter;
    salesFormletterParmData         salesFormLetterParmData;

    SalesParmTable                  salesParmTable;
    SalesParmLine                   salesParmLine;
    salesLine                       salesLine, salesLineUpd;
    salesParmUpdate                 salesParmUpdate;
    SalesTable                      salestable = SalesTable::find(_salesId, true);
    CustPackingSlipJour             custPackingSlipJour;
    TransDate                       packingSlipDate = DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone());
    InventDim                       inventDim;
    InventLocation                  inventLocation;

    ttsbegin;
    salesFormLetterParmData = salesFormletterParmData::newData(DocumentStatus::PackingSlip, VersioningUpdateType::Initial);

    salesFormLetterParmData.parmOnlyCreateParmUpdate(true);
    salesFormLetterParmData.createData(false);
    salesParmUpdate = salesFormLetterParmData.parmParmUpdate();

    salesParmTable.clear();
    salesParmTable.TransDate                = PackingSlipDate;
    salesParmTable.Ordering                 = DocumentStatus::PackingSlip;
    salesParmTable.ParmJobStatus            = ParmJobStatus::Waiting;
    salesParmTable.salesId                  = salesTable.salesId;

    salesParmTable.salesName                = salesTable.salesName;
    salesParmTable.DeliveryName             = salesTable.DeliveryName;
    salesParmTable.DeliveryPostalAddress    = salesTable.DeliveryPostalAddress;
    salesParmTable.CustAccount              = salesTable.CustAccount;
    salesParmTable.CurrencyCode             = salesTable.CurrencyCode;
    salesParmTable.InvoiceAccount           = salesTable.InvoiceAccount;
    salesParmTable.ParmId                   = salesParmUpdate.ParmId;
    salesParmTable.insert();

    while select salesLine 
        where salesLine.SalesId == salestable.SalesId
            Join InventDim 
            where inventdim.inventDimId == salesLine.InventDimId
                join inventLocation 
                where inventlocation.InventLocationId == inventdim.InventLocationId
                &amp;amp;&amp;amp; inventlocation.TestOwnWareHouse == NoYes::Yes
    {
  
        salesParmLine.InitFromsalesLine(salesLine);
        salesParmLine.DeliverNow    = salesLine.SalesQty;
        salesParmLine.ParmId        = salesParmTable.ParmId;
        salesParmLine.TableRefId    = salesParmTable.TableRefId;
        salesParmLine.setQty(DocumentStatus::PackingSlip, false, true);
        salesParmLine.setLineAmount(salesLine);
        salesParmLine.insert();
    }

    salesFormLetter_PackingSlip = salesFormLetter::construct(DocumentStatus::PackingSlip);
    salesFormLetter_PackingSlip.transDate(PackingSlipDate);
    salesFormLetter_PackingSlip.proforma(false);
    salesFormLetter_PackingSlip.specQty(salesUpdate::All);
    salesFormLetter_PackingSlip.salesTable(salesTable);
    salesFormLetter_PackingSlip.parmId(salesParmTable.ParmId);
    salesFormLetter_PackingSlip.salesParmUpdate(salesFormLetterParmData.parmParmUpdate());
    salesFormLetter_PackingSlip.run();
       
    if (salesFormLetter_PackingSlip.parmJournalRecord().TableId == tableNum(custPackingSlipJour))
    {
        custPackingSlipJour = salesFormLetter_PackingSlip.parmJournalRecord();
        info(custPackingSlipJour.packingSlipId)
    }
    ttscommit;
    
}&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Steps to Post a Partial Packing Slip&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Initialization:&lt;/strong&gt; The process begins by initializing necessary variables and objects, such as &lt;code&gt;salesFormLetter_PackingSlip&lt;/code&gt; and &lt;code&gt;salesParmUpdate&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Creating Sales Parameters:&lt;/strong&gt; Sales parameters are populated with relevant data from the sales order, such as customer details, delivery information, and currency.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Handling Sales Lines:&lt;/strong&gt; Iterate through sales lines associated with the sales order. For each line, initialize a &lt;code&gt;salesParmLine&lt;/code&gt; object and set relevant parameters. Ensure the line is associated with a warehouse (&lt;code&gt;TestOwnWareHouse == NoYes::Yes&lt;/code&gt;) before proceeding.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Generating the Packing Slip:&lt;/strong&gt; Use the &lt;code&gt;salesFormLetter_PackingSlip&lt;/code&gt; object to generate the packing slip. Set parameters such as transaction date and sales table details. Finally, execute the packing slip generation process.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Verifying the Packing Slip:&lt;/strong&gt; After generating the packing slip, verify if the process was successful by checking the &lt;code&gt;parmJournalRecord&lt;/code&gt;. If successful, retrieve relevant information such as the packing slip ID.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Automating the creation and posting of packing slips, including partial packing slips, streamlines the order fulfillment process in D365FO and AX 2012. By leveraging X++ code, businesses can ensure accuracy and efficiency in their shipping operations.&lt;/p&gt;

&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2024/02/post-partial-packing-slip-in-d365fo.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total><georss:featurename>India</georss:featurename><georss:point>20.593684 78.96288</georss:point><georss:box>-36.24694396225857 -61.66212 77.434311962258576 -140.41212000000002</georss:box></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-5404076075385857163</guid><pubDate>Fri, 15 Dec 2023 10:48:00 +0000</pubDate><atom:updated>2023-12-15T03:02:52.381-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">export contract class into JSON</category><category domain="http://www.blogger.com/atom/ns#">How to convert contract class to JSON</category><category domain="http://www.blogger.com/atom/ns#">list to JSON</category><title>JSON serialization in X++ </title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;JSON Serialization in X++&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            margin: 20px;
        }

        code {
            background-color: #f4f4f4;
            border: 1px solid #ddd;
            padding: 5px;
            display: block;
            margin-bottom: 10px;
            white-space: pre-wrap;
        }

        h2 {
            color: #333;
        }

        p {
            margin-bottom: 15px;
        }

        .json-output {
            border: 1px solid #ddd;
            padding: 10px;
            margin-top: 20px;
            background-color: #f8f8f8;
        }
      .json-input {
            border: 1px solid #ddd;
            padding: 10px;
            margin-top: 20px;
            background-color: #f8f8f8;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h2&gt;JSON Serialization in X++&lt;/h2&gt;

    &lt;h3&gt;TestCustTransExportRequest Class&lt;/h3&gt;
  &lt;p&gt;
        The &lt;b&gt;TestCustTransExportRequest&lt;/b&gt; class represents the request data for exporting customer transactions. 
    &lt;/p&gt;
    &lt;code&gt;
[datacontractAttribute]
class TestCustTransExportRequest
{
    String10 dataAreaId;
    CustAccount custAcc;

    [DataMemberAttribute("dataAreaId")]
    public String10 parmDataAreaId(String10 _dataAreaId = dataAreaId)
    {
        dataAreaId = _dataAreaId;
        return dataAreaId;
    }

    [DataMemberAttribute("CustomerAccount")]
    public CustAccount parmCustAcc(CustAccount _custAcc = custAcc)
    {
        custAcc = _custAcc;
        return custAcc;
    }
}
    &lt;/code&gt;

    &lt;h3&gt;TestCustTransListResponseContract Class&lt;/h3&gt;
 &lt;p&gt;
        The &lt;b&gt;TestCustTransListResponseContract&lt;/b&gt; class is a response data contract representing customer transaction details. This class includes properties for various transaction details such as type, date, amount, and currency. The &lt;b&gt;[DataMemberAttribute]&lt;/b&gt; attribute is used to specify the names of these properties in the serialized JSON.
    &lt;/p&gt;
    &lt;code&gt;
[datacontractAttribute]
class TestCustTransListResponseContract
{
    Str60 transType;
    ExchRate exchRate;
    String30 transDate;
    AmountCur amountCur;
    CurrencyCode currency;
    TransactionTextLarge description;
    AmountMST amountMST;
    AmountCur remainAmountBal;
    String10 dataAreaId;
    CustAccount custAcc;

    [DataMemberAttribute("Channel")]
    public String10 parmDataAreaId(String10 _dataAreaId = dataAreaId)
    {
        dataAreaId = _dataAreaId;
        return dataAreaId;
    }

    [DataMemberAttribute("Customer Id")]
    public CustAccount parmCustAcc(CustAccount _custAcc = custAcc)
    {
        custAcc = _custAcc;
        return custAcc;
    }

    [DataMemberAttribute("Transaction type")]
    public Str60 parmTransType(Str60 _transType = transType)
    {
        transType = _transType;
        return transType;
    }

    [DataMemberAttribute("Date")]
    public String30 parmTransDate(String30 _transDate = transDate)
    {
        transDate = _transDate;
        return transDate;
    }

    [DataMemberAttribute("Description")]
    public TransactionTextLarge parmDescription(TransactionTextLarge _description = description)
    {
        description = _description;
        return description;
    }

    [DataMemberAttribute("Amount in currency")]
    public AmountCur parmAmountCur(AmountCur _amountMST = amountCur)
    {
        amountCur = _amountMST;
        return amountCur;
    }

    [DataMemberAttribute("Currency")]
    public CurrencyCode parmCurrencyCode(CurrencyCode _currency = currency)
    {
        currency = _currency;
        return currency;
    }

    [DataMemberAttribute("Amount in accounting currency")]
    public AmountMST parmAmountMST(AmountMST _amountMST = amountMST)
    {
        amountMST = _amountMST;
        return amountMST;
    }

    [DataMemberAttribute("Exchange rate")]
    public exchRate parmExchRate(ExchRate _exchRate = exchRate)
    {
        exchRate = _exchRate;
        return exchRate;
    }

    [DataMemberAttribute("Balance")]
    public AmountCur parmRemainAmount(AmountCur _remainAmountBal = remainAmountBal)
    {
        remainAmountBal = _remainAmountBal;
        return remainAmountBal;
    }
}
    &lt;/code&gt;

    &lt;h3&gt;TestCustTransExportResponse Class&lt;/h3&gt;
  &lt;p&gt;
        The &lt;b&gt;TestCustTransExportResponse&lt;/b&gt; class represents the response data for exporting customer transactions. It contains a list of transaction data. This class is designed to be serialized into a JSON structure containing an array of transactions.
    &lt;/p&gt;
    &lt;code&gt;
class TestCustTransExportResponse
{
    List transactionData = new List(Types::Class);
    CustAccount custAcc;
    String10 dataAreaId;

    [DataMemberAttribute("Transactions"),DataCollectionAttribute(Types::Class, classStr(TestCustTransListResponseContract))]
    public List parmTransactionData(List _transactionData = transactionData)
    {
        transactionData = _transactionData;
        return transactionData;
    }
}
    &lt;/code&gt;

    &lt;h3&gt;TestCustTransExportService Class&lt;/h3&gt;
  &lt;p&gt;
        The &lt;b&gt;TestCustTransExportService&lt;/b&gt; class is a custom web service class that processes export transactions based on the provided request. It uses the other three classes to gather and structure the transaction data, and then returns the response in the specified JSON format.
    &lt;/p&gt;
    &lt;code&gt;
class TestCustTransExportService extends SysOperationServiceBase
{
    public TestCustTransExportResponse processExportTransaction(TestCustTransExportRequest _requestedCustomer)
    {
        TestCustTransExportResponse response = new TestCustTransExportResponse();
        CustTrans custTrans;
        List custTransactionsList = new List(Types::Class);
        CustAccount custAccount = _requestedCustomer.parmCustAcc();

        Microsoft.Dynamics.Ax.Xpp.ErrorException errorEx;
        try
        {
            changecompany(_requestedCustomer.parmDataAreaId())
            {
                while select  custTrans
                    where custTrans.AccountNum == custAccount
                    &amp;&amp; (custTrans.AmountCur - custTrans.SettleAmountCur) != 0
                {
                    TestCustTransListResponseContract custTransListContract = new TestCustTransListResponseContract();

                    custTransListContract.parmCustAcc(custTrans.AccountNum);
                    custTransListContract.parmDataAreaId(custTrans.DataAreaId);
                    custTransListContract.parmTransType(enum2Str(custTrans.TransType));
                    custTransListContract.parmTransDate(date2StrUsr(custTrans.TransDate));
                    custTransListContract.parmDescription(custTrans.Txt);
                    custTransListContract.parmamountCur(custTrans.AmountCur);
                    custTransListContract.parmAmountMST(custTrans.AmountMST);
                    custTransListContract.parmExchRate(custTrans.ExchRate);
                    custTransListContract.parmRemainAmount(custTrans.remainAmountCur());
                    custTransListContract.parmCurrencyCode(custTrans.CurrencyCode);
                    custTransactionsList.addEnd(custTransListContract);
                }
               
                response.parmTransactionData(custTransactionsList);
            }
        }
    
        catch(errorEx)
        {
            throw error(strFmt("Validation failed for customer %1.",custAccount, errorEx.Message));
        }
        catch (Exception::CLRError)
        {
            System.Exception ex = CLRInterop::getLastException();
            
            throw error(strFmt("Validation failed for customer %1.",custAccount, ex.Message));
        }
        return response;
    }

}
    &lt;/code&gt;
&lt;h2&gt;JSON Input&lt;/h2&gt;
   &lt;div class="json-input"&gt;
     &lt;pre&gt;
{
    "_requestedCustomer": 
    {
        "dataAreaId": "SE02",
        "CustomerAccount": "C0002"
    }
}
        &lt;/pre&gt;
    &lt;/div&gt;

    &lt;h2&gt;JSON Output&lt;/h2&gt;
    &lt;div class="json-output"&gt;
        &lt;pre&gt;
{
    "$id": "1",
    "Transactions": [
        {
            "$id": "2",
            "Channel": "Site1",
            "Customer Id": "TestCustomer",
            "Transaction type": "Sales order",
            "Date": "11/12/2023",
            "Description": "Credit IN000001VR6 SO SE02-12345VR6 11/12/2023",
            "Amount in currency": -2500.0,
            "Currency": "SEK",
            "Amount in accounting currency": -2500.0,
            "Exchange rate": 100.0,
            "Balance": -2500.0
        },
        {
            "$id": "3",
            "Channel": "Site1",
            "Customer Id": "TestCustomer",
            "Transaction type": "Sales order",
            "Date": "11/12/2023",
            "Description": "Credit IN000001VR7 SO SE02-12345VR7 11/12/2023",
            "Amount in currency": -2500.0,
            "Currency": "SEK",
            "Amount in accounting currency": -2500.0,
            "Exchange rate": 100.0,
            "Balance": -2500.0
        }
    ]
}
        &lt;/pre&gt;
    &lt;/div&gt;

   
&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2023/12/json-serialization-in-x.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-7339313133326817928</guid><pubDate>Wed, 13 Dec 2023 12:06:00 +0000</pubDate><atom:updated>2024-07-15T22:18:46.317-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Automation</category><category domain="http://www.blogger.com/atom/ns#">Batch Jobs</category><category domain="http://www.blogger.com/atom/ns#">Customization</category><category domain="http://www.blogger.com/atom/ns#">D365FO Development</category><category domain="http://www.blogger.com/atom/ns#">Dependent Tasks</category><category domain="http://www.blogger.com/atom/ns#">Dynamics 365 Finance and Operations</category><category domain="http://www.blogger.com/atom/ns#">ERP Systems</category><category domain="http://www.blogger.com/atom/ns#">Microsoft Dynamics</category><category domain="http://www.blogger.com/atom/ns#">Task Scheduling</category><category domain="http://www.blogger.com/atom/ns#">X++ Programming</category><title>Creating Dependent Tasks in Dynamics 365 Finance and Operations Batch Jobs with X++ Code</title><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;

&lt;head&gt;
  &lt;meta charset="UTF-8"&gt;
  &lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt;
  &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
  &lt;title&gt;Creating Dependent Tasks in Dynamics 365 Finance and Operations Batch Jobs with X++ Code&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;

  &lt;h1&gt;Creating Dependent Tasks in Dynamics 365 Finance and Operations Batch Jobs with X++ Code&lt;/h1&gt;

  &lt;p&gt;Batch processing is a critical component in handling large-scale data operations within Dynamics 365 Finance and Operations (D365FO). Often, there's a need to create dependent tasks within batch jobs to ensure proper sequencing and execution. In this blog post, we will explore how to create dependent tasks using X++ code in D365FO, based on the provided example.&lt;/p&gt;

  &lt;h2&gt;Understanding the Code&lt;/h2&gt;

  &lt;pre&gt;
    BatchHeader batchHeader = BatchHeader::construct();

// First task (your first batch job)
DMFBatchImporter batchImporter = new DMFBatchImporter();

batchImporter.batchInfo().parmBatchExecute(NoYes::Yes);
batchImporter.parmReadyForBatchRun(true);
DMFExecutionId batchExecutionId = DMFPackageImporter::PrepareDefinitionGroupForImport(definitionGroupName, executionId, dataAreaId, true);
batchImporter.parmExecutionId(batchExecutionId);

batchHeader.addTask(batchImporter);
batchHeader.addRuntimeTask(batchImporter, BatchHeader::getCurrentBatchTask().RecId);

// Add your second batch job here
TestIntegrationBatch integrationBatch = new TestIntegrationBatch();
integrationBatch.parmLogRecId(logRecId);
integrationBatch.batchInfo().parmGroupId(definition.BatchGroupId);

batchHeader.parmCaption(strFmt('%1 - Test Log - %2', TestIntegrationBatch::description(), logRecId));
// Add second task
batchHeader.addRuntimeTask(integrationBatch, BatchHeader::getCurrentBatchTask().RecId);
// Add dependency
batchHeader.addDependency(integrationBatch, batchImporter, BatchDependencyStatus::FinishedOrError);
batchHeader.save();

  &lt;/pre&gt;

  &lt;h2&gt;Step-by-Step Guide on Creating Dependent Tasks&lt;/h2&gt;

  &lt;ol&gt;
    &lt;li&gt;&lt;strong&gt;Batch Header Initialization:&lt;/strong&gt;
      &lt;p&gt;Create a new instance of &lt;code&gt;BatchHeader&lt;/code&gt; to represent the batch job.&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;First Task - DMFBatchImporter:&lt;/strong&gt;
      &lt;p&gt;Instantiate the primary task (&lt;code&gt;DMFBatchImporter&lt;/code&gt;).
        Set necessary parameters for batch execution.
        Prepare the execution ID using &lt;code&gt;DMFPackageImporter::PrepareDefinitionGroupForImport&lt;/code&gt;.
        Add the task to the batch header using &lt;code&gt;addTask&lt;/code&gt;.
        Add the task as a runtime task using &lt;code&gt;addRuntimeTask&lt;/code&gt;.&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Second Task - TestIntegrationBatch:&lt;/strong&gt;
      &lt;p&gt;Instantiate the secondary task (&lt;code&gt;TestIntegrationBatch&lt;/code&gt;).
        Set any required parameters for this task.&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Batch Header Configuration:&lt;/strong&gt;
      &lt;p&gt;Set the caption for the batch header for better identification.
        Add the secondary task as a runtime task.
        Define a dependency between tasks using &lt;code&gt;addDependency&lt;/code&gt;.
        In this case, the dependency is set to &lt;code&gt;FinishedOrError&lt;/code&gt;, meaning the second task will execute only when the first task finishes successfully or encounters an error.&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Save Batch Header:&lt;/strong&gt;
      &lt;p&gt;Save the configured batch header to persist the changes.&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;

  &lt;h2&gt;Conclusion&lt;/h2&gt;

  &lt;p&gt;Creating dependent tasks in batch jobs is essential for maintaining the proper flow of data processing in Dynamics 365 Finance and Operations. The provided X++ code showcases the integration of two tasks with a dependency relationship. Customize this example according to your specific business requirements and extend the logic as needed to handle more complex scenarios in your batch processing workflows.&lt;/p&gt;

&lt;/body&gt;

&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2023/12/creating-dependent-tasks-in-dynamics.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-6100379036965526758</guid><pubDate>Wed, 04 Oct 2023 07:14:00 +0000</pubDate><atom:updated>2024-07-19T06:57:19.631-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">How  to  send Lasernet report PDF on email</category><title>How  to  send Lasernet report PDF on email.</title><description>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Calling Lasernet Report from X++ Code in Dynamics 365 Finance and Operations&lt;/title&gt;
    &lt;meta name="author" content="Your Name"&gt;
    &lt;meta charset="UTF-8"&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;h1&gt;Calling Lasernet Report from X++ Code in Dynamics 365 Finance and Operations&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;Published on October 4, 2023 by Your Name&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hi All,&lt;/p&gt;

&lt;p&gt;I hope everybody is doing great and learning isn't stopped. Today, I am here with another article that will help us call a Lasernet report from X++ code in Dynamics 365 Finance and Operations. Let me explain my requirement. I have a requirement to send the SalesPackingSlipReport over email, but we don't want to use the standard report designs because we have implemented the ISV solution "Lasernet." So, here comes the challenge: how can we call it? I got some input from the below blog, but after that, I faced lots of problems, but finally, I have achieved it. &lt;/p&gt;
  
&lt;p&gt;&lt;a href="https://support.formpipe.com/guides/lasernet-for-dynamics-365-fo-user-guide/tutorial-model-how-to-start-query-based-lasernet-reports-from-x-class-per-code#how_to_call_lasernet_print_options_from_code_on_lasernet_query_report" target="_blank"&gt;Lasernet User Guide&lt;/a&gt;
&lt;/p&gt;
  
 &lt;p&gt;Prerequisites to follow &lt;br&gt;
  
   step 1 : 
  &lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;
class FPPrintReport
{
    public static void main(Args _args)
    {
        CustPackingSlipJour custPackingSlipJour = CustPackingSlipJour::findRecId(5637146826);
        FPPrintReport::sendPackingSlipByEmail('200030-SHI-UK01', custPackingSlipJour, 
        	'vijay.yelmame14@gmail.com', 'Test.pdf');
    }

    public static void sendPackingSlipByEmail(WHSShipmentId _shipmentId, 
    	CustPackingSlipJour custPackingSlipJour, Email _ToEmail, Filename _fileName)
    {
        CustFormletterParameters custFormParm = CustFormletterParameters::find();

        if (custFormParm.TestEnableEmailPackSlipReport)
        {
            SalesPackingSlipController formLetterController = SalesPackingSlipController::construct();
            SRSPrintDestinationSettings destinationSettings = new SRSPrintDestinationSettings();
            destinationSettings.printMediumType(SRSPrintMediumType::LAC);

            LACDestinationSettings LACDestinationSettings = new LACDestinationSettings();
            LACDestinationSettings.destTypes4Print(LACDestTypes4Print::Email);
            
            LACDestinationSettings.emailFrom(custFormParm.TestFromEmailAddress);
            LACDestinationSettings.emailTo(_ToEmail);
            LACDestinationSettings.emailSubject(strFmt(custFormParm.TestEmailSubject, _shipmentId));
            LACDestinationSettings.emailBody(custFormParm.TestEmailBody);
            LACDestinationSettings.allowForcedReRun(NoYes::Yes);
            LACDestinationSettings.emailFromName('Test Test');

            destinationSettings.lacDestinationSettings(LACDestinationSettings);

            LACReport report = LACReport::find(ssrsReportStr(Salespackingslip, Report));
            LACResendReport::resendReportFromRecord(report.ReportName, custPackingSlipJour, destinationSettings, true);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That's it! You can now follow these steps to call Lasernet reports from your X++ code in Dynamics 365 Finance and Operations. This solution should help you send your SalesPackingSlipReport over email using Lasernet.&lt;/p&gt;

&lt;p&gt;If you have any questions or encounter any issues, please feel free to ask. Happy coding!&lt;/p&gt;

&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2023/10/how-to-send-lasernet-report-pdf-on-email.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3112615091101096759.post-3628039989573164508</guid><pubDate>Mon, 21 Aug 2023 10:23:00 +0000</pubDate><atom:updated>2023-08-30T21:37:09.840-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Importing data through Data entities using X++</category><title>X++ Code to import file using data entity</title><description>&lt;div&gt;internal final class TestDataEntityImport&lt;/div&gt;&lt;div&gt;{&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; public static void main(Args _args)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; FileUploadTemporaryStorageResult&amp;nbsp; &amp;nbsp; fileUpload;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; AsciiStreamIo&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;file;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; System.IO.Stream&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; stream;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fileUpload&amp;nbsp; = File::GetFileFromUser() as FileUploadTemporaryStorageResult;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; file&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = AsciiStreamIo::constructForRead(fileUpload.openResult());&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; stream&amp;nbsp; &amp;nbsp; &amp;nbsp; = file.getStream();&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; TestDataEntityImport&amp;nbsp; TestDataEntityImport = new TestDataEntityImport();&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; TestDataEntityImport.importFromBlob(stream,fileUpload.getFileName());&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; public DMFDefinitionGroup findDMFDefinitionGroup(Filename&amp;nbsp; &amp;nbsp;_fileName)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DMFDefinitionGroup definitionGroup;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (strStartsWith(_fileName, 'Test'))&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; select firstonly definitionGroup&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; where definitionGroup.DefinitionGroupName == 'TestVendorPlantImport'; //DMF import data project&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return definitionGroup;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; public DMFDefinitionGroupEntity findDMFDefinitionGroupEntity(DMFDefinitionGroup _definitionGroup)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DMFDefinitionGroupEntity definitionGroupEntity;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DMFEntity dmfEntity;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; select firstonly RecId, Entity from definitionGroupEntity&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exists join dmfEntity&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; where definitionGroupEntity.DefinitionGroup == _definitionGroup.DefinitionGroupName&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;amp;&amp;amp; dmfEntity.EntityName == definitionGroupEntity.Entity;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!definitionGroupEntity)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; throw error(strFmt("@DMF:DMFNoEntityExists", _definitionGroup.DefinitionGroupName));&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return definitionGroupEntity;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; public DMFLocalFilePath applyTransforms(SharedServiceUnitFileID _uploadedStatement, DMFDefinitionGroup definitionGroup)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DMFDefinitionGroupEntity&amp;nbsp; &amp;nbsp; definitionGroupEntity = this.findDMFDefinitionGroupEntity(definitionGroup);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DMFExecutionId&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; executionId = DMFUtil::setupNewExecution(definitionGroup.DefinitionGroupName);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DMFDefinitionGroupExecution execution = DMFDefinitionGroupExecution::find(&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; definitionGroup.DefinitionGroupName,&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; definitionGroupEntity.Entity,&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; executionId,&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; true);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; execution.IsTransformed = NoYes::No;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DMFLocalFilePath filePath = execution.applyTransforms(_uploadedStatement);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DMFExecution e = DMFExecution::find(executionId, true);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; e.delete();&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return filePath;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; public void importFromBlob(System.IO.Stream&amp;nbsp; _memory, str _fileName)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SharedServiceUnitFileID&amp;nbsp; &amp;nbsp; &amp;nbsp;fileId;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DMFDefinitionGroup&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; definitionGroup;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DMFDefinitionGroupEntity&amp;nbsp; &amp;nbsp; definitionGroupEntity;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DMFExecutionId&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; executionId;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DMFDefinitionGroupExecution execution;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //Should be used to get file into FileUploadTemporaryStorageResult object&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; FileUploadTemporaryStorageResult result = File::SendFileToTempStore_GetResult(_memory, _fileName);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (result &amp;amp;&amp;amp; result.getUploadStatus())&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fileId = result.getFileId();&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; definitionGroup = this.findDMFDefinitionGroup(_fileName);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.applyTransforms(fileId, definitionGroup);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; definitionGroupEntity = this.findDMFDefinitionGroupEntity(definitionGroup);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; executionId = DMFUtil::setupNewExecution(definitionGroup.DefinitionGroupName);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Find execution&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; execution = DMFDefinitionGroupExecution::find(definitionGroup.DefinitionGroupName, definitionGroupEntity.Entity, executionId, true);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; execution.FilePath = fileId;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; execution.IsTransformed = NoYes::Yes;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; execution.IsSelected = NoYes::Yes;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; execution.ExecuteTargetStep = NoYes::Yes;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; execution.update();&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; setPrefix(strFmt("@SYS73667", _fileName));&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Import the file via quick import DMF&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DMFQuickImportExport::doPGImport(definitionGroup.DefinitionGroupName, executionId, true);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //deletes file&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result.deleteResult();&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Importing Files Using Data Management in D365FO/X++&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div&gt;
   &lt;p&gt;Data migration and integration are critical aspects of any business application, and Microsoft Dynamics 365 Finance and Operations (D365FO) offers a powerful toolset to facilitate these tasks. One of the key features for importing data is the Data Management framework (DMF). In this blog post, we'll explore how to use X++ code to import files using the Data Management framework in D365FO. This code is useful in scenarios where you want to call data entity import throgh integration and also by this code you dont need to worry about how many columns user is going to add later.&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;h2&gt;Background&lt;/h2&gt;
    &lt;p&gt;The X++ code provided in this blog post demonstrates how to import files using the Data Management framework in D365FO. This code is encapsulated within the &lt;code&gt;TestDataEntityImport&lt;/code&gt; class and consists of several methods that work together to achieve a successful file import.&lt;/p&gt;
    &lt;pre&gt;
&lt;code&gt;
internal final class TestDataEntityImport
{
    public static void main(Args _args)
    {
        FileUploadTemporaryStorageResult fileUpload;
        AsciiStreamIo file;
        System.IO.Stream stream;

        fileUpload = File::GetFileFromUser() as FileUploadTemporaryStorageResult;
        file = AsciiStreamIo::constructForRead(fileUpload.openResult());
        stream = file.getStream();
        
        TestDataEntityImport TestDataEntityImport = new TestDataEntityImport();
        TestDataEntityImport.importFromBlob(stream, fileUpload.getFileName());
    }

    public DMFDefinitionGroup findDefinitionGroup(Filename _fileName)
    {
        DMFDefinitionGroup definitionGroup;
        
        if (strStartsWith(_fileName, 'Test'))
        {
            select firstonly definitionGroup
             where definitionGroup.DefinitionGroupName == 'TestVendorPlantImport'; 
                //DMF import data project
        }

        return definitionGroup;
    }
    public DMFLocalFilePath applyTransforms(SharedServiceUnitFileID _uploadedStatement, DMFDefinitionGroup definitionGroup)
    {
        DMFDefinitionGroupEntity    definitionGroupEntity = this.findDMFDefinitionGroupEntity(definitionGroup);
        DMFExecutionId              executionId = DMFUtil::setupNewExecution(definitionGroup.DefinitionGroupName);

        DMFDefinitionGroupExecution execution = DMFDefinitionGroupExecution::find(
            definitionGroup.DefinitionGroupName,
            definitionGroupEntity.Entity,
            executionId,
            true);

        execution.IsTransformed = NoYes::No;
        DMFLocalFilePath filePath = execution.applyTransforms(_uploadedStatement);

        DMFExecution e = DMFExecution::find(executionId, true);
        e.delete();

        return filePath;
    }

	public void importFromBlob(System.IO.Stream _memory, str _fileName)
    {
        SharedServiceUnitFileID fileId;
        DMFDefinitionGroup definitionGroup;
        DMFDefinitionGroupEntity definitionGroupEntity;
        DMFExecutionId executionId;
        DMFDefinitionGroupExecution execution;

        // Should be used to get file into FileUploadTemporaryStorageResult object
        FileUploadTemporaryStorageResult result 
        	= File::SendFileToTempStore_GetResult(_memory, _fileName);

        if (result &amp;amp;&amp;amp; result.getUploadStatus())
        {
            fileId = result.getFileId();
            definitionGroup = this.findDefinitionGroup(_fileName);
            this.applyTransforms(fileId, definitionGroup);

            definitionGroupEntity = this.findDMFDefinitionGroupEntity(definitionGroup);
            executionId = DMFUtil::setupNewExecution(definitionGroup.DefinitionGroupName);

            // Find execution
            execution = DMFDefinitionGroupExecution::find(
                definitionGroup.DefinitionGroupName,
                definitionGroupEntity.Entity,
                executionId,
                true
            );
            
            execution.FilePath = fileId;
            execution.IsTransformed = NoYes::Yes;
            execution.IsSelected = NoYes::Yes;
            execution.ExecuteTargetStep = NoYes::Yes;
            execution.update();

            setPrefix(strFmt("@SYS73667", _fileName));

            // Import the file via quick import DMF
            DMFQuickImportExport::doPGImport(definitionGroup.DefinitionGroupName, executionId, true);

            // Deletes file
            result.deleteResult();
        }
    }
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;h2&gt;Getting Started&lt;/h2&gt;
    &lt;p&gt;The &lt;code&gt;main&lt;/code&gt; method serves as the entry point for the file import process. Let's break down the code step by step:&lt;/p&gt;
    &lt;ol&gt;
        &lt;li&gt;&lt;strong&gt;File Upload:&lt;/strong&gt; The code begins by getting a file from the user using the &lt;code&gt;File::GetFileFromUser()&lt;/code&gt; method. The file is uploaded and stored in temporary storage.&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;File Reading:&lt;/strong&gt; The uploaded file is then read using an &lt;code&gt;AsciiStreamIo&lt;/code&gt; object. This object provides methods to read data from the uploaded file.&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;Stream Handling:&lt;/strong&gt; The &lt;code&gt;stream&lt;/code&gt; variable is assigned the stream of the file data, which will be used to process the contents of the file.&lt;/li&gt;
    &lt;/ol&gt;
&lt;/div&gt;

&lt;!-- Continue explaining the rest of the code... --&gt;

&lt;div&gt;
    &lt;h2&gt;Conclusion&lt;/h2&gt;
    &lt;p&gt;In this blog post, we've explored how to use X++ code to import files using the Data Management framework in Dynamics 365 Finance and Operations. The provided code demonstrates the step-by-step process of uploading a file, identifying the appropriate DMF Definition Group and Entity, applying transformations, and executing the import.&lt;/p&gt;
    &lt;p&gt;The Data Management framework in D365FO simplifies data migration and integration tasks, enabling organizations to efficiently import and process large volumes of data. By leveraging the power of X++ and the DMF, businesses can ensure accurate and streamlined data management within their Dynamics 365 environment.&lt;/p&gt;
&lt;/div&gt;

&lt;/body&gt;
&lt;/html&gt;
</description><link>https://d365fotechnicalblog.blogspot.com/2023/08/x-code-to-import-file-using-data-entity_21.html</link><author>noreply@blogger.com (Vijay Yelmame)</author><thr:total>0</thr:total></item></channel></rss>