Pages

Tuesday, January 27, 2015

Create QR codes from AX 2012 R3 CU8

It seems like the Brazilian authorities are very modern in their approach to how you report to and communicate with them. I have found several neat things in AX from the Brazil specific features.

This time I stumbled over an assembly called QRCode and I thought I should look into what that was used for. It turns out you can create QR codes from AX pretty easy. Here is an example:
static void JobCreateQRCode(Args _args)
{
    Image           image;
    container       imageContainer;
    str             url;
    EFDocQRCode_BR  qrCode;  
    
    // The url to create the QR code. Could also for example be an e-mail address
    url = 'http://www.agermark.com';
    
    // Create an instance of the QR code class
    qrCode = new EFDocQRCode_BR();
    
    // Generate a QR code for the URL and save the result to a container
    imageContainer = qrCode.generateQRCode(url);
    
    // Use AX's good old Image class to load the image from the container
    // and save it as a file
    image = new Image();
    image.setData(imageContainer);
    
    image.saveImage("F:\QrCode.jpg", ImageSaveType::JPG);
}
You can now open the file and see the resulting QR code.

It links to www.agermark.com. Which leads me to the thing I really don't understand about QR codes. For security reasons we are always told not to click an URL that doesn't seem familiar. But scanning QR codes having absolute no idea about where they lead to is perfectly alright. Go figure.

Monday, January 5, 2015

Entering a multi line control in a grid

If you add a multi line FormStringControl to a grid, and set it up to just show one line in order to keep the normal layout of the grid, you will find that the control behaves differently depending on how you enter it; by keyboard or mouse.

If you enter the control by keyboard, it behaves as expected setting the cursor on the first line of the text. But, if you enter the control using the mouse it starts out by clearing the field and making it blank. Only when you click the field again or use up and down arrows it will show the text.

Today I spent a couple of hours trying to figure out how to fix it, and all I could come up with was the following odd solution. So, I run some code when I release the mouse button after moving the cursor into the field. This helps, but doesn't quite fix the problem. To fix it entirely I have to call that exact same code again after a short wait.

So here is my code. Executed once, and then again after a short wait for 100 ms.
public int mouseUp(int _x, int _y, int _button, boolean _Ctrl, boolean _Shift)
{
    int ret;

    ret = super(_x, _y, _button, _Ctrl, _Shift);

    this.setLineFocus();

    // The same code needs to be called again after a short wait in order to make
    // the control show the right line and move the cursor to that line
    this.setTimeOut('setLineFocus', 100);

    return ret;
}

private void setLineFocus()
{
    element.lock();
    [formStringControl].lineIndex(1);
    [formDataSource]_ds.refresh();
    element.unLock(false);
}
If I remove any part of this code, the fix won't work. I don't have any good explanations about this behavior, but it works so I'm happy leaving it at that.

Thursday, January 1, 2015

Testing JSON from AX 2012

I wanted to see how JSON could be consumed from AX, and found this great article from Jonathan.

Then I needed something to test with and found the site jsontest.com.

And so, here are two examples.

The first example just returns your IP address:
static void JSONTestIP(Args _args)
{ 
    RetailWebRequest    request; 
    RetailWebResponse   response; 
    str                 rawResponse; 
    Map                 responseData; 
    str                 responseValue;
    
    RetailCommonWebAPI webApi = RetailCommonWebAPI::construct(); 
    
    request = RetailWebRequest::newUrl("http://ip.jsontest.com"); 
    response = webApi.getResponse(request); 
    
    rawResponse = response.parmData(); 
    
    responseData = RetailCommonWebAPI::getMapFromJsonString(rawResponse); 
    responseValue = responseData.lookup("ip");
 
    info(strFmt("Element name: %1", responseValue));
}

The next example returns key/value pairs. In this example first name of a person is found based on the persons last name:
static void JSONTestKeyValue(Args _args)
{ 
    RetailWebRequest    request; 
    RetailWebResponse   response; 
    str                 rawResponse; 
    Map                 responseData; 
    str                 responseValue;
    
    RetailCommonWebAPI webApi = RetailCommonWebAPI::construct(); 
    
    request = RetailWebRequest::newUrl("http://echo.jsontest.com/Agermark/Palle/Kent/Clark"); 
    response = webApi.getResponse(request); 
    
    rawResponse = response.parmData(); 
    
    responseData = RetailCommonWebAPI::getMapFromJsonString(rawResponse); 
    responseValue = responseData.lookup("Kent");
 
    info(strFmt("Element name: %1", responseValue));
}