Skip to main content

Mass cheque printing in AX7/Dynamics 365 for finance & operation


AX7/Dynamics 365 for finance & operation: How to avoid user interaction while printing multiple cheques(Mass cheque printing)
You all might be aware of the ‘Generate Payment’ functionality available in Dynamics AX. This function we use to generate/print cheques. The process is to create one payment journal, add few transactions with mode of payment as ‘Cheque’ then go for ‘Generate Payment’ option available in the drop down of ‘Function’ menu item button. Process is specific to print one cheque at a time for a single journal.
Recently I came across a requirement where I had a customized form which contains multiple journal records and I have to add the ‘Generate Payment’ button on the form to allow user to print the checks for journals, and also allow user to select multiple journal records at the same time to print cheques and avoid user interaction with the system for each cheque.
The major challenge here was, how to handle user interactions everytime to print multiple cheques simultaneously? Because standard AX prints cheques individually for individual payment journal records. On printing of each cheque, a pop-up screen/dialog with next cheque number and bank information will appear where user has to click “OK” to proceed further for printing of cheque.

Solution:
To achieve the above solution, you have to avoid the dialog with cheque number to pop-up.
So a little bit logic was required at first to loop through all the selected record and call ‘Generate Payment’ function for each one of them.
Then you need to specify a Boolean value to check for the first journal record, because you need to populate the dialog once for the first reord. Then I have created two parm() methods in following classes to pass this parameter from my generate payment logic-
1.     CustVendSumForPaym
2.     CustVendOutPaym

[ExtensionOf(classStr(CustVendSumForPaym))]
Final class CustVendSumForPaym_Extension
{
            Boolean                    firstrecord;
            Public Boolean parmFirstRecord(Boolean _firstRecord = firstRecord)
{
            firstRecord = _firstrecord;
            return firstRecord;
}
}

[ExtensionOf(classStr(CustVendSumForPaym))]
Final class CustVendOutPaym_Extension
{
            Boolean                    firstrecord;
            Public Boolean parmFirstRecord(Boolean _firstRecord = firstRecord)
{
            firstRecord = _firstrecord;
            return firstRecord;
}
}

Now form your custom class where you are calling generate payment function, you have to set the value to true for the first record.
I am writing here the piece of code that solves the purpose, for complete code you can refer the standard generatePayment() method.
Public class XYZ
{
            Public void generatePayement(List  _journalList)
{
            VendSumForPaym          vendSumForPaym;
            ledgerJournalTable         journaltable;
            boolean                                firstRecord;
int                                           i = 0;
            ListEnumerator                listEnum = _journalList.getEnumerator();
            While (listEnum.moveNext())
{
            i++;
Journaltable = listEnum.current();
-------------------------------------------
-------------------------------------------
If (i == 1)
{
            firstRecord = true;
}
Else
{
            firstReord = flase;
}
            vendSumforPaym.parmFirstRecord(firstRecord);
            vendSumforPaym.run();
}
}
}
Now in the extension class of CustVendSumForPaym, you have to pass the Boolean firstRecord value to CustVendOutPaym object.
For this you can use chain of command for initCustVendOutPaym() method of CustvendSumForPaym class.
[ExtensionOf(classStr(CustVendSumForPaym))]
Final class CustVendSumForPaym_Extension
{
            Void initCustVendSumForPaym()
            {
                        Next initCustVendSumForPaym();
                        custVendOutPaym.parmFirstRecord(this.parmFirstRecord());
            //’this’ gives you the reference of CustVendSumForPaym
}
}

Now the last thing you have to do is to avoid showing the dialog again and again while printing.
For this you have to create a post even handler for the showDialog() method of runBase class.

[PostHandlerFor(classStr(RunBase), methodStr(RunBase, showDialog))]
Public static void RunBase_Post_showDialog(xppPrePostArgs          args)
{
            Boolean        ret;
            CustVendOutPaym          outPaym;
            Object                                    obj = args.getThis();
            Args   localArgs = new Args(obj);

            Switch (classIdGet(obj))
            {
                        Case classNum(VendOutPaym_Cheque):
                                    outPaym = args.getThis();
                                    if (outPaym.parmFirstRecord())
{
            ret = true;
}
Else
{
            ret = false;
}
Break;
                        Default:
                                    ret = true;
                                    break;
}
args.setReturnValue(ret);
}
So, here in the post event handler for showDialog() method, we are setting up the true value for the first record for cheque print and false for the rest of them. This will allow user to print multiple cheques without prompting user again and again for input.


Comments

Popular posts from this blog

Get account Structure ranges set in AX Ledger

How to pass Account Structure ranges set in AX Ledger to an external system. Recently I have got a requirement where I have to populate same set of main account and financial dimension values to an external system using integration off course, which I have set in AX Ledger. The difficulty in this scenario was, how to get the valid set of main account and financial dimension values from AX.  Because AX gives us 'Segmented Entry Controls' where we just have to use the field as a segmented entry control and valid values will populate according to the Account Structure set in Ledger.  I have created a service class which extends "DimensionValueService" public class CMCDimensionValueService extends DimensionValueService {     // Insert list of valid main accounts to 'DimensionValueContract'     private void insertMainAccountValueLocalList(List                       _dimensionValueList,                                                  Dime

Hierarchy conflicts in AX 7 during migration from other AX versions and it's resolution - Delegates and Handlers

Delegates and Handlers in AX 7(Hierarchy conflicts resolution) Hi, We recently did a migration of our AX 2012 solution to AX 7, and while doing so one of the major challenge that we have faced are hierarchy conflicts. I'll be discussing here on the same. First of all we need to know that what is a hierarchy conflict. Coming to the AX 7 architecture, Application stack is divide into three basic packages. These are- 1: Application Platform 2: Application Foundation  3: Application Suite As shown in the above image, Application platform is the base package which contains Runtime and data access , work flow and services etc. and on top of it we have application foundation which contains organisation model, number sequence and GAB etc. and at the top we have Application Suite and Fleet Management. To understand the concept of these packages in depth you can follow the below link- Architecture changes in AX 7 All three models follows a hierarchy. Application p