Tuesday, March 31, 2015

AX2012 JSON 2 XML converter


While writing some code for the Exchange Rate Provider class, I ran across an issue where some exchange rate provider APIs only gave JSON output instead of XML.  I found very little in Dynamics AX that would let me deserialize JSON.  The only alternative was to manually parse the data based on the structure provided at the time.

I didn't like that approach.  Manually parsing data like that can be a nightmare.  The only tools I know of in Dynamics AX are the XML tools.  With that in mind, I decided to write a JSON to XML converter.

classdeclaration


loadFromFile


convert2xml

convert

getTag




Sample JSON exchange rate data from Fixer.io.



XML version after running it through the converter.


Sunday, March 29, 2015

Zebra Printer Label Printing with Dynamics AX 2012 R3


Microsoft Dynamics AX 2012 R3 introduces label printing capabilities.  It does this by sending ZPL commands directly to a Zebra printer.

After researching the new capabilities, in tangent with the new warehouse License Plate functionality I was able to derive enough information to design my own label printing functionality.

There are several stages involved in the development process, which is a prerequisite to printing labels directly to Zebra printers.

  • A label designer, which will print ZPLII code and allow for field names where data substitution needs to occur (optional).
  • A table in Dynamics AX to store the design in ZPL format (memo field).
  • A class that does the data substitution against the ZPL code, which then sends the resulting string of data directly to the printer.
  • A printer capable of interpreting ZPL commands.

This article will explain the prerequisites, and give code examples on how to send label output directly to a Zebra printer.

Note:  I do not have a Zebra printer, and even though the printer I do use, doesn't print anything it does recognize that commands are being sent to the printer.  So I am concluding that should I have a Zebra prnter, the code example in this article would work.  If anyone can confirm that would be great.

For examples in this article, I am going to use the ZebraDesigner version 2.5 from Zebra Technologies Corporation



The first step in the process is to create a label design.  Preferably a design that can be used as a template for reuse.  The example I am creating will contain just one barcode.  I won't go into how to create the label, that can be determined by reading the documentation for ZebraDesigner.



The next step is to print the label to a .prn file.  Notice the highlighted fieldname in the text below.  I came up with that field name.  Later in the process that field name will get substituted with data.


Now that we have a 'template', we need to create the infrastructure in Dynamics AX to store the template and act upon it.  To do this a table was created called ZPLDocumentLayout.  It will store three things.

  • A layout Id.
  • A description of the layout.
  • The ZPL code from the template. (This is a memo field in the table)
To support data entry for the table a form called ZPLDocumentLayout was created and data was populated as follows:


Notice the form has a LayoutId of 'ZPL1'.  That is a code that I made up, and will use later in the process to identify which ZPL template data to use for the labels.  Also notice the template data has been inserted into the record. 

Next I created a table called ZPLDocumentLabel to hold the data for the labels.  It is a simple table with one field called BarcodeId, and holds 3 records, whose values are 'Label1', 'Label2', 'Label3'.

Now that the underlying data, and templates exist, a class needs created specifically to do the data substitution for the template.

Create a class called ZPLDocumentPrint with the following methods.



The code for the methods are listed below:

classDeclaration
getFieldList
initMenuFields
new
printDocument

The magic in this whole process is the new CSharp project WHS.DeviceCom, which was introduced in R3.  It allows communicating directly with printers with raw data.  Microsoft.Dynamics.AX.WHS.DeviceCom.Printer::SendStringToPrinter().

translate

What's fascinating about the translate method it substitutes the field names in the ZPL code, with the table field values in the ZPLDocumentLabel table by matching the field names between the ZPL code and table.


The final piece to the process is to bring it altogether and print the label data from the ZPLDocumentLabel table.  I did this using a job, which invokes the ZPLDocumentPrint class.  The code for the job is as follows:

The output can be captured through a debugging process and entered into a form online at Labelary Online ZPL Viewer

The output from this article looks like this:


Please note that you might need to enable pass through mode on the printer properties,  Prior to WHS.DeviceCom, the method I would use would be to send the ZPL string, wrapped in pass through codes ${ and }$ respectively.

Determining layers in AOT elements for Dynamics AX 2012


When working with new clients its a good to get an idea to the level of customizations they have.  Usually upgrading Dynamics AX for a client it exponentionally proportional in time and effort to the degree of customization.

The code segment shown below, gives an example of how to determine the degree of customization.  The code will transverse the AOT , node by node based on a base node and report back the number of customizations per element.  

The code is fairly useful in that it shows how to transverse the nodes in the AOT, and how to get information about those nodes.

I received an out of memory error when trying to check the layers of multiple base nodes, so I just run it for one base node at a time.  If anyone knows why it would run out of memory, please let me know.





Number of elements and number of which are customized layers

Pulling source code from the AOT in Dynamics AX2012


There may come a time when you want to pull the source code to a class method out of the AOT by using XPP.  This can be accomplished by pulling the AOT source code out of the tree node of an object in the AOT as follows:

static void GBS_JEH_ShowCode(Args _args)
{
 
    TreeNode tn;
    str code;
    ;
    tn=TreeNode::findNode(@'Classes\ExchangeRateProviderFixer\classdeclaration');
    code = tn.AOTgetSource();
    info(code);

}

Of course for the code to work, you would have to have an ExchangeRateProviderFixer class in this scenario, so choose your own class and substitute accordingly.


Result of job execution


It would be interesting to iterate through the AOT , pulling out all the source code in the nodes to see what we come up with.


Executing a Stored Procedure from AX


I am not really a fan of having external code supporting functionality within Dynamics AX, but there may come a time when for whatever reason you need to create a stored procedure and have it executed from XPP code.

server static void executeSP()
{
    Connection con = new Connection();
    Statement stmt = con.createStatement();
    ResultSet r;
    str sql;
    SqlStatementExecutePermission perm;
    ;
    sql = strfmt('EXEC [insertdaxjob]');
    perm = new SqlStatementExecutePermission(sql);
    perm.assert();
    try
    {
        stmt.executeUpdate(sql);
    }
    catch (exception::Error)
    {
        print "An error occured in the query.";
        pause;
    }
    CodeAccessPermission::revertAssert();
}

Debugging a Dynamics AX2012 SSRS RDP Report


I haven't put my finger on it yet, but there are times when I am unable to debug an SSRS RDP Report.  I add my breakpoint but during code execution, the system just won't break when it should.  I believe this is related to how the classes are extended.

While faced with this delima, I did some research on the internet and found an article which shows how to create a job for debugging purposes.  Please follow this link for the original reference: Test Report Data Provider in AX2012.

The following is a simple job to invoke an SSRS RDP report.  It doesn't actually print the report, but it does do the meat of the processing so you can debug your RDP code.  Substitute your RDP class and Contract information as required.

static void Job3(Args _args){
TmpABC tempTable;
InventABCDP dataProvider = new InventABCDP();
InventABCContract contract = new InventABCContract();
contract.parmABCModel(ABCModel::Link);
contract.parmCategoryA(10);
contract.parmCategoryC(20);
contract.parmCategoryB(70);
contract.parmInterest(2.5);

dataProvider.parmDataContract(contract);
dataProvider.processReport();
tempTable = dataProvider.getTmpABC();

while
 select tempTable
{
info(tempTable.ItemName);
}
}

Saturday, March 28, 2015

Creating Exchange Rate Providers in Microsoft Dynamics AX 2012 for JSON Rates



Microsoft Dynamics AX 2012 has the frame work for integrating currency exchange rates from exchange rate providers. Please reference Creating Exchange Rate Providers for Microsoft Dynamics AX 2012. The referenced document from Microsoft shows how to customize the frame work to work with Oanda Exchange Rates .

There are other providers, some which offer a fee based API and others which offer a free API. Doing research on these providers led me to JSON Rates. They offer a free API, which has the functionality needed for basic currencyPair conversion rate retrieval.

This blog entry uses the referenced document from Microsoft as a guide to create a provider class in Dynamics AX specifically for use with the JSON Rates API.

The provider class we will create will support the JSON Rates API.

Create the class as ExchangeRateProviderJSONRates and have it extend the ExchangeRateProvider as shown in the class declaration below.

Note: The ExchangeRateProviderIdAttribute is a unique ID that you will need to supply. You can obtain a unique ID from http://createguid.com


Now create a method called getConfigurationDefaults. This method will provide the default URL used to make requests to the provider.


Next create the getExchangeRates method. This method is responsible for constructing the URL to request the currency information from the provider, and store the results in the currency exchange rate tables of Dynamics AX.



Next create the getName method. This method is used by Dynamics AX to populate the list of providers that Dynamics AX has been modified to support.


Once the getName method is created, create the getProviderId method. This method simply returns the unique GUID that was assigned in the class declaration.

Next create the getSupportedOptions method.


The last method that needs created is the readRate method. It is responsible for parsing the XML response string from the provider, and storing the exchange rate and currency information in the Lists.



A JSON to XML converter class will also need to be added as a dependency, which is coded as follows:

classdeclaration

loadFromFile

convert2xml
convert
getTag


Now that the class has been created, it can be used in currency configuration and setup within Dynamics AX.




currency2