Blog

Name is Anant Dubey and the intent to create this blog is to discuss the problems and issues that developer face in the dynamics AX development and to share the new things that come up with the new version of AX.

Monday, March 24, 2025

configure Retail components on dev environment in D365FO

 


configure Retail components on dev environment


Configure retail re-targeting tool

k: deployable package/ select latest pkg/retail server/scripts/ 

open powershell with admin and run

retargetretailserver.ps1


Configure retail tenant update tool

k: deployable package/ select latest pkg/retail server/scripts/ 

open powershell with admin and run

RetailTenantUpdateTool.ps1


or

k:retailSDK/tools

run

Monday, January 13, 2025

Import Transfer Journal using CSV in AX 2012

Below is the CSV import format JournalID,itemId,FromSiteId,FromWarehouse,FromLocation,FromSize,FromColor,FromConfig,FromStyle,ToSiteId,ToWarehouse,ToLocation,ToSize,ToColor,ToConfig,ToStyle,Qty,CostPrice,CostAmount,dimcustomer, dimDepartment, dimEmployee, dimLocation, dimRetailStores, dimVendor INJ-019996,100185,2001,WH001,Stock,,White,A,KEN,2001,CW0001,Stock,,White,A,KEN,15,20,200,,,,2099-Whole,, ---------------------------------------------------------------------------------------------------------------- Below is the Dynamics AX Code static void ADImportTransferJournal(Args _args) { CommaTextIO csvFile; container readCon; Dialog dialog; DialogField dfFileName; FileName fileName; ItemId itemId; InventJournalTable inventJournalTable; InventJournalTrans inventJournalTrans; InventDim frominventDim, ToinventDim; JournalCheckPost inventJournalCheckPost; DimensionAttributeValueSetStorage valueSetStorage = new DimensionAttributeValueSetStorage(); DimensionDefault result; int i; DimensionAttribute dimensionAttribute; DimensionAttributeValue dimensionAttributeValue; container conAttr; container conValue, conLedgerDimension; str dimValue; DimensionDisplayValue dimcustomerFrom, dimDepartmentFrom, dimEmployeeFrom, dimLocationFrom, dimRetailStoresFrom, dimVendorFrom; DimensionDisplayValue dimcustomerTo, dimDepartmentTo, dimEmployeeTo, dimLocationTo, dimRetailStoresTo, dimVendorTo; #File dialog = new Dialog("Pick the file"); dfFileName = dialog.addField(extendedTypeStr("FilenameOpen")); dialog.filenameLookupFilter(['csv','*.csv']); if (dialog.run()) { csvFile = new CommaTextIo(dfFileName.value(), 'r'); csvFile.inFieldDelimiter(','); readCon = csvFile.read(); while(csvFile.status() == IO_Status::OK) { readCon = csvFile.read(); if(readCon) { inventJournalTable.JournalId = conPeek(readCon,1); itemId = conPeek(readCon,2); inventJournalTrans.clear(); inventJournalTrans.initFromInventJournalTable(inventJournalTable); inventJournalTrans.ItemId = itemId; frominventDim.InventSiteId= conPeek(readCon,3); frominventDim.InventLocationId= conPeek(readCon,4); frominventDim.wMSLocationId = conPeek(readCon,5); fromInventDim.InventSizeId = conPeek(readCon,6); fromInventDim.InventColorId = conPeek(readCon,7); fromInventDim.configId = conPeek(readCon,8); fromInventDim.InventStyleId = conPeek(readCon,9); ToinventDim.InventSiteId= conPeek(readCon,10); ToinventDim.InventLocationId= conPeek(readCon,11); ToinventDim.wMSLocationId = conPeek(readCon,12); ToinventDim.InventSizeId = conPeek(readCon,13); ToinventDim.InventColorId = conPeek(readCon,14); ToinventDim.configId = conPeek(readCon,15); ToinventDim.InventStyleId = conPeek(readCon,16); //ToinventDim.InventLocationId = "SD"; //ToInventDim.wMSLocationId = '11_A2'; //ToInventDim.InventSizeId = '1000'; //ToInventDim.inventBatchId = 'T20/0001/1'; ToinventDim = InventDim::findOrCreate(ToinventDim); frominventDim = InventDim::findOrCreate(frominventDim); inventJournalTrans.InventDimId = frominventDim.inventDimId; inventJournalTrans.initFromInventTable(InventTable::find(itemId)); inventJournalTrans.Qty = conPeek(readCon,17); inventJournalTrans.ToInventDimId = ToinventDim.inventDimId; //inventJournalTrans.CostAmount = InventJournalTrans.calcCostAmount(-abs(any2real(strReplace((strFmt('%1',inventJournalTrans.Qty))),',','.')))); //inventJournalTrans.CostAmount = InventJournalTrans.calcCostAmount(inventJournalTrans.Qty); inventJournalTrans.CostPrice = conPeek(readCon,18); inventJournalTrans.CostAmount = conPeek(readCon,19); dimcustomerFrom = conPeek(readCon,20); dimDepartmentFrom = conPeek(readCon,21); dimEmployeeFrom = conPeek(readCon,22); dimLocationFrom = conPeek(readCon,23); dimRetailStoresFrom = conPeek(readCon,24); dimVendorFrom = conPeek(readCon,25); inventJournalTrans.TransDate = str2Date(conpeek(readCon, 26), 213); //conPeek(readCon,26); //dimcustomerTo = conPeek(readCon,26); //dimDepartmentTo = conPeek(readCon,27); //dimEmployeeTo = conPeek(readCon,28); //dimLocationTo = conPeek(readCon,29); //dimRetailStoresTo = conPeek(readCon,30); //dimVendorTo = conPeek(readCon,31); conAttr = ["Customer", "Department", "Employee", "Location", "RetailStores", "Vendor"]; conValue = [dimcustomerFrom, dimDepartmentFrom, dimEmployeeFrom, dimLocationFrom, dimRetailStoresFrom, dimVendorFrom]; //conLedgerDimension = ["Customer", "Department", "Employee", "Location", "RetailStores", "Vendor"]; inventJournalTrans.LedgerDimension = 0; for (i = 1; i <= conLen(conAttr); i++) { dimensionAttribute = dimensionAttribute::findByName(conPeek(conAttr,i)); if (dimensionAttribute.RecId == 0) { continue; } dimValue = conPeek(conValue,i); if (dimValue != "") { dimensionAttributeValue = dimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,dimValue,false,true); valueSetStorage.addItem(dimensionAttributeValue); } } result = valueSetStorage.save(); inventJournalTrans.DefaultDimension = result; inventJournalTrans.JournalType = InventJournalType::Transfer; inventJournalTrans.insert(); } } } info("Imported Successfully"); //inventJournalCheckPost = InventJournalCheckPost::newJournalCheckPost(JournalCheckpostType::Post,inventJournalTable); //inventJournalCheckPost.parmThrowCheckFailed(1); //inventJournalCheckPost.parmShowInfoResult(1); //inventJournalCheckPost.run(); }

Import data through CSV in AX2012

static void ADUpdateInventTable(Args _args) { CommaTextIO csvFile; container readCon; Dialog dialog; DialogField dfFileName; FileName fileName; InventTable inventTable; ItemId itemId; //DirPartyContactInfoView contactView; #File dialog = new Dialog("Pick the file"); dfFileName = dialog.addField(extendedTypeStr("FilenameOpen")); dialog.filenameLookupFilter(['csv','*.csv']); if (dialog.run()) { csvFile = new CommaTextIo(dfFileName.value(), 'r'); csvFile.inFieldDelimiter(','); readCon = csvFile.read(); while(csvFile.status() == IO_Status::OK) { readCon = csvFile.read(); if(readCon) { itemId = conPeek(readCon,1); ttsBegin; select forUpdate inventTable where inventTable.ItemId == itemId; if(inventTable.Test == NoYes::Yes) { inventTable.Test = NoYes::No; inventTable.update(); } ttsCommit; info(itemId); } } } }

Wednesday, November 29, 2023

Encryption And Decryption Using A Symmetric Key(AES) using x++ in D365FO

 

Encryption And Decryption Using A Symmetric Key(AES) using x++

 Encryption And Decryption Using A Symmetric Key(AES) using x++.


I received a requirement to generate an XML file with encrypted data using a symmetric key. The recipients on the other side will decrypt the text using the same symmetric key. To test this, I used a dummy value such as 'RRR'.

To achieve this, I wrote the code in C# and added the resulting DLL to my project references.


C# Code:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace EncryptionDecryptionUsingSymmetricKey
{
    public class AesOperation
    {
        public static string EncryptString(string key, string plainText)
        {
            byte[] iv = new byte[16];
            byte[] array;

            using (Aes aes = Aes.Create())
            {
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.IV = iv;

                ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
                        {
                            streamWriter.Write(plainText);
                        }

                        array = memoryStream.ToArray();
                    }
                }
            }

            return Convert.ToBase64String(array);// It will convert bytes to string
        }

        public static string DecryptString(string key, string cipherText)
        {
            byte[] iv = new byte[16];
            byte[] buffer = Convert.FromBase64String(cipherText); // It will convert string to bytes
using (Aes aes = Aes.Create()) { aes.Key = Encoding.UTF8.GetBytes(key); aes.IV = iv; ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); using (MemoryStream memoryStream = new MemoryStream(buffer)) { using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, decryptor, CryptoStreamMode.Read)) { using (StreamReader streamReader = new StreamReader((Stream)cryptoStream)) { return streamReader.ReadToEnd(); } } } } } } }



X++ Code:

b14ca5898a4e4133bbce2ea2315a1916

Using EncryptionDecryptionUsingSymmetricKey;

internal final class TestRunnableClass1
{
    public static void main(Args _args)
    {
        str key = "b65ff7654brt8799fghj4ed7892b6798";
 
        str	text = 'RRR';
 
        str encryptedString = AesOperation::EncryptString(key, text);
 
        info(encryptedString);
 
        str decryptedString = AesOperation::DecryptString(key, encryptedString);
 
        info(decryptedString);
    }
}
References   Ref1  Ref2 and https://sheriffayed23.blogspot.com/2023/11/encryption-and-decryption-using.html

Wednesday, October 11, 2023

Get system notification in D365FO

 


  SystemNotificationDataContract notification = new SystemNotificationDataContract();

        notification.Users().value(1, curUserId());

        notification.Title("Delete Operation ended");

        notification.RuleId('StagingCleanup');

        notification.Message(strfmt("Deleted %1 records from TestTable and Total time consumed: %2",countRecord, timeConsumed(fromTime, timeNow())));

        notification.ExpirationDateTime(DateTimeUtil::addHours(DateTimeUtil::utcNow(), 48));


        SystemNotificationsManager::AddSystemNotification(notification);

Tuesday, September 5, 2023

override lookup method in Event handler and chain of command in d365fo

 link - https://dynamics365musings.com/override-an-existing-lookup-method-chain-of-command/


Two Ways To Override An Existing Lookup Method

There are actually two ways to override an existing lookup method.

I will explain both methods. No pun intended. Ultimately, I do not know that one way is preferred over the other. I am more partial to using Chain Of Command, because I find the attribute syntax easier to write. And I tend to put all of my other extension code in a Chain Of Command class. But please use whatever you are most comfortable with.

If you are new to Chain Of Command, I recommend you read this previous article on Chain Of Command Fundamentals.

The Example Scenario

In this section, consider the example that you want to override an existing lookup method on the customer details form. Go to customer form by searching for ‘all customers’ in the search bar. Then select a customer to open the customer details form.

The CustTable form, contains a field that lets a user select the customer group. By default this lookup method shows two columns. The customer group ID and the Description.

Let’s pretend we wish to show a third column. The related Customer Group form contains a field named ‘Terms of payment’. In this example, I will show you how to display additional columns in the lookup.

Override An Existing Lookup Using An Event Handler

In this previous article I showed you how you can use a form event handler to override an existing lookup. The key in this situation, is to use CancelSuperCall.

class TutorialCustTable_Form_Handler
{
    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    [FormControlEventHandler(formControlStr(CustTable, Posting_CustGroup), FormControlEventType::Lookup)]
    public static void Posting_CustGroup_OnLookup(FormControl sender, FormControlEventArgs e)
    {
        SysTableLookup      sysTableLookup  = SysTableLookup::newParameters(tableNum(CustGroup), sender);
        
        // Add the lookup columns
        sysTableLookup.addLookupfield(fieldNum(CustGroup, CustGroup));
        sysTableLookup.addLookupfield(fieldNum(CustGroup, Name));
        sysTableLookup.addLookupfield(fieldNum(CustGroup, PaymTermId));

        // Run the lookup
        sysTableLookup.performFormLookup();

        //cancel the call to super() to prevent the system from trying to show 
        //the lookup form twice and cause an error.
        FormControlCancelableSuperEventArgs cancelableSuperEventArgs = e as FormControlCancelableSuperEventArgs;
        cancelableSuperEventArgs.CancelSuperCall();
    }
}

Override An Existing Lookup Using Chain Of Command

Secondly, we will look at how to override an existing lookup using Chain Of Command. Create a new class, by right clicking on the project and select Add>Class. Name the class TutorialCustTable_Form_Extension.

Now that the class is created, we need to add the attribute to above the class definition to indicate to the compiler that code in this class extends the code in the form CustTable. See this article for how to use chain of command on form methods. Your code should look like this to start.

[ExtensionOf(formStr(CustTable))]
final class TutorialCustTable_Form_Extension
{
}

You may think that we need to add a chain of command class for the form control. However, in this case, we actually need to add form methods. Specifically, add an ‘init’ method and a lookup method. First, we will create a lookup method. And then the ‘init’ method, which gets called when the form first opens, will register our version of the lookup method.

First, add the lookup method. In this case, this is just a method that takes a form control object. It can actually be named something other than just ‘lookup’.

[ExtensionOf(formStr(CustTable))]
final class TutorialCustTable_Form_Extension
{
    public void overridenCustGroupLookup(FormStringControl _formControl)
    {
        SysTableLookup      sysTableLookup  = SysTableLookup::newParameters(tableNum(CustGroup), _formControl);

        // Add the lookup columns
        sysTableLookup.addLookupfield(fieldNum(CustGroup, CustGroup));
        sysTableLookup.addLookupfield(fieldNum(CustGroup, Name));
        sysTableLookup.addLookupfield(fieldNum(CustGroup, PaymTermId));

        // Run the lookup
        sysTableLookup.performFormLookup();
    }

}

Secondly, we need to extend the ‘init’ method to add code that will register the lookup method we just created and associate to the correct form control. The complete code should look like this.

[ExtensionOf(formStr(CustTable))]
final class TutorialCustTable_Form_Extension
{
    public void init()
    {
        next init();

        Posting_CustGroup.registerOverrideMethod(methodStr(FormDataObject, lookup), formMethodStr(CustTable, overridenCustGroupLookup));
    }

    public void overridenCustGroupLookup(FormStringControl _formControl)
    {
        SysTableLookup      sysTableLookup  = SysTableLookup::newParameters(tableNum(CustGroup), _formControl);

        // Add the lookup columns
        sysTableLookup.addLookupfield(fieldNum(CustGroup, CustGroup));
        sysTableLookup.addLookupfield(fieldNum(CustGroup, Name));
        sysTableLookup.addLookupfield(fieldNum(CustGroup, PaymTermId));

        // Run the lookup
        sysTableLookup.performFormLookup();
    }
}

In our example, the form control we needed to change the lookup for, had the ‘Auto Declaration’ property set to Yes. This meant we could simply use the name of the control, Posting_CustGroup, in our code. However, that is not always the case. If you need to reference a control that does not have this property set, you can find the control by adding an extra line of code. You still need to reference the control’s name. But this code still works even when the code does not have the ‘Auto Declaration’ property set to Yes. The ‘init’ method would then look like this.

public void init()
    {
        next init();

        FormStringControl custGroupControl = this.design().controlName(formControlStr(CustTable, Posting_CustGroup));
        custGroupControl.registerOverrideMethod(methodStr(FormDataObject, lookup), formMethodStr(CustTable, overridenCustGroupLookup));
    }

The method named registerOverrideMethod will tell the system what method to use as the lookup code for this form.

Demonstration

After adding all the code, save and compile your project.

In order to see your latest changes, reload the customer details form in your browser.

Finally, test out the overridden lookup method. You show now see all three columns showing in the lookup.

Override lookup method in d365fo

 

Override Lookup AX7 & D365FO



Here is the small example to override lookup ..


copy the lookup event handler of the field and  paste the event into any class




/// <summary>
    ///
    /// </summary>
    /// <param name="sender">receiving value in parameter</param>
    /// <param name="e">receiving value in parameter</param>
    [FormControlEventHandler(formControlStr(PayrollEmployerTaxRegion, Overview_StateId), FormControlEventType::Lookup)]
    public static void Overview_StateId_OnLookup(FormControl sender, FormControlEventArgs e)
    {
           /// write your lookup code here

if control or field already have lookup to we need to cancel parent lookup execution otherwise we will get exception.

below code you can use to cancel parent lookup ---
        FormControlCancelableSuperEventArgs ce = e as FormControlCancelableSuperEventArgs;
        //cancel super() to prevent error.
        ce.CancelSuperCall();
      }


Here is the complete code sample 


/// <summary>
    ///
    /// </summary>
    /// <param name="sender">receiving value in parameter</param>
    /// <param name="e">receiving value in parameter</param>
    [FormControlEventHandler(formControlStr(PayrollEmployerTaxRegion, Overview_StateId), FormControlEventType::Lookup)]
    public static void Overview_StateId_OnLookup(FormControl sender, FormControlEventArgs e)
    {
        SysTableLookup      sysTableLookup  = SysTableLookup::newParameters(tableNum(LogisticsAddressState), sender);
        Query               query           = new Query();

        // Filter lookup to only show US states
        query.addDataSource(tableNum(LogisticsAddressState)).addRange(fieldNum(LogisticsAddressState, CountryRegionId)).value(LogisticsAddressCountryRegion::findByISOCode(SysCountryRegionCode::countryInfo(curext())).CountryRegionId);

        // Sort the lookup by state Id
        query.dataSourceTable(tableNum(LogisticsAddressState)).addOrderByField(fieldNum(LogisticsAddressState, StateId), SortOrder::Ascending);

        // Add fields
        sysTableLookup.addLookupfield(fieldNum(LogisticsAddressState, StateId));
        sysTableLookup.addLookupfield(fieldNum(LogisticsAddressState, Name));

        // Run lookup
        sysTableLookup.parmQuery(query);
        sysTableLookup.performFormLookup();
        FormControlCancelableSuperEventArgs ce = e as FormControlCancelableSuperEventArgs;

        //cancel super() to prevent error.
        ce.CancelSuperCall();
    }


ref: - https://community.dynamics.com/blogs/post/?postid=c7132ede-dd1b-4408-a038-4354f0a2c7be

Thursday, June 1, 2023

Create Label in Visual studio in D365fo

 http://axbackup.com/AxLabelCreator/


http://axbackup.com/AxLabelCreator/release/AxLabelCreator.1.3.1.0.exe

http://axbackup.com/AxLabelCreator/release/AxLabelCreator.1.3.1.0.zip

Monday, May 22, 2023

How to Debug MPOS in D365FO

 click - Start -> developer mode

Enable it





Download Microsot Edge Dev tool preview

https://apps.microsoft.com/store/detail/microsoft-edge-devtools-preview/9MZBFRMZ0MNJ?hl=en-us&gl=US


check console window for any error


Tuesday, November 15, 2022

Table [ax].[GUPITEMBASEPRICE] does not exist, skip creating CONSTRAINT [ax].[GUPITEMBASEPRICE].[I_-1063074925_1429128816] Creating [DataSyncUsersRole] service upgrade in D365 fo on premise

 Error while upgrading service upgrade in On-premise environment in D365


usually this error occurs while upgrading between version 10.0.28 and 10.0.30.. may be appear in future as well

It's not a proper solution, but this workaround helped me...


usually this error occurs at step 57 or step 60.

1. I did manually create table AX.GUPItemBasePrice table in AXDB

(Needed to create this table because upgrade package had removed the "AX" schema and all tables were with "DBO" schema. upgrade package is looking for table in "AX" schema. Got to know from Error Logs)

USE [AXDB]

GO


/****** Object:  Table [ax].[GUPITEMBASEPRICE]    Script Date: 11/15/2022 12:41:45 AM ******/

SET ANSI_NULLS ON

GO


SET QUOTED_IDENTIFIER ON

GO


CREATE TABLE [ax].[GUPITEMBASEPRICE](

[RECID] [bigint] NOT NULL,

[ACTIVATIONDATE] [date] NOT NULL,

[INVENTDIMID] [nvarchar](20) NOT NULL,

[ITEMID] [nvarchar](100) NOT NULL,

[MARKUP] [numeric](32, 16) NOT NULL,

[MARKUPQTY] [numeric](32, 16) NOT NULL,

[PRICE] [numeric](32, 16) NOT NULL,

[PRICEALLOCATEMARKUP] [int] NOT NULL,

[PRICEQTY] [numeric](32, 16) NOT NULL,

[PRICETYPE] [int] NOT NULL,

[UNITID] [nvarchar](10) NOT NULL,

[FROMDATE] [date] NOT NULL,

[TODATE] [date] NOT NULL,

[CREATEDDATETIME] [datetime] NOT NULL,

[DATAAREAID] [nvarchar](4) NOT NULL,

[ROWVERSION] [timestamp] NOT NULL,

 CONSTRAINT [I_GUPITEMBASEPRICE_RECID] PRIMARY KEY CLUSTERED 

(

[RECID] ASC

)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY],

 CONSTRAINT [I_-1063074925_1429128816] UNIQUE NONCLUSTERED 

(

[ITEMID] ASC,

[INVENTDIMID] ASC,

[PRICETYPE] ASC,

[FROMDATE] ASC,

[TODATE] ASC,

[CREATEDDATETIME] ASC,

[DATAAREAID] ASC

)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_ACTIVATIONDATE]  DEFAULT ('1900-01-01') FOR [ACTIVATIONDATE]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_INVENTDIMID]  DEFAULT ('') FOR [INVENTDIMID]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_ITEMID]  DEFAULT ('') FOR [ITEMID]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_MARKUP]  DEFAULT ((0)) FOR [MARKUP]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_MARKUPQTY]  DEFAULT ((0)) FOR [MARKUPQTY]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_PRICE]  DEFAULT ((0)) FOR [PRICE]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_PRICEALLOCATEMARKUP]  DEFAULT ((0)) FOR [PRICEALLOCATEMARKUP]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_PRICEQTY]  DEFAULT ((0)) FOR [PRICEQTY]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_PRICETYPE]  DEFAULT ((0)) FOR [PRICETYPE]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_UNITID]  DEFAULT ('') FOR [UNITID]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_FROMDATE]  DEFAULT ('1900-01-01') FOR [FROMDATE]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_TODATE]  DEFAULT ('1900-01-01') FOR [TODATE]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_CREATEDDATETIME]  DEFAULT (getutcdate()) FOR [CREATEDDATETIME]

GO


ALTER TABLE [ax].[GUPITEMBASEPRICE] ADD  CONSTRAINT [DF_GUPITEMBASEPRICE_DATAAREAID]  DEFAULT ('dat') FOR [DATAAREAID]

GO


2. Removed all Roles from AXDB (Whichever is allowing to delete)

3. Removed all schemas from AXDB (Whichever is allowing to delete)

4. Execute below query in AXDB

DROP VIEW __RETAIL_PENDING_DEPLOYMENT

5. re-execute the step with below command

AXUpdateInstaller.exe execute -runbookid="Dev-runbook14112022" -rerunstep=60

Monday, September 5, 2022

Get on hand inventory in d365fo

 [ExtensionOf(tableStr(ReqPO))]

final class ReqPOTable_Extension

{

    public void insert(ReqPlanData _reqPlanData)

    {

        InventOnhand    inventOnHand, inventOnHandRWH;

        InventDim       inventDim;

        InventDimParm   inventDimParm;

        

        inventDim = InventDim::find(this.CovInventDimId);

        inventDimParm.initFromInventDim(inventDim);

        inventOnHand = InventOnhand::newParameters(this.ItemId, inventDim, inventDimParm);

        this.GKAvailPhysical = inventOnHand.availPhysical();


        inventOnHandRWH = InventOnhand::newItemId(this.ItemId);

        inventOnHandRWH.parmInventLocationId("TEST");


        this.GKAvailPhysicalRWH = inventOnHandRWH.availPhysical();

        //-------------------------------------------------------------------------------

        this.GKModelGroupId = InventModelGroupItem::findByItemIdLegalEntity(this.ItemId).ModelGroupId;

        //-------------------------------------------------------------------------------

        

        //-------------------------------------------------------------------------------


        EcoResProductCategory   EcoResProductCategory;

        EcoResCategory               EcoResCategory,EcoResCategoryNext;

        EcoResCategoryId            parentCategory;

        List                                    li = new List(Types::String);

        ListEnumerator                 enumer;


        select * from EcoResCategory

        join RecId from EcoResProductCategory

            where EcoResCategory.RecId == EcoResProductCategory.Category

            && EcoResProductCategory.Product == InventTable::find(this.itemId).Product;


        parentCategory = EcoResCategory.ParentCategory;


        while (parentCategory)

        {

            li.addStart(EcoResCategory.Name);


            select * from EcoResCategory

            where EcoResCategory.RecId ==  parentCategory

            && EcoResCategory.ParentCategory != 0;  // skip the top node


            parentCategory = EcoResCategory.ParentCategory;

        }


        enumer = li.getEnumerator();

        while (enumer.moveNext())

        {

            this.GKProductcategory = enumer.current();

        }


        next insert();

    }


}

Tuesday, August 23, 2022

Steps to upgrade or apply service update On-Premise environment in D365FO

To install Custom package on-premise environment

AXUpdateInstaller.exe devinstall

--------------------------------------------------------------------------------------------------

To install Service update package


Step 1: Download the service update package from LCS

Step 2: Right click and Unblock the package

Step 3: Extract to some folder like C:/Temp 

Step 4: go-to - C:/Temp/"Serive Update extracted folder"/RetailServer/Scripts

Step 5: search file "DropAllRetailChannelDbObjects.sql" and click edit on notepad, copy all code

Step 6: Open SQL and New query on AXDB -> paste the code and Execute

Step 7: go-to - C:/Temp/"Serive Update extracted folder"/DefaultTopologyData.XML(Open in notepad)

Step 8: search in notepad (LocalHost) and replace with PC name

Step 9: Paste the list of devTools list by executing AXUpdateInstaller.exe list(Inside CMD under same folder). Example below: -  

<Machine>

      <Name>TESTDEV001</Name>

      <ServiceModelList>

        <string>AOSService</string>

        <string>DevToolsService</string>

<string>ALMService</string>

<string>BIService</string>

<string>DIXFService</string>

<string>MROneBox</string>

<string>PayrollTaxModule</string>

<string>PerfSDK</string>

<string>ReportingService</string>

<string>RetailCloudPos</string>

<string>RetailHQConfiguration</string>

<string>RetailSDK</string>

<string>RetailSelfService</string>

<string>RetailServer</string>

<string>RetailStorefront</string>

      </ServiceModelList>

    </Machine>

Step 10: open CMD as admin and navigate to extracted folder. i.e. C:/Temp/"Serive Update extracted folder"

Step 11: Execute below commands: -  

AXUpdateInstaller.exe list

AXUpdateInstaller.exe generate -runbookid="Dev-runbook22082022-1" -topologyfile="DefaultTopologyData.xml" -servicemodelfile="DefaultServiceModelData.xml" -runbookfile="Dev-runbook22082022-1.xml"


AXUpdateInstaller.exe import -runbookfile="Dev-runbook22082022-1.xml"


AXUpdateInstaller.exe execute -runbookid="Dev-runbook22082022-1"

--------------------------------------------------------------------------------------------------

To re-run step: - 

AXUpdateInstaller.exe execute -runbookid="Dev-runbook22082022-1" -rerunstep=60

To mark step has completed: - 

AXUpdateInstaller.exe execute -runbookid="Dev-runbook22082022-1" -setstepcomplete=60

--------------------------------------------------------------------------------------------------

Additional Basic Troubleshooting solutions: - 

Unable to find Dynamics 365 Finance and operations extension: -

Solution - Check for service: - CNG Key Isolation

to install - C:\Temp\FinanceAndOperations_10.0.1265.20_Application\DevToolsService\Scripts

Microsoft.Dynamics.Framework.Tools.Installer.vsix

Any Step failed: - 

solution - Right click on extracted folder - Uncheck Read only option.

Wednesday, July 20, 2022

Enable developer mode of Retail POS in d365 how to check label text id of each button on CPOS in d365

 open cpos on edge

f12

setting

enable javascript source maps true

console

Commerce.Helpers.DeveloperModeHelper.setDeveloperMode(true);


Monday, July 18, 2022

Export Import Model in D365fo

CMD as admin

go to path-

 C:\AOSService\PackagesLocalDirectory\bin


Export - 


ModelUtil.exe -export -metadatastorepath=K:\AosService\PackagesLocalDirectory -modelname=CustomModel -outputpath=C:\Temp


Import-


ModelUtil.exe -import -metadatastorepath=C:\AOSService\PackagesLocalDirectory -file="C:\Temp\Custom Seperate Models\CustomModel.axmodel"


Each model might contains Resources folder which contains DLLs. Need to import seperately.

synchronize DB

Build the model


Thursday, March 17, 2022

Enable/ Disable or Hide/ Show new, edit, delete button on form in D365fo

 This is posts shows that how to enable disable or show hide system defined button on Form


FormCommandButtonControl attachButton; public void init() { #SysSystemDefinedButtons

//(This Macro contains all system defined buttons to be used on forms and you can play with

// and you play with all system defined buttons like command button, grid controls etc. super(); attachButton= this.control(this.controlId(#SystemDefinedAttachButton)) as FormCommandButtonControl; attachButton.visible(false); }


  public void init()
    {
        this.form().design().showNewButton(0);
        this.form().design().showDeleteButton(0);
        super();

    }

[ExtensionOf(FormStr(InventBatch))]
public final class P_InventBatchForm_Extension
{
    void run()
    {
        next run();
        inventBatch_ds.allowCreate(false); // Disable System Defined NEW Button
      }

}

ref: - System-defined buttons - Finance & Operations | Dynamics 365 | Microsoft Docs

Monday, December 13, 2021

Enter data from new line in SSRS and Formula in D365fo

 =Format(Fields!QuotationDate.Value, "MMM-dd yyyy") & Microsoft.VisualBasic.Constants.vbcrlf & Microsoft.VisualBasic.Constants.vbcrlf & Fields!CustomerName.Value & Microsoft.VisualBasic.Constants.vbcrlf & Fields!CustomerAddress.Value



 =Format(Fields!QuotationDate.Value, "MMM-dd yyyy") & vbcrlf & vbcrlf & Fields!CustomerName.Value & vbcrlf & Fields!CustomerAddress.Value


=Fields!PurchOrderDocNum.Value & vbcrlf & Format(Now(),"dd/MM/yyyy")


=IIF(Fields!CompLabelPrice.Value = "0.00",Nothing, Format(Fields!CompLabelPrice.Value, "#,0.00;(#,0.00)")) & " /-"

--------------------------------------------------------------------------------------------------------

To Get user specific date time on report

-

=Microsoft.Dynamics.Framework.Reports.DataMethodUtility.ConvertUtcToAxUserTimeZoneForUser(Parameters!AX_CompanyName.Value, Parameters!AX_UserContext.Value, System.DateTime.UtcNow, "d", Parameters!AX_RenderingCulture.Value) & vbCrLf & Microsoft.Dynamics.Framework.Reports.DataMethodUtility.ConvertUtcToAxUserTimeZoneForUser(Parameters!AX_CompanyName.Value, Parameters!AX_UserContext.Value, System.DateTime.UtcNow, "t", Parameters!AX_RenderingCulture.Value)

--------------------------------------------------------------------------------------------------------

Print every word with new line

=Replace(Fields!Text2.Value," ", System.Environment.NewLine)

--------------------------------------------------------------------------------------------------------


Print Page number on SSRS in D365 FO

Visual studio expression to print page number on every pages of report


 ="Page "&Globals!PageNumber &" of "&Globals!TotalPages

Saturday, December 11, 2021

Insert User ID in All user group in D365fo

 Assign user id in All user group in D365 FO


insert into USERGROUPLIST ( USERID, GROUPID)

select 'anant.dubey', GROUPID from USERGROUPLIST where GROUPID not in (select GROUPID from USERGROUPLIST where USERID = 'anant.dubey') group by GROUPID


Tuesday, October 12, 2021

Enable delete button on Purchase order or change Purchase order status or delete purchase order versions in d365


To change that status to draft write following code where we will change its status to draft and further code to is to remove version of purchase order which necessary to make delete button enabled on purchase order form


code:-


/// <summary>
/// extension of class: ReqTransPoMarkFirm
/// </summary>
[ExtensionOf(classStr(ReqTransPoMarkFirm))]
final class ReqTransPoMarkFirmCFSClass_Extension
{
    public container conPurchOrders;

    /// <summary>
    /// updatePurchTable
    /// </summary>
    /// <param name = “_purchTable”>_purchTable</param>
    protected void updatePurchTable(PurchTable _purchTable)
    {
        conPurchOrders += _purchTable.PurchId;

        next updatePurchTable(_purchTable);
    }

    /// <summary>
    /// purchTablePostProcessing
    /// </summary>
    protected void purchTablePostProcessing()
    {
        next purchTablePostProcessing();

        for (int i = 1; i <= conLen(conPurchOrders); i++)
        {
            PurchTable purchTable = PurchTable::find(conPeek(conPurchOrders, i), true);

            if(purchTable.RecId)
            {
                ttsbegin;
                //delete the version created for po
                PurchTableVersion purchTableVersion = PurchTableVersion::findLatest(purchTable.PurchId, purchTable.DataAreaId, true);

                if(purchTableVersion.RecId)
                {
                    purchTableVersion.delete();
                }

                purchTable.ChangeRequestRequired = NoYes::No;
                purchTable.DocumentState         = VersioningDocumentState::Draft;
                purchTable.update();

                ttscommit;
            }
        }

    }


Ref: - https://www.cloudfronts.com/change-planned-purchase-order-status-as-draft-insted-of-default-approved/