Saturday, March 28, 2020

D365 FO upgrade from AX 2012 R2:


D365 FO upgrade from AX 2012 R2:

I am going to explain technical work stream for D365 FO upgrade from AX 2012 R2.

Below steps is high level points for the upgrade however I will post other articles for each major steps which required detail information.


  1. As part of the prerequisite Install KB 4048614 and Install latest cumulative update before starting any upgrade activity.
  2. Analyze and Identify all CRs and SSRS report which not required or deprecated in D365.
  3. Cleanup any CRs or functionality in AX 2012 which is not being used which will help to reduce upgrade cost and upgrade time as well.
  4. Configure LCS .
  5. Configure DevOps.
  6. Create test cases and process including ISV in BPML(Business process modular library )in LCS.
  1. Run upgrade analysis: estimate the AX 2012 preparation work.
  2. Run code upgrade tile: estimate the code upgrade work.
  3. Analyze LCS output report from LCS and find out over layered and conflict objects which will be base during code upgrade.
  4. Run LCS code upgrade tool with "only estimation" check box unchecked and then LCS will create report and also create work items and repository in the DevOps.
  5. Map DevOps repository with Dev VS to start code upgrade.
  6. Next is to start code upgrade and then data upgrade however this approach is good if you have less customization and you can follow water fall model. But if there is huge customization and want reduce the project duration then follow below steps.
  7. As part of data upgrade work first on schema based objects Like EDT, Enum, Table and view.
  8. Work on overlaying  and conflict objects all above related objects add all these objects in a separate model and move to Dev folder.
  9. Map this Dev folder with D365 Dev instance and start data upgrade task parallel to the code upgrade for other object type and it will save significant time in overall project and also enable and involve early in the team to start functional validation after data and code upgrade.
  10. Also we can Fast track or crash code upgrade duration by adding more resources in the project. However adding more developers for code upgrade we need extra precautions, setup and control to avoid further code conflict which I will discuss in the separate post.
  11. There are two part in code upgrade first one to work on overlaying and conflict objects by creating extension in the system ,secondly to check added code and objects after system is compiled with no error because after adding code we can not check objects from front end as there are errors in the system.
  12. During the code upgrade source ISV can be ignored and after successful code upgrade D365 compatible ISV package need to added in D365 through source control so that ISV related data can be upgraded during data upgrade.
  13. During data upgrade most of the errors are due to duplicate records and ISV related errors. So its good practice to discuss with ISV vendor and cleanup orphan and stranded data before starting data upgrade to avoid any ISV related errors.
  14. Once code upgrade and data upgrade are completed functional testing can be started. However, if code upgrade completed before data upgrade then functional team can start CR testing with Std data so that any bug/issue can be highlighted in advance and fixed before actual functional testing.
  15. First data upgrade is the part of development data upgrade which used to identify duration of each step and any error so that these orphan or duplicate data can be cleaned in AX 2012 production before starting next data upgrade in UAT. Also this data upgrade will help for functional testing before UAT.
  16. Its always recommended to do Mock cut over to simulate actual production data upgrade.

Friday, July 12, 2019

Create dialog run time and update respective record on Dialog in D365:


Below are the method to create Dialog dynamically, inter value, fetch value from dialog and update dialog field automatically :

class DialogDemo extends RunBase
{
DialogField fieldAccount;
DialogField fieldName;
DialogField fieldGroup;
VendAccount vendAccount;
VendName vendName;
VendGroupId vendGroupId;

}

//Convert object to container
Public Container pack()
{
return conNull();
}

//Convert container to object
Public boolean unpack(container _packedClass)
{
return true;
}

// Dialog layout
Object dialog()
{
Dialog dialog;
dialog = super();
dialog.caption("Customer information");
dialog.allowUpdateOnSelectCtrl(true);
fieldAccount=dialog.addField(Extendedtypestr(VendAccount),"Vendor Account");
fieldName=dialog.addField(Extendedtypestr(VendName));
fieldName.enabled(false);
dialog.addTabPage("Details");
fieldgroup=dialog.addField(Extendedtypestr(vendGroupId));
fieldgroup.enabled(false);
return dialog;

}

//Fetch value from Dialog
public boolean getFromDialog()
{
vendAccount=fieldAccount.value();
vendName=fieldName.value();
vendGroupId=fieldGroup.value();
return super();
}

public static void main(Args _args)
{
DialogDemo dialogDemo= new DialogDemo();
if(DialogDemo.prompt())
{
DialogDemo.run();
}
}
//field value assignment
public void dialogSelectCtrl()
{
VendTable vendTable;
vendTable=vendTable::find(fieldAccount.value());
fieldName.value(vendTable.name());
fieldGroup.value(vendTable.VendGroup);

}

//To execute logic
Public void run()
{
info(strFmt("Vend Account: %1", vendAccount));
info(strFmt("Vend Name: %1", vendName));
info(strFmt("Vend Group: %1", vendGroupId));
}

Saving last value on the form in D365:


We can save last value on the form in AX so that when next time form will open it will show last saved value in the certain control:

We will take example to save value of below mark control on inventory counting form:


Below are the steps to enable this functionality:
1. Add below code snippet in class declaration:

AllOpenPosted allOpenPostedTrans
#define.CurrentVersion(1)
#localmacro.CurrentList
allOpenPostedTrans
#endmacro

2. Add below methods on the InventJournalTable form:

//To save default value in case if no last value available
public void initParmDefault()
{
allOpenPostedTrans= AllOpenPosted::All;
}

//To convert object to container
public container pack()
{
return [#CurrentVersion, #CurrentList];
}

//To convert container to object
public boolean unpack(container _packedClass)
{
int version = RunBase::getVersion(_packedClass);
switch (version)
{
case #CurrentVersion:
[version, #CurrentList] = _packedClass;
return true;
default:
return false;
}
return false;
}

//To save last design name
public IdentifierName lastValueDesignName
{
return element.args().menuItemName();
}

//To save last value
public IdentifierName lastValueElementName
{
return this.name();
}

//To save valueType in this case Form
public UtilElementType lastValueType()
{
return UtilElementType::Form;
}

//To store User Id
public UserId lastValueUserId()
{
return curUserId();
}

//To save Legal entity details
public DataAreaId lastValueDataAreaId()
{
return curext();
}
3. Add below code in Run(above Super) and Close(last in method) form's method:
Run:
xSysLastValue::getLast(this);
AllOpenPosted.selection(allOpenPostedTrans );

Close:
allOpenPostedTrans = AllOpenPosted.selection();
xSysLastValue::saveLast(this);

Compile and open form change value in the "show " control and close form next time form will open with last value in the show field.

I hope this will help !!!!


How to find SQL query in D365:


How to find SQL query out of the AOT query:


static void AOTQuery(Args _args)
{

QueryRun queryRun;

;

queryRun = new QueryRun(queryStr(QueryName));//add any name of query here in place of QueryName

info(queryRun.query().toString());

}