Friday, 14 September 2018

Changing report design based on parameter value in X++ in AX

First, you need to create a controller class and override its preRunModifyContract() method. This method is commonly used for Modifying the query or setting the contract values that are hidden from the user on the dialog. Below is the sample code  

/// <summary>
///    The <c>HRKPIStatusReportController</c> class is the controller class for the <c>HRKPIStatusReport</c>
///    SRS report.
/// </summary>
class HRKPIStatusReportController extends SrsReportRunController
{

    public static void main(Args _args)
    {
        HRKPIStatusReportController controller = new HRKPIStatusReportController();
        controller.parmReportName(ssrsReportStr(HRKPIStatusReport, Summary));
        controller.parmArgs(_args);
        controller.startOperation();
    }

    protected void preRunModifyContract()
    {
        HRKPIStatusReportContract contract = this.parmReportContract().parmRdpContract() as HRKPIStatusReportContract;
       
        this.parmReportContract().parmReportName(this.getReportName(contract));
       
        super();
    }

    private str getReportName(HRKPIStatusReportContract _contract)
    {
        str reportNameLocal;

        if (_contract.parmReportDesign() == HRReportDesign::SummaryView)
        {
            reportNameLocal = ssrsReportStr(HRKPIStatusReport, Summary);
        }
        else
        {           
            reportNameLocal = ssrsReportStr(HRKPIStatusReport, Detail);
        }

        return reportNameLocal;
    }

}

Friday, 3 August 2018

Import and Export project with multiple objects using VS - D365FO / AX 7

Overview
In Visual Studio we have solution that contains multiple projects. These projects helps us to organize and manage the elements. Each project contain elements from only one model. In order to move elements from one environment to another in D365, It can be easily done by using project package file which contains list of the elements added in the project.

To transfer the elements first create a project in VS and add elements to the project and follow the steps.

Export a project
Exporting a project is quite simple. You need to Right-click it and select Export Project. Provide the name of the project file and click Save. Project file is created with extension .axpp.
















Import a project
Now, you can use this file to move the elements into any environment by just simply importing the project. 

Go to Visual Studio and click on Dynamics 365 -> Import Project. Now select the .axpp file you need to import. By default all the elements in the project are selected for import. After selecting the elements click OK. 



















NOTE: Project package file doesn’t only carries the elements but also contains the information about the model and the layer they belongs to. So during import if the model doesn’t exists Visual Studio creates the missing model automatically.

Wednesday, 1 August 2018

Deploy SSRS reports using PowerShell D365 / AX 7

Open Windows PowerShell as administrator and run below command.

Deploy all reports

C:\AOSService\PackagesLocalDirectory\Plugins\AxReportVmRoleStartupTask\DeployAllReportsToSSRS.ps1










Deploy specific report

C:\AosService\PackagesLocalDirectory\Plugins\AxReportVmRoleStartupTask\DeployAllReportsToSSRS.ps1 -Module ModuleName -ReportName ReportName.Report

Monday, 30 July 2018

Creating custom financial dimension Lookup using X++ code in AX / D365FO / AX 7


Here is the sample X++ code to create custom financial dimension lookup

public void Lookup(FormStringControl _control)
{
        DimensionAttribute                  dimensionAttribute;
        DimensionAttributeDirCategory       dimAttributeDirCategory;
        Query                               query = new Query();
        SysTableLookup                      sysTableLookup;

        dimensionAttribute = DimensionAttribute::findByName('ServiceLine');

        if (dimensionAttribute.Type == DimensionAttributeType::CustomList)

        {

        select firstonly DirCategory from dimAttributeDirCategory
            where dimAttributeDirCategory.DimensionAttribute == dimensionAttribute.RecId;

        sysTableLookup = SysTableLookup::newParameters(tableNum(DimensionFinancialTag), _control);

        sysTableLookup.addLookupfield(fieldNum(DimensionFinancialTag, Value));
        sysTableLookup.addLookupfield(fieldNum(DimensionFinancialTag, Description));

        query = new Query();
        query.addDataSource(tableNum(DimensionFinancialTag)).

        addRange(fieldNum(DimensionFinancialTag, FinancialTagCategory)).

        value(queryValue(dimAttributeDirCategory.DirCategory));

        sysTableLookup.parmQuery(query);

        // Perform the lookup.
        sysTableLookup.performFormLookup();

       }
}



How to get Financial Dimension value from Worker Position in AX / D365FO / AX 7

Here is the sample X++ code to find financial dimension value from the worker's primary position.

public Name getDimensionValue(HcmWorkerRecId _workerRecId, Name _DimensionName)
{
        HcmPositionDefaultDimension             hcmPositionDefaultDimension;
        DefaultDimensionView                    dimensionView;
        DimensionAttributeValueSet              DimensionAttributeValueSet;
        DimensionAttributeValueSetItem          DimensionAttributeValueSetItem;
        DimensionAttributeValue                 DimensionAttributeValue;
        DimensionAttribute                      DimensionAttribute;
       
        select HcmPositionDefaultDimension where
            HcmPositionDefaultDimension.Position == HcmWorker::getPrimaryPosition(_workerRecId);

        select RecId from DimensionAttributeValueSet
           where  DimensionAttributeValueSet.RecId == HcmPositionDefaultDimension.DefaultDimension
           join RecId, DisplayValue, DimensionAttributeValueSet from DimensionAttributeValueSetItem
           where DimensionAttributeValueSetItem.DimensionAttributeValueSet == DimensionAttributeValueSet.RecId
           join RecId from DimensionAttributeValue
           where DimensionAttributeValue.RecId == DimensionAttributeValueSetItem.DimensionAttributeValue
           join RecId, Name, ValueAttribute from DimensionAttribute
           where DimensionAttribute.RecId == DimensionAttributeValue.DimensionAttribute
                && DimensionAttribute.Name == _DimensionName;

        select dimensionView
            where dimensionView.DefaultDimension == HcmPositionDefaultDimension.DefaultDimension
                && dimensionView.Name == _DimensionName
                && dimensionView.DisplayValue == DimensionAttributeValueSetItem.DisplayValue
                && dimensionView.DimensionAttributeId == DimensionAttribute.RecId;

        return dimensionView.dimensionDiscription();
       
}

Friday, 27 July 2018

How to get multiple selected records in control level event handlers in D365FO / AX 7

Purpose:
The purpose of this document is to show how to get multiple selected records in form control event handlers. 

Development:
First of all create new event handler class HRPayrollPayStatementEventHandler and subscribe to form button OnClicked event handler.

/// <summary>
/// The <c>HRPayrollPayStatementEventHandler</c> class is the event handler class for managing PayrollPayStatement form events
/// </summary>
class HRPayrollPayStatementEventHandler
{
   

    /// <summary>
    /// Click event handler
    /// </summary>
    /// <param name="_sender">Form control buffer</param>
    /// <param name="_e"> Event args</param>
    [FormControlEventHandler(formControlStr(PayrollPayStatement, CustomButton), FormControlEventType::Clicked)]
    public static void SLD_CustomButton_OnClicked(FormControl _sender, FormControlEventArgs _e)
    {
        FormDataSource    PayrollPayStatement_DS = _sender.formRun().dataSource(formDataSourceStr(PayrollPayStatement, PayrollPayStatement));

        MultiSelectionHelper    selectionHelper = MultiSelectionHelper::construct();
        PayrollPayStatement     payStatement;

        selectionHelper.parmDataSource(PayrollPayStatement_DS);
        payStatement  = selectionHelper.getFirst();

        if (payStatement.RecId)
        {
            while (payStatement.RecId != 0)
            { 
                info (payStatement.DocumentNumber);

                payStatement = selectionHelper.getNext();
            }          
        }
    }
}

Tuesday, 17 July 2018

D365 / AX 7 - How to override form control methods

Purpose:
The purpose of this document is to show how to override form control methods without overlaying in Dynamics 365 for Operations

Development:
To demonstrate we are using the HRMCompFixedEmplActionDialog form and going to override the planId_Control lookup method.

First of all, create new event handler class HRMCompFixedEmplActionDialogEventHandler and subscribe to post-event handler of form init.

/// <summary>
/// The <c>HRMCompFixedEmplActionDialogEventHandler</c> class is the event handler class
/// for managing HRMCompFixedEmplActionDialog form events
/// </summary>
class HRMCompFixedEmplActionDialogEventHandler
{     

    /// <summary>
    ///  Post event handler for HRMCompFixedEmplActionDialog
    /// </summary>
    /// <param name="_args">Event args</param>
    [PostHandlerFor(formStr(HRMCompFixedEmplActionDialog), formMethodStr(HRMCompFixedEmplActionDialog, init))]
    public static void HRMCompFixedEmplActionDialog_Post_init(XppPrePostArgs _args)
    {
        FormRun formRun = _args.getThis();

        var methodOverrides = HRMCompFixedEmplActionDialogEventHandler::construct();

        FormStringControl PlanIdctrl = formRun.design().controlName(formControlStr(HRMCompFixedEmplActionDialog, planId_Control));
        PlanIdctrl.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(HRMCompFixedEmplActionDialogEventHandler, LookupPlanId ), methodOverrides );
    }

    /// <summary>
    /// Constructs a new instance of <c>HRMCompFixedEmplActionDialogEventHandler</c> class.
    /// </summary>
    /// <returns>
    /// A <c>HRMCompFixedEmplActionDialogEventHandler</c> class.
    /// </returns>
    public static HRMCompFixedEmplActionDialogEventHandler construct()
    {
        return new HRMCompFixedEmplActionDialogEventHandler();
    }

    /// <summary>
    ///    Overrided method for Plan id lookup
    /// </summary>
    /// <param name="_ctrl">
    /// FormStringControl buffer
    /// </param>
    public void LookupPlanId(FormStringControl _ctrl)
    {
        SysTableLookup      sysTableLookup = SysTableLookup::newParameters(tableNum(HRMCompFixedPlanTable), _ctrl);
        Query               query;

        QueryBuildDataSource qbds = query.addDataSource(tablenum(HRMCompFixedPlanTable));

        sysTableLookup.addLookupfield(fieldNum(HRMCompFixedPlanTable, PlanId));
        sysTableLookup.addLookupfield(fieldNum(HRMCompFixedPlanTable, Description));
        sysTableLookup.addLookupfield(fieldNum(HRMCompFixedPlanTable, Type));
        sysTableLookup.addLookupfield(fieldNum(HRMCompFixedPlanTable, CurrencyCode));
        sysTableLookup.addLookupfield(fieldNum(HRMCompFixedPlanTable, PayFrequencyId));

        sysTableLookup.parmQuery(query);
        sysTableLookup.performFormLookup();
    }

}



Using this the approach we can override any form of control methods

Run AX report using X++

       Args                     args;      ReportRun          report;     salesLineProductPartProd salesLineProductPartProdLocal;     ;     ...