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.

Sunday, April 25, 2021

Multi-Select Lookup on Form Control in D365FO

 

/// <summary>

/// TSTLookupMultiSelectGridForDatasource to show lookup for a datasource field

/// </summary>

class TSTLookupMultiSelectGridForDatasource extends SysLookupMultiSelectGrid

{

    FormRun             callerFormRun;

    str                 callerFormdatasourceName;

    FieldId             populateFieldId;

   

 

    /// <summary>

    /// Get set Caller Form run

    /// </summary>

    /// <param name = "_callerFormRun">Caller form run</param>

    /// <returns>Caller form run</returns>

    FormRun parmCallerFormRun(FormRun _callerFormRun = callerFormRun)

    {

        callerFormRun = _callerFormRun;

 

        return callerFormRun;

    }

 

    /// <summary>

    /// Get set Caller datasource for lookup

    /// </summary>

    /// <param name = "_callerFormdatasourceName">Caller datasource for lookup</param>

    /// <returns>Caller datasource for lookup</returns>

    str parmCallerFormdatasourceName(str _callerFormdatasourceName = callerFormdatasourceName)

    {

        callerFormdatasourceName = _callerFormdatasourceName;

 

        return callerFormdatasourceName;

    }

 

    /// <summary>

    /// Get set field number for lookup

    /// </summary>

    /// <param name = "_populateFieldId">field number for lookup</param>

    /// <returns>field number for lookup</returns>

    FieldId parmPopulateFieldId(FieldId _populateFieldId = populateFieldId)

    {

        populateFieldId = _populateFieldId;

 

        return populateFieldId;

    }

 

    /// <summary>

    /// Set slected field to datasource field

    /// </summary>

    public void setSelected()

    {

        callingControlId.text(SysOperationHelper::convertMultiSelectedValueString(selectedId));

        str callingControlStrTxtVal = SysOperationHelper::convertMultiSelectedValueString(selectedStr);

        callingControlStr.text(callingControlStrTxtVal);

        if (callerFormRun && callerFormdatasourceName && populateFieldId)

        {

            FormDataSource  locDatasource = callerFormRun.dataSource(callerFormdatasourceName);

 

            if (locDatasource)

            {

                Common  recordTOPopulate = locDatasource.cursor();

 

                recordTOPopulate.(populateFieldId) = callingControlStrTxtVal;

            }

 

        }

    }

 

    /// <summary>

    /// Lookup multi select

    /// </summary>

    /// <param name = "_query">Query for lookup</param>

    /// <param name = "_callingCtrl">Calling control</param>

    /// <param name = "_ctrlIds">Control ids</param>

    /// <param name = "_ctrlStrs">Control strings</param>

    /// <param name = "_selectField">Selection fields</param>

    /// <param name = "_queryRun">Query run</param>

    /// <param name = "_formRun">Caller fi=ormrun</param>

    /// <param name = "_formDatasource">Caller data source</param>

    /// <param name = "_fieldId">Field id for populating lookup</param>

    public static void lookup(Query _query, FormStringControl _callingCtrl, FormStringControl _ctrlIds, FormStringControl _ctrlStrs, container _selectField, queryRun _queryRun = null,

        FormRun _formRun = null, str _formDatasource = '', FieldId _fieldId = 0)

    {

        TSTLookupMultiSelectGridForDatasource    lookupMS = new TSTLookupMultiSelectGridForDatasource();

 

        lookupMS.parmCallingControl(_callingCtrl);

        lookupMS.parmCallingControlId(_ctrlIds);

        lookupMS.parmCallingControlStr(_ctrlStrs);

        lookupMS.parmQuery(_query);

        lookupMS.parmQueryRun(_queryRun);

        lookupMS.parmSelectField(_selectField);

        lookupMS.parmCallerFormRun(_formRun);

        lookupMS.parmCallerFormdatasourceName(_formDatasource);

        lookupMS.parmPopulateFieldId(_fieldId);

        lookupMS.run();

    }

 

}


 

class TSTSampleFormEventHandler

{

    /// <summary>

    /// Lookup event handler of eentHanlder

    /// </summary>

    /// <param name="sender"></param>

    /// <param name="e"></param>

    [FormControlEventHandler(formControlStr(RetailTenderTypeTable, RetailTenderTypeTable_AllowedRefundTender), FormControlEventType::Lookup),

        SuppressBPWarning('BPParameterNotUsed', 'Parameter not required')]

    public static void MCSAllowedRefundTender_OnLookup(FormControl sender, FormControlEventArgs e)

    {

        Query                       query;

        FormRun                     formRunTT = sender.formRun();

        QueryBuildDataSource        tenderTypeQBDS;

        QueryBuildFieldList         enderTypeFieldList;

        FormStringControl           stringControl = sender as FormStringControl;

 

        query                       = new Query();

        tenderTypeQBDS = query.addDataSource(tableNum(RetailTenderTypeTable));

       

        enderTypeFieldList = tenderTypeQBDS.fields();

       

        enderTypeFieldList.dynamic(QueryFieldListDynamic::No);

        enderTypeFieldList.clearFieldList();

        enderTypeFieldList.addField(fieldNum(RetailTenderTypeTable, tenderTypeId));

        enderTypeFieldList.addField(fieldNum(RetailTenderTypeTable, name));

        enderTypeFieldList.addField(fieldNum(RetailTenderTypeTable, defaultFunction));

 

        TSTLookupMultiSelectGridForDatasource::lookup(query, stringControl, stringControl, stringControl, conNull(), null, formRunTT, formDataSourceStr(RetailTenderTypeTable, RetailTenderTypeTable), fieldNum(RetailTenderTypeTable, AllowedRefundTender));

    }

 

}

Wednesday, April 21, 2021

Enable Maintenance mode to update Financial dimension in d365fo

 In DEV environment

OPEN SQL

goto table - SQLSystemVariables


change the value of ConfigurationMode from 0 to 1


update dbo.SQLSYSTEMVARIABLESset dbo.SQLSYSTEMVARIABLES.VALUE =1

where dbo.SQLSYSTEMVARIABLES.PARM = ‘CONFIGURATIONMODE’

IISReset


roll back once done

Sunday, April 18, 2021

Get Next Number using Number Sequence in d365fo

NumberSeq numberSeq; 


numberSeq = NumberSeq::newGetNum(NumberSeqReference::findReference(extendedTypeNum(BOMId)), true);


bomTable.BOMId = numberSeq.num();

bomTable.insert();

numberSeq.used();


Monday, March 1, 2021

Export User's Security Roles, Duties and Privileges in ax 2012

 static void AD_ExportUsersecurities_User(Args _args)

{

    SysExcelApplication         xlsApplication;

    SysExcelWorkBooks           xlsWorkBookCollection;

    SysExcelWorkBook            xlsWorkBook;

    SysExcelWorkSheets          xlsWorkSheetCollection;

    SysExcelWorkSheet           xlsWorkSheet;

    SysExcelRange               xlsRange;

    CustTable                   custTable;

    int                         row = 1;

    str                         fileName;


    SecurityTask                securityTask, securityTaskDuty, securityTaskPriv;

    SecuritySubTask             securitySubTask;

    SecurityRoleTaskGrant       securityRoleTaskGrant;

    SecurityRole                securityRole, securityRoleDuty,securityRolePriv, securityRoleM;

    SecurityTaskEntryPoint      SecurityTaskEntryPoint;

    SecurableObject             SecurableObject;

    SecurityUserRole            securityUserRole;

    UserInfo                    userInfo;


    SecurityTaskEntryPoint  taskEntryPoint;

    SecurityRole            role;

    SecurityRoleTaskGrant   taskGrant;

    SecuritySubTask         subTask;

    SecurityTask            privilege;


    str privName;

    str dutyName;

    str entrName;

    str accessLevel;


    boolean i = true,j = true;

    ;

    fileName = "UserName.CSV";    //Rename file

    xlsApplication           = SysExcelApplication::construct();

    xlsWorkBookCollection    = xlsApplication.workbooks();

    xlsWorkBook              = xlsWorkBookCollection.add();

    xlsWorkSheetCollection   = xlsWorkBook.worksheets();

    xlsWorkSheet             = xlsWorkSheetCollection.itemFromNum(1);

    xlsWorkSheet.cells().item(row,1).value("User Id");

    xlsWorkSheet.cells().item(row,2).value("User Role");

    xlsWorkSheet.cells().item(row,3).value("Duty");

    xlsWorkSheet.cells().item(row,4).value("Privilege AOT");

    xlsWorkSheet.cells().item(row,5).value("Privilege Description");


    row++;


    while select RecId,Name, AotName from securityRole

        join User,SecurityRole from securityUserRole

        where securityUserRole.User == "axadminr"     //Enter user information here

        && securityUserRole.SecurityRole == securityRole.RecId

    {

        while select SecurityRole,SecurityTask  from securityRoleTaskGrant

            where securityRoleTaskGrant.SecurityRole == securityRole.RecId

        {

            select * from securityTask

                where securityTask.RecId == securityRoleTaskGrant.SecurityTask

                && securityTask.Type != SecurityTaskType::ProcessCycle;

            {

                if(securityTask.Type == SecurityTaskType::Duty)

                {

                    while select * from subTask //where subTask.SecuritySubTask == SecurityTaskEntryPoint.SecurityTask

                        where subTask.SecurityTask == securityRoleTaskGrant.SecurityTask

                    {

                        select RecId, AotName, Name, Type from privilege

                            where privilege.RecId == securityRoleTaskGrant.SecurityTask

                            && SecurityTaskType::Duty == privilege.Type;

                                dutyName = privilege.AotName;


                        select RecId, AotName, Name, Type from privilege

                            where privilege.RecId == subTask.SecuritySubTask

                            && SecurityTaskType::Privilege == privilege.Type;

                            privName = privilege.AotName;

                        {

                            //Information to Excel

                            xlsWorkSheet.cells().item(row,1).value(securityUserRole.User);         //User id

                            xlsWorkSheet.cells().item(row,2).value(securityRole.Name);  //Role Name

                            xlsWorkSheet.cells().item(row,3).value(dutyName); //DutyName

                            xlsWorkSheet.cells().item(row,4).value(privName);  //Privilege AOT Name

                            xlsWorkSheet.cells().item(row,5).value(securityTask.Name);  //Privilege Description

                            row++;

                        }

                    }

                }

                else             //Role if contain Privilegs directly

                {

                        xlsWorkSheet.cells().item(row,1).value(securityUserRole.User);         //User id

                        xlsWorkSheet.cells().item(row,2).value(securityRole.Name);  //Role Name

                        xlsWorkSheet.cells().item(row,3).value(""); //DutyName

                        xlsWorkSheet.cells().item(row,4).value(securityTask.AotName);  //Privilege AOT Name

                        xlsWorkSheet.cells().item(row,5).value(securityTask.Name);  //Privilege Description

                }

            }

        }

    }

    if(WinApi::fileExists(fileName))

        WinApi::deleteFile(fileName);

    xlsWorkbook.saveAs(fileName);

    xlsApplication.visible(true);

    info(strFmt("File has been exported"));

}

Sunday, February 16, 2020

Application Object Server (AOS) Services WSDL URI accessible

Performing a service status check for prerequisite 'Application Object Server (AOS) Services WSDL URI accessible'. - Check failed.
When I click on the "Error"link I get the message:
"Resolution: Attempt to access the WSDL port manually by entering the URI http://<SERVER>:/DynamicsAx/Services/MetadataService. ..."
It seems that the port (8101) is missing in the URI the prerequisite checker is trying to access.
If I enter the URI http://<SERVER>:8101/DynamicsAx/Services/MetadataService in the browser it works without any problem.

Solution:-
The rootcause of this issue is, you must have installed .NET Business Connector to resolve some 32/64 bit InstallPath issue.
and The Default Client configuration in this server points to blank WSDL port.
To fix this issue:
1.Open Client configuration.
2.Create a new Configuration for AX and BusinessConnector. Ensure the WSDL port is set to the correct value [Default : 8101].
3.Perform Refresh Configuration to generate WCF Settings.
4.Exit the setup and run it again


How to send email using email template by Outlook in AX 2012

static void AD_SendEmailOutlook(Args _args)
{
    SysEmailId           emailId;
    DialogField          dlgEmailId;
    CustTable            custTable;
    LanguageId           languageId = 'EN-IN';
    #define.CurrentVersion(1)
    #localmacro.CurrentList
        emailId
    #endmacro
    SendEmail           sendEmail;
    SysInetMail         mail;
    str subject()
    {
        return SysEmailMessageTable::find(emailId, languageId).Subject;
    }
    str processMappings(str _message)
    {
        Map mappings;
        ;
        mappings = new Map(Types::String, Types::String);
        mappings.insert('CustomerName', "Anu");
        mappings.insert('CustomerStreet', "Testingg");
        return SysEmailMessage::stringExpand(_message, mappings);
    }
    str message()
    {
        COM                  document;
        COM                  body;
        str                  ret;
        SysEmailMessageTable message;
        #help
        ;
        message = SysEmailMessageTable::find(emailId, languageId);
        ret = processMappings(message.Mail);
        //ret = WebLet::weblets2Html4Help(ret, '');
        document = new COM(#HTMLDocumentClassName);
        SysEmailTable::insertHTML2Document(document, ret);
        body = document.body();
        if (!body)
        {
            return '';
        }
        return body.outerText();
    }

    ;
    //sendEmail = new SendEmail();
    emailId = "Test";
    mail = new SysInetMail();
    mail.parmForceSendDialog(true);
    mail.sendMail("support@****.com",subject(), message(),false);
    info("sent");
}