Thursday, September 26, 2013

AX2012 : Post costs for a project using X++ code

In this post I would like to share X++ code to post costs for a project without any user intervention. Normally post cost  is a three step process, but before running this process you should have proper data setup in the system and have some transactions against the project:

Step 1: User open post cost screen from project form



Step 2: Click on select button the following selection criterion screen opens up














Step 3 - Post: User fills the selection criterion and click OK, system generates some records based on this selection and those records are shown in the post cost screen as shown below and then user posts the cost and these can be seen in posted transactions of the project.

 
















In this process technically system populates some temporary table buffers based on the user selection criterion and then posts the costs based on the temporary tables populated in step 2. It is important to know the classes and there hierarchy involved in this process.
Hierarchy of classes used to build the temporary table buffers for posting the cost based on user criterion are shown below:















Hierarchy of classes used to post the cost is shown below

 











The three steps shown above can be automated using the below X++ code job:

 


















Let me show you how the code relates to the actual steps:
The selection criterion in step 2 goes here:
You can create a setup to run the code on any setting. For illustration I have used Balance in the job.















The Query criterion in step 2 again goes here


 
The assignment of temporary table buffer to post the cost goes as shown below:














Trigger of post function goes here:




For those who quickly want to reuse the code, here it is:

  Args                                args;
  ProjPeriodPostingSelectCost_Proj    projPeriod;
  ProjId                              projId = strFmt("%1*",'JOB001159'); //Your project Number
  ProjPeriodPostingLedger             projPeriodPosting;

  args = new Args();
  args.parmEnumType(enumNum(ProjCostSales));
  args.parmEnum(ProjCostSales::Cost);
  projPeriod  = ProjPeriodPostingSelect::newProj(args,projId);
  projPeriod.setQueryRange();
  projPeriod.initQuery();
  projPeriod.parmProjLedgerStatus(ProjGroup::periodic2ledgerStatus(ProjLedgerStatusPeriodic::BalanceSheet));
  projPeriod.parmTransActionDate(systemDateGet());
  projPeriod.parmQueryCost(NoYes::Yes);
  projPeriod.parmQueryEmpl(NoYes::Yes);
  projPeriod.parmQueryItem(NoYes::Yes);
  projPeriod.parmProjTimeMaterial(NoYes::Yes);
  projPeriod.parmProjInternal(NoYes::Yes);
  projPeriod.createTrans();

  //Posting the cost
  projPeriodPosting  = ProjPeriodPostingLedger::construct(args);
  projPeriodPosting.getLast();
  projPeriodPosting.parmProjLedgerStatus(ProjLedgerStatus::BalanceSheet);
  projPeriodPosting.parmtransActionDate(systemDateGet());
  projPeriodPosting.parmAcknowledgementDate(systemDateGet());
  projPeriodPosting.parmTmpProjPeriodic(projPeriod.tmpProjPeriodic());
  projPeriodPosting.parmTmpProjPeriodicCost(projPeriod.tmpProjPeriodicCost());
  projPeriodPosting.parmTmpProjPeriodicSale(projPeriod.tmpProjPeriodicSale());
  projPeriodPosting.run();

Next section is for those interested in deep diving into the job:

U might notice that I have declared object of ProjPeriodPostingSelectCost_Proj class instead of ProjPeriodPostingSelectCost and the reason for this is I need to initialize query for the project. If you debug the standard AX class then you will notice that the function to initialize it for a project is called from the dialog() method of class "ProjPeriodPostingSelectCost_Proj "

 





















If you dive into this function you will notice that the query is getting initialized here

















As we are doing this fully behind the scenes and will not be calling the prompt() method so we cannot initialize the query from the base class as it does not has this function






















So in order to initialize our query properly we need to call this method.Another important thing to note is the sequence of calling the methods as shown in job is important.

Thanks for reading the blog. Have a great day!!!
Rachit Garg

Wednesday, September 25, 2013

AX2012 : Custom lookup on Dialog control - A standard AX 2012 example


Recently while debugging a process of approving BOM, I came across a standard AX example where registerOverrideMethod() is used to create lookup on a dialog field. Thought to share with the community.

 

There are some nice blogs which explain more about this method :




 
Apart from having the flexibility to create custom lookups on dialog, this also helps us to reuse the existing code.

Saturday, June 29, 2013

VT-x features locked error resolution while setting AX2012 R2 VPC on Windows 8-64 bit machine.

Hi Friends,

I want to share this experience, recently I was configuring AX2012 R2 VPC which I downloaded from Microsoft information source, on my new HP machine having  Windows 8 64 bit operating system and Intel(R) Core(TM) i7-3630QM CPU @ 2.40 GHz processor.

I was configuring it in an Oracle VM virtual box using Oracle VM Virtual Box Manager.

I found some really good blogs having detailed description of how to do it :

http://www.doens.be/2011/11/how-to-run-a-microsoft-ax-2012-hyper-v-on-virtualbox/

http://dynamicsnavax.blogspot.in/2011/04/how-to-run-ax2012-hyperv-on-virtualbox.html

http://axretail.blogspot.in/2012/08/ax-retail-2012-vpc-configuration-on.html


So I followed them and once the setup was completed, I started the virtual machine. To my surprise I got the below error message on starting it :
"VT-x features locked or unavailable in MSR.(VERR_VMX_MSR_LOCKED_OR_DISABLED)"


So I again checked my setup and made sure that Hardware Virtualization is enabled in my VM settings, it was enabled but still I was getting the error.




So I started searching for the solution in various forums, I even went to Intel forums to read more about hardware virtualization. Fortunately I came across one of the forum mentioning that by default hardware virtualization is disabled in BIOS settings of most of Intel processor laptops by vendors for better performance and in order to enable it we need to go to host machine BIOS and turn on the virtualization technology.

Keeping my fingers crossed I restarted the machine, jumped into the BIOS of the machine and under system configuration group I found virtualization technology option. It was actually disabled, I turned it on then then saved the settings and exited from the BIOS. I also captured the screen through my mobile camera.



Now when I ran the AX virtual machine, it started up smoothly. Never thought that to start a VM we might need to change BIOS settings.

P.S --> The above information is based on my experience and in case you are getting the same issue that please change BIOS on your own risk or contact your vendor technical support team.




Friday, December 28, 2012

AX2012: Role of attributes in data contracts

Hi Friends,
In continuation to my previous post on Basics of attributes, I would like to take this journey further  to discuss the use DataMemberAttribute and DataContractAttribute classes provided by AX2012. My idea in this post is not to show how to create a new service or a batch process using attributes but it is to understand the underlying reason for using attributes in these areas.

In short DataMemberAttribute and DataContractAttribute classes are used to define data contracts. However I would like to talk about data contracts in this post so that we clearly understand the meaning of one liner said above .So let's begin with some initial questions which come to mind when we hear a term like "Data Contract":

What is a data contract? 
If try to understand it word by word in a simple way, contract means an agreement to exchange something between two parties, similarly data contract means that data is being exchanged between two parties.

Who are the two parties which exchanges data?
Now let's start moving towards technology, the parties involved in a data exchange are client and a service.

Who provides framework for data contract?
WCF (Windows Communication Foundation) provides the framework for data contracts.

In which format the data is exchanged?
Data exchange happens in XML. The data is serialized and deserialized (converted to and from XML) during the process of data exchange.

Who does data serialization and deserialization?
There is a serialization engine called "Data Contract Serializer" which used by WCF to convert the data to and from XML.

So now when we know about the basics of data contract along with a technical flavor so the next questions which come to mind are:

How system identifies what data needs to be exchanged?
Here comes the roles of Attributes. There are 2 attributes which are used to decorate/mark/tag/identify the data which needs to be part of a data contract. These attributes are DataContractAttribute and DataMemberAttribute.

Where to define DataContractAttribute?
To keep it simple DataContractAttribute is defined on classes. More details can be found on MSDN.

Where to define DataMemberAttribute?
DataMemberAttribute is defined on each of the members of the class which needs to be exchanged.

How to define these attributes?
In the same way we define a normal attribute. You can refer to my last post Basics of attributes as well.

Standard AX2012 out of the box provides us with these attribute classes:

DataMemberAttribute 














DataContractAttribute


Examples can be found in standard AX where these attributes are used, an example is shown below:
















DataContractAttribute and DataMemberAttribute also play vital role in SysOperationFramework introduced in AX2012 and there are some very good blogs available to understand how we use these attributes in SysOperationFramework and creation of services. Some really nice articles I would recommend are:

I hope now we are able to realize the power of attributes. They have wide area of applicability and with the ability to create your own custom attributes it is seamless. 


Thanks for reading the blog.

Cheers!!!!!


Thursday, December 27, 2012

AX2012 : Understanding Attributes

Hi Friends,
I would like to discuss about the concept of attributes with an example of how we use them in AX2012. This post will be interesting to those who are new to Attributes concept. It is important to understand that Attributes come from .NET platform they are not simply implemented as language elements.To summarize the general introduction of attributes:
  • Attributes are declarative information used to add metadata information to the code.
  • Attributes are stored as metadata in an assembly. They are NOT part of executable code.
  • Attributes information can be extracted through reflection at run time/compile time/design time.
  • Attributes are extensible, you can create you own custom attributes.
An attribute can be attached by simply typing the name of the attribute enclosed in square bracket before the declaration of class/function where it needs to be applied.

In AX 2012, SysAttribute class is an abstract base class for all attribute classes. So if you have to create your own attribute class then it should be a non abstract class and must inherit from SysAttribute class. 
Attributes can be used in many different scenarios, one of the common practice is to use them in creating batch jobs through SysOperation framework.

Let's jump into some practical way to use attributes, I'll use SysObsoleteAttribute in the below example to get a feel of using attributes:

I created a new class "SampleCalculator" and a method to add two numbers:
Then I created a job to call this method

This is simple, nothing interesting till now. 

In the current method, there is a limitation that it accepts only 2 integers, there can be situations where a person wants to add n number of integers, so to improve the design and usability I thought to create a new function which accepts a list as a parameter so that we can add any number of integers, the new method looks  like below:
We test this method through job, it works good:

Now I want that if any other developer is using the class "SampleCalculator"  to perform the addition calculations, he should prefer using the new function "addMultipleNum()" instead of the old function "add2Num()".
Also, I do not want to delete the previous function as it may lead to compilation errors in system in case the previous function is used somewhere. So what do I do ??? The answer in such situation is use ATTRIBUTES. 
AX2012 provides us with an Attribute class SysObsoleteAttribute for such situations.

I can decorate my first function add2Num() with SysObsoleteAttribute and to do this I simply have to add the attribute in function definition as shown below:

Now the question is how does it impacts the overall process, to know this just compile the job and you will notice that the compiler gives a warning and immediately tells me that this function which I am using in my job is Obsolete.


This is Okay but does it tells me what to do if this function is Obsolete? No not now. 
Can I add some more information to the attribute I attached? YES :)
While defining SysObsoleteAttribute you can see that we can define two optional parameters:
So now I added the explanation in the first parameter for the attribute, notice that value in second boolean parameter "_isError" is passed as false for now.


Now if I compile the job, the warning is more informative, it tells me which function should I use:


This is cool. Now I can inform someone other developers to use the new function, when the try to use the old one.

Now let us change second Boolean parameter "_isError" value to true, compile the code and see what happens:


You will notice that compiler gave an error instead of warning. This is quite helpful in situations where we want to avoid use of some function. This is an example of attributes behavior at compile time.  

This attribute class "SysObsoleteAttribute" is also helpful for ISV's when they release new hot fixes  versions of there product and want there partners to start using new functions when they customize the solution.

An example of SysObsoleteAttribute can also be found in SysDictClass 


There are many attribute classes provided by default in AX. You can get the list by simply looking the type hierarchy browser of SysAttribute class and start playing with them :).

Thanks for reading the post!!!!!













Sunday, October 7, 2012

AX2012 : Move label file between environments

Hi Friends,
Recently, I moved label file from one environment to another environment.I referred to various sources before doing this activity and found the below as most recommended method:

  • Create a dummy model.
  • Move the existing label file to dummy model.
  • Delete the dummy model using Axutil commands.
  • Restart AOS.
  • Import the label file.
  • Restart AOS.

However even after performing the above mentioned steps, I was still not able to view the updated labels. While playing around I found the following solution which I want to share with you all:

  • Delete the *.ali file for the specific label Id, from the folder "C:\Program Files\Microsoft Dynamics AX\60\Server\"Your Application name"\bin\Application\Appl\Standard"
  • Restart AOS
When I reopened the client, I was able to see the updated labels.

P.S. --> The above information is based on my experience and does not guarantee the results in general. Please take essential backups before performing the above task in your environment.

Thanks for your time.

Wednesday, February 29, 2012

Ax2012: View map for addresses


Hi Friends,

Just came across feature in AX2012, ability to view maps for a address.
e.g: On customer master form you will notice a new button “map” under the fast tab of addresses.




When you click this system will open the map in explorer using bing!!! Cool isn’t it J




How it is done: Check the code below. This is also an example of CLR Interop. You can find the standard code using .net function to encode URL.



This feature is also available in AX2009 as shown below: