Blog Archive

Friday, June 23, 2023

D365 FnO- Creating Multiple Selection Parameterized SSRS Report

 For Multi Selection Parameter Report Design like below all drop downs are multi selection. We have to make a few changes in Contract Class and DP class.



1. Contract Class:

The parameter must be a list type and must be marked with AifCollectionTypeAttribute with type string.



2. Create a helper class "TVS_FixedAssetCountingReportHelper"  and create a static method to transform your list collection to comma separated values.



3. Now in your DP class "processreport()" method apply and get parameters like below and finally run the query as usual.




All set.

1. Contract Class code:

[

    DataContractAttribute,

    SysOperationContractProcessingAttribute(classstr(TVS_FixedAssetsCountingReportUIBuilder))

]

public class TVS_FixedAssetCountingReportContract  //implements SysOperationValidatable, SysOperationInitializable

{

    

    TVS_FixedAssetCountingReportView reportView;

    List assetLocation, assetGroup, assetCondition, assetMajorType;





    [

        DataMemberAttribute('ReportView'),

        SysOperationLabelAttribute('Report View'),

        SysOperationControlVisibilityAttribute(false),

         SysOperationDisplayOrderAttribute("1")

    ]

    public TVS_FixedAssetCountingReportView parmReportView(TVS_FixedAssetCountingReportView _reportView = reportView)

    {

        reportView = _reportView;

        return reportView;

    }


    [

        DataMemberAttribute('AssetGroup'),

        AifCollectionTypeAttribute("AssetGroup", Types::String),

        SysOperationLabelAttribute('Fixed asset group'),

        SysOperationControlVisibilityAttribute(false),

        SysOperationDisplayOrderAttribute("2")

    ]

    public List parmAssetGroup(List _assetGroup = assetGroup)

    {

        assetGroup = _assetGroup;

        return assetGroup;

    }


    [

        DataMemberAttribute('AssetLocation'),

        AifCollectionTypeAttribute("AssetLocation", Types::String),

        SysOperationLabelAttribute('Fixed asset location'),

        SysOperationControlVisibilityAttribute(false),

        SysOperationDisplayOrderAttribute("3")

    ]

    public List parmAssetLocation(List _assetLocation = assetLocation)

    {

        assetLocation = _assetLocation;

        return assetLocation;

    }


    [

        DataMemberAttribute('AssetCondition'),

        AifCollectionTypeAttribute("AssetCondition", Types::String),

        SysOperationLabelAttribute('Fixed asset condition'),

        SysOperationControlVisibilityAttribute(false),

        SysOperationDisplayOrderAttribute("4")

    ]

    public List parmAssetCondition(List _assetCondition = assetCondition)

    {

        assetCondition = _assetCondition;

        return assetCondition;

    }


    [

        DataMemberAttribute('AssetMajorType'),

        AifCollectionTypeAttribute("AssetMajorType", Types::String),

        SysOperationLabelAttribute('Asset Major Type'),

        SysOperationControlVisibilityAttribute(false),

        SysOperationDisplayOrderAttribute("5")

    ]

    public List parmAssetMajorType(List _assetMajorType = assetMajorType)

    {

        assetMajorType = _assetMajorType;

        return assetMajorType;

    }


}


2. -- DP Class Code:

/// <summary>

/// DP class

/// </summary>


[SrsReportParameterattribute(classStr(TVS_FixedAssetCountingReportContract))]

public class TVS_FixedAssetsCoutingRrportDP extends SRSReportDataProviderBase

{

    // Contains Agreement header data.

    TVS_FixedAssetsCountingTmpTable tvs_fixedAssetCountingTmpTable;



    [SRSReportDataSetAttribute(tablestr(TVS_FixedAssetsCountingTmpTable))]

    public TVS_FixedAssetsCountingTmpTable getTVS_FixedAssetsCountingTmpTable()

    {

        select * from tvs_fixedAssetCountingTmpTable;

        return tvs_fixedAssetCountingTmpTable;

    }


    /// <summary>

    /// Process report data.

    /// </summary>

    public void processReport()

    {

        TVS_FixedAssetCountingReportContract contract;

        contract = this.parmDataContract() as TVS_FixedAssetCountingReportContract;

        CompanyInfo     companyInfo = CompanyInfo::find();


        Query                   query = new Query();

        QueryBuildDataSource    qbDsAssetTable;

        QueryBuildDataSource    qbDsASSETGROUP;

        QueryBuildRange         queryBuildRange;

 

        //Specify the name of the table the lookup should show data from.

        qbDsAssetTable = query.addDataSource(tableNum(AssetTable));

            

        qbDsASSETGROUP = qbDsAssetTable.addDataSource(tableNum(AssetGroup));

        qbDsASSETGROUP.joinMode(JoinMode::InnerJoin);

        qbDsASSETGROUP.addLink(fieldNum(AssetTable, AssetGroup), fieldNum(AssetGroup, GroupId));



        TVS_FixedAssetCountingReportView reportView = contract.parmReportView();


        //asset Group

        if (contract && contract.parmAssetGroup() != null)

        {

            qbDsAssetTable.addRange(fieldNum(AssetTable, AssetGroup)).value(TVS_FixedAssetCountingReportHelper::transformListToCommaSepString(contract.parmAssetGroup()));

        }


        //asset condition

        if (contract && contract.parmAssetCondition() != null)

        {

            qbDsAssetTable.addRange(fieldNum(AssetTable, Condition)).value(TVS_FixedAssetCountingReportHelper::transformListToCommaSepString(contract.parmAssetCondition()));

        }


        //major type

        if (contract && contract.parmAssetMajorType() != null)

        {

            qbDsAssetTable.addRange(fieldNum(AssetTable, MajorType)).value(TVS_FixedAssetCountingReportHelper::transformListToCommaSepString(contract.parmAssetMajorType()));

        }


        //warehouse location

        if (contract && contract.parmAssetLocation() != null)

        {

            qbDsAssetTable.addRange(fieldNum(AssetTable, Location)).value(TVS_FixedAssetCountingReportHelper::transformListToCommaSepString(contract.parmAssetLocation()));

        }

        else

        {

            //reason becausae this report has to run over only four warehouses filters

            qbDsAssetTable.addRange(fieldNum(AssetTable, Location)).value(TVS_FixedAssetCountingReportHelper::getLocationFilterRange());

        }

               

        QueryRun qryRun= new QueryRun(query);

        this.runDataQuery(qryRun, companyInfo, reportView);


    }


    private void runDataQuery(QueryRun _qryRun,  CompanyInfo _companyInfo, TVS_FixedAssetCountingReportView _reportView)

    {

        QueryRun qryRun = _qryRun;

        AssetLending assetLending;

        AssetTable assettable;

        AssetGroup assetGroup;

        HcmWorker hcmWorker;


        container companyImgCnt = CompanyImage::findByRecord(_companyInfo).Image;


        ttsbegin;

        while (qryRun.next())

        {

            


           //put your code

           

        }

        ttscommit;

    }

}


3- Helper Class code

public class TVS_FixedAssetCountingReportHelper

{

   

    public static str getLocationFilterRange()

    {

        return "";

    }


    public static str transformListToCommaSepString(List _locationsList)

    {

        str commaSepratedValues = "";


        if (_locationsList != null)

        {

            ListIterator lstIterator = new ListIterator(_locationsList);

            while (lstIterator.more())

            {

                commaSepratedValues += lstIterator.value() + ',';

                lstIterator.next();

            }


            //remove comma at the end

            if (strLen(commaSepratedValues) > 0)

            {

                commaSepratedValues = subStr(commaSepratedValues, 1, strLen( commaSepratedValues)-1);

            }

        }

        return commaSepratedValues;

    }


    public static real getAssetAquistion(str _assetId)

    {

        real assetAQValue = 0;

        return assetAQValue;

    }

}


4- UI Builder Class Code (if applies in your case)

/// <summary>

/// UI Builder

/// </summary>

public  class TVS_FixedAssetsCountingReportUIBuilder extends SrsReportDataContractUIBuilder

{

    TVS_FixedAssetCountingReportContract tvsReportDataContract;


    public void build()

    {

        tvsReportDataContract = this.dataContractObject();


        this.addDialogField(methodStr(TVS_FixedAssetCountingReportContract, parmReportView), tvsReportDataContract);

        this.addDialogField(methodStr(TVS_FixedAssetCountingReportContract, parmAssetGroup), tvsReportDataContract);

        this.addDialogField(methodStr(TVS_FixedAssetCountingReportContract, parmAssetLocation), tvsReportDataContract);

        this.addDialogField(methodStr(TVS_FixedAssetCountingReportContract, parmAssetCondition ), tvsReportDataContract);

        this.addDialogField(methodStr(TVS_FixedAssetCountingReportContract, parmAssetMajorType), tvsReportDataContract);

    }


    public void postRun()

    {

        DialogField dlgReportView;

        DialogField dlgAssetgroupId;

        DialogField dlgLocationId;

        DialogField dlgCondition;

        DialogField dlgMajorType;



        //super();


        dlgReportView = this.bindInfo().getDialogField(this.dataContractObject(), methodStr(TVS_FixedAssetCountingReportContract,parmReportView));


        dlgAssetgroupId = this.bindInfo().getDialogField(this.dataContractObject(), methodStr(TVS_FixedAssetCountingReportContract, parmAssetGroup));

        dlgAssetgroupId.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(TVS_FixedAssetsCountingReportUIBuilder, lookupAssetGroupId), this);


        dlgLocationId = this.bindInfo().getDialogField(this.dataContractObject(), methodStr(TVS_FixedAssetCountingReportContract, parmAssetLocation));

        dlgLocationId.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(TVS_FixedAssetsCountingReportUIBuilder, lookupLocationId), this);


        dlgCondition = this.bindInfo().getDialogField(this.dataContractObject(), methodStr(TVS_FixedAssetCountingReportContract, parmAssetCondition));

        dlgCondition.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(TVS_FixedAssetsCountingReportUIBuilder, lookupCondition), this);


        dlgMajorType = this.bindInfo().getDialogField(this.dataContractObject(), methodStr(TVS_FixedAssetCountingReportContract, parmAssetMajorType));

        dlgMajorType.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(TVS_FixedAssetsCountingReportUIBuilder, lookupMajorType), this);


    }


    private void lookupAssetGroupId(FormStringControl _formStringControl)

    {

        Query                   query = new Query();

        QueryBuildDataSource    queryBuildDataSource;

        QueryBuildRange         queryBuildRange;

        container cntner;


        //Specify the name of the table the lookup should show data from.

        queryBuildDataSource = query.addDataSource(tableNum(ASSETGROUP));

        queryBuildDataSource.addSelectionField(fieldNum(AssetGroup, GROUPID));

        queryBuildDataSource.addSelectionField(fieldNum(AssetGroup, Name));


        SysLookupMultiSelectGrid::lookup(query, _formStringControl, _formStringControl, _formStringControl, cntner);


    }


    private void lookupLocationId(FormStringControl _formStringControl)

    {

        

        Query                   query = new Query();

        QueryBuildDataSource    queryBuildDataSource;

        QueryBuildRange         queryBuildRange;

        container cntner;

        //Specify the name of the table the lookup should show data from.

        queryBuildDataSource = query.addDataSource(tableNum(AssetLocation));

        queryBuildRange = queryBuildDataSource.addRange(fieldNum(AssetLocation, Location));


        queryBuildRange.value(TVS_FixedAssetCountingReportHelper::getLocationFilterRange());


        queryBuildDataSource.addSelectionField(fieldNum(AssetLocation, Location));

        queryBuildDataSource.addSelectionField(fieldNum(AssetLocation, Name));



        SysLookupMultiSelectGrid::lookup(query, _formStringControl, _formStringControl, _formStringControl, cntner);


    }


    private void lookupCondition(FormStringControl _formStringControl)

    {

        Query                   query = new Query();

        QueryBuildDataSource    queryBuildDataSource;

        QueryBuildRange         queryBuildRange;

        container cntner;

        //Specify the name of the table the lookup should show data from.

        queryBuildDataSource = query.addDataSource(tableNum(ASSETCONDITION));

        queryBuildDataSource.addSelectionField(fieldNum(ASSETCONDITION, Condition));

        queryBuildDataSource.addSelectionField(fieldNum(ASSETCONDITION, Description));



        SysLookupMultiSelectGrid::lookup(query, _formStringControl, _formStringControl, _formStringControl, cntner);


    }


    private void lookupMajorType(FormStringControl _formStringControl)

    {

        

        Query                   query = new Query();

        QueryBuildDataSource    queryBuildDataSource;

        QueryBuildRange         queryBuildRange;

        container cntner;

        //Specify the name of the table the lookup should show data from.

        queryBuildDataSource = query.addDataSource(tableNum(AssetMajorType));

        queryBuildDataSource.addSelectionField(fieldNum(AssetMajorType, MajorType));

        queryBuildDataSource.addSelectionField(fieldNum(AssetMajorType, Description));

        SysLookupMultiSelectGrid::lookup(query, _formStringControl, _formStringControl, _formStringControl, cntner);


    }


}


Friday, June 16, 2023

D365 FO - Creating a custom Lookup Field

 

Creating a lookup on Field

 Here is a simple way of creating lookup field.

[Control("String")]

    class SLDApprelPricingReq_CustomerId

    {

        /// <summary>

        ///

        /// </summary>

        public void lookup()

        {

 

            //Specify the name of the table the lookup should show data from.

            SysTableLookup          sysTableLookup = SysTableLookup::newParameters(tableNum(CustTable), this);

            //Create a new query

            Query                   query = new Query();

            QueryBuildDataSource    queryBuildDataSource;

            QueryBuildRange         queryBuildRange;

 

            //Specify the name of the table the lookup should show data from.

            queryBuildDataSource = query.addDataSource(tableNum(CustTable));

            //Specify which fields should be shown  in the lookup form.

            //  field returned is the first field referenced

            sysTableLookup.addLookupfield(fieldNum(CustTable, AccountNum));

 

            sysTableLookup.parmQuery(query);

            sysTableLookup.performFormLookup();

 

        }

D365 Reading Image Attachments on PO Lines and Transforming to Asset Images

 Hi,

I had to read PO line image attachments and needed to transform to asset image. Here are the codes glimpses of this. First you need to read the docuref image related to PO line item and then transform it to memory stream and then to image container.





Second Method:




Thursday, June 15, 2023

D365 FO - Netmodule file missing:Dynamics.AX.anymodel.netmodule Error occurred

 Hi,

I was facing the error while creating a package for D365 FO. To mitigate it I followed follwing steps


1) Stop All three services (Microsoft unified, Dixf, worldwide web)

2) Go to packages local directory --> your model --> bin

3) search keyword ".net" to filter all files and delete those files

4) build the model again and again created the package


Finally, restart your services.


Best luck,

Mirza Salman Niaz.

Adding Postal Address of HCMApplicant

 Hi, If you want to add a postal address in D365 FnO against party. or DirPartyTable. My use case was while creating a HCMApplicant we need ...