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.

Monday, November 14, 2016

How to create SSRS report in AX 2012

Reports in Dynamics Ax 2012 R3 are very Easy. For this purpose I have to create a new AOT/Static Query AOT. This query is between CustTable and SalesTable. I want to create Inner Join so Only those Customer came who have Sales Orders. Consider following Steps to create A new report
Create a new Query with Name “DyWorldCustSales”
Drop or add Data Source with CustTable
6-21-2014 9-02-30 PM

Right click on Fields and add following fields from Customer table.
CustomerFileds


Expand Data Source inside Custtable, Add or create DataSource with SalesTable and fields

SalesOrder

Right Click on Relations node in SalesTables Data Source and set its join properties as follow
DataSetProperties

Expand Relationship node of SalesTable_1  Add Following relationship
Relations

Set it properties as follow
RelationshipDetail

New create a new report In existing or New DataModel Report in Visual Studio project
NewReport Project

Add New report with DyCustSalesOrderList
Add Dataset with Name DSCustomer and Point to Query which we create in above steps

PointToQuery QueryDataSet
Now drag and drop the dataset on designer to create a designer
And Update rename it to  DyCustSalesOrderList

Set DataTable’s Propeties visible to set false
DataTable
Add a List and set its name to CustList
Create two groups there one for CustomerGroup and second for AccountNum
Groups

Now drop the fields from dataset which  you want to display on report
Fields

Right click on CustList and set Data Navigation Style to DrillDown from properties window
DrillDownProperties
Now right click add report to aot and then deploy to Report Server

When you run the report  from meu Item you will find following
CustomerGroupClick

Click on Customer group this will open it
reportCustomerLevel

Click on Customer account it will drill down report on Detail level
Details

Reference taken by:- https://community.dynamics.com/ax/b/alirazatechblog/archive/2014/06/23/exploring-drill-down-ssrs-reports-in-dynamics-ax-2012-r3

How to create and debug batch job in AX 2012

There are many scenario where we have to schedule the tasks, so they execute in background. Real world scenarios are
  • Sales order with certain criteria will update status to Invoiced.
  • Scheduled job check the file location to find comma delimited files and after finding create sales order or purchased orders in Ax.
  • Schedule job clear the data in database logging after certain time.
  • Schedule job execute mid night to extract all sales order/ Purchase order and integrated it other system.

In dynamics Ax we can schedule the with help of RunBaseBatch framework.

For current example, I just wrote the batch job which just put its execution time in custom table.
First step for batch process is to enable the Dynamics Ax 2012 as Batch server.
Link


Enable Server
Consider a custom table with only two fields. These fields just dummy text and the time when batch process execute.

Table Structure

Now just create a class, set it run at server.

Class attributes
Extends the class with run batch base class.  The class logic should be same


class ProcessTableIncrement extends RunBaseBatch

{

 

}

 

public container pack()

{

return conNull();

}

 

public void run()

{

 

// The purpose of your job.

TblBatchHit _hit;

 

_hit.HitBy ="BatchJob";

_hit.hitTime= DateTimeUtil ::utcNow();

_hit.insert();

}

 

public boolean unpack(container packedClass)

{

return true;

}

 

Now compile the code and Generate Increment CIL. Incremental CIL generation is required to setup every time you update the code.

Now create ax job which deploy above class as batch Process job.

static void TestBatchHit(Args _args)

{

BatchHeader header;

SysRecurrenceData sysRecurrenceData;

Batch batch;

BatchJob batchJob;

ProcessTableIncrement _ProcessIncrement;

BatchInfo processBatchInfo;

BatchRetries noOfRetriesOnFailure = 4;

;

 

// Create the tutorial_RunBaseBatch job, only if one does not exist

select batch where batch.ClassNumber == classnum(ProcessTableIncrement);

if(!batch)

{

// Setup the tutorial_RunBaseBatch Job

header = BatchHeader::construct();

_ProcessIncrement = new ProcessTableIncrement();

processBatchInfo = _ProcessIncrement.batchInfo();

processBatchInfo.parmRetriesOnFailure(noOfRetriesOnFailure);

processBatchInfo.parmCaption("Table Increment");

 

header.addTask(_ProcessIncrement);

 

// Set the recurrence data

sysRecurrenceData = SysRecurrence::defaultRecurrence();

SysRecurrence::setRecurrenceStartDateTime(sysRecurrenceData, DateTimeUtil::addSeconds(DateTimeUtil::utcNow(), 20));

SysRecurrence::setRecurrenceNoEnd(sysRecurrenceData);

SysRecurrence::setRecurrenceUnit(sysRecurrenceData, SysRecurrenceUnit::Minute);

header.parmRecurrenceData(sysRecurrenceData);

// Set the batch alert configurations

header.parmAlerts(NoYes::No, NoYes::Yes, NoYes::No, NoYes::Yes, NoYes::Yes);

header.save();

 

// Update the frequency to run the job to every two minutes

ttsbegin;

select forupdate batchJob

join batch

where batchJob.RecId == batch.BatchJobId

&& batch.ClassNumber == classnum(ProcessTableIncrement);

 

sysRecurrenceData = batchJob.RecurrenceData;

sysRecurrenceData = conpoke(sysRecurrenceData, 8, [3]);

batchJob.RecurrenceData = sysRecurrenceData;

batchJob.update();

ttscommit;

}

}

 

 
When you execute the X++ job, you will find a new batch job created and waiting state at following link with caption Table Increment

Job Link


From top menu you can check the job execution history.

Batch Job

Job History

If any error occur or you put some info logs, these can be seen from Log from top menu.
For example in some other batch job I used many info boxes at different locations to trace.
11-12-2014 12-58-09 AM

Remove / Delete the batched job.
Delete the existing job is two-step process if job is in waiting step. First we have to convert it into withhold state and then delete it.
Select the required batch job for example if I want to delete Job with caption “Table Increment”. From top menu to select change state to with hold

select

withhold

Now again go in Functions top menu and select

delete
Now from dialog set status to withhold and click on ok
ddd
This will remove the Batch Job

Debug the Batch Process Job
Now question is how we can debug batch job, for that purpose we have to go in visual studio.

For debugging at AOS server following check box must be check form AOS server configuration.
“Enable breakpoints to debug x++ code running on this server on this machine”
X++



If Client and AOT are in same machine then open the Application explore and locate the file and attach debug there.
Visual studio debug


If files are at AOS is another machine go at XPPIL folder in visual studio and add break point.



From debug menu click on attached process
Attached process
From  Attach to select the manage code.
From top click on select button and select the Managed(v4.0) code
ttss
Check the two check boxes below “Show Processes from All Users and show processes in all sessions and click on refresh.
After refresh select Ax32Serv.exe and click on attach button.

When the job execute after certain time link appear on break point.
sss

Reference taken by:- https://community.dynamics.com/ax/b/alirazatechblog/archive/2014/11/12/exploring-the-batch-job-process-in-dynamics-ax-2012-r3

Wednesday, November 18, 2015

Event Handling in Microsoft Dynamics AX 2012

Today, I am going to talk on the event handling mechanism in Microsoft Dynamics AX 2012. With the event-handling mechanism in Microsoft Dynamics AX 2012 you can lower the cost of doing development and then upgrading these customizations.
Events are a simple and yet powerful concept. In daily life, we encounter with so many events. Events can be used to support these programming paradigms.
  • Observation: Generate alerts to see exceptional behavior.
  • Information dissemination: To convey information to right people at right time.
  • Decoupling: The consumer doesn’t need to know about the producer. Producer and Consumer can be sitting in totally different applications.
  • Terminology: Microsoft Dynamics AX 2012 events are based on .NET eventing concepts.
  •  
  • Producer: Object to trigger the event.
  • Consumer: Object to consume the event and process logic based on the event triggered.
  • Event: An action that needs to be triggered
  • Event Payload: Information that can go along with event.
  • Delegate: Definition that is passed to trigger an event. Basically, communicator between producer and consumer
Things to remember while using Events in AX2012
  • Delegate keyword to use in delegate method.
  • Public or any other accessibility specifier is not allowed in a delegate method.
  • Delegate Method return type must be void.
  • Delegate Method body must be empty.
  • A delegate declaration can have the same type of parameters as a method.
  • Event handlers can run only on the same tier as the publisher class of the delegate runs on.
  • Only static methods are allowed to be event handlers.
  • Delegate method can’t be called outside class. Basically, events can’t be raised outside class in which event is defined.
  • Event handlers for host methods can use one of two parameter signatures:
    • One parameter of the type XppPrePostArgs. Go through all the methods available in XppPrePostArgs.
    • The same parameters that are on the host method that the event handler subscribes to.
Now, let’s talk about how to use events in Microsoft Dynamics AX 2012.
  1. Let’s create a class Consumer to create EventHandler (sendEmailToCustomer). This will be called once order is shipped so that email can be sent to customer to notify. It has to be static method.
  2. Now let’s create Producer class where this event (sendEmailToCustomer) is called using Delegates. Add delegate by right clicking on Producer class > New > Delegate.
  3. Change its name to delegateEmail (you can have any name). Parameter should be same as event handler method (sendEmailToCustomer) i.e. of type Email. Notice it has no body and is a blank method.
  4. Now drag and drop sendEmailToCustomer method from Consumer class to delegateEmail
  5. Look at properties of EventHandler. You will notice it is pointing to Class Consumer and method sendEmailToCustomer
  6. If order is not shipped, I am creating another event handler (errorLog) in Consumer class to log error into error log.
  7. Create another delegate method (delegateErrorLog) in Producer class to call this event handler (errorLog)
  8. Drag and drop event handler (errorLog) in delegate method (delegateErrorLog) similar to step 4.
  9. Now let’s create main method in Producer class to ship order and let’s see how delegates can be used to trigger event handlers.
  10. Suppose shipOrder method returns true. Now, if I run this main method, it should go into delegateEmail method and should trigger method sendEmailToCustomer. Let’s run and see the result.
  11. Here is the result and it is as expected so it did trigger method sendEmailToCustomer.
  12. Let’s suppose shipOrder method returns false. Now, if I run this main method, it should go into delegateErrorLog method and should trigger method errorLog. Let’s run and see the result.
  13. Here is the result and it is as expected so it did trigger method errorLog.
  14. Handlers can also be added or removed
    Add Handler: It uses += sign.
    Remove Handler: It uses -= sign.
  15. Now, let’s use addStaticHandler in main method. If you see the code, it is calling addStaticHandler before calling delegate method. If we run it and see the result, it should send 2 emails.
  16. Here is the result as expected.
  17. Similarly if we use removeStaticHandler method instead of addStaticHandler before calling delegate method then it will remove handler and will not send any email.
So, you can see that with the use of delegates and event handlers, it is so easy to trigger events. Also, it will be easy and less time consuming to upgrade it. Suppose if delegates are called from standard methods while doing customizations then it will be so easy to upgrade if standard methods are changed in next release because only 1 liner code of calling delegate method needs to be rearranged and no changes will be required in event handler methods.
Use of Pre and Post event handlers
In Microsoft Dynamics AX 2012, any event handler method can dropped in other method. If the property "CalledWhen" is set to "Pre" then it becomes pre event handler. If it is set to "Post" then it becomes post event handler. Pre event handler is called before the method under which it is dropped and Post event handler is called after method ends. These are so powerful that event handler method can be created in new class and can be dropped in any standard or any other method without changing a single line of code and can be set as pre or post event handler as per business need. Suppose, before creating a customer in AX, business need is to do some business logic then logic can be written in pre event handler and can be dropped in insert method of CustTable. Similarly, if there is post logic to be written after customer is created then post event handler can be created and dropped in insert method of the Customer Table (CustTable).
Let’s see how pre and post event handler methods can be created and used.
  1. Let’s take same example. I added 2 event handler methods in Consumer class.
  2. Drag and drop both these event handlers in method sendEmailToCustomer
  3. Set property "CalledWhen" to Pre for EventHandler1 and Post for EventHandler2.
  4. Now let’s run main method of Producer class again and see the results. It should call EventHandler1 and then sendEmailToCustomer and then EventHandler2.
  5. Here is the result as expected.
With use of events, it has opened so many doors and possibilities. Model architecture and events can be integrated which can help if multiple vendors are doing customizations in different models so that it doesn’t impact customizations of other models/vendors. Use of pre and post handlers is so powerful that it can be used without changing a single line of code in original method. Pre or Post handlers can be just dropped in the original method and will be called automatically before (pre handler method) or after (post handler method) original method.
Stay tuned for more technical tips on Microsoft Dynamics AX 2012.