Thursday, March 21, 2013

Determining the root cause of errors in the Dynamics AX 2009 for Retail POS

NOTE: This is an old post I'm just now getting around to posting 3 years later...  It was helpful back then so maybe some of the people on AX 2009 for Retail can still use it.
 
On occasions, a user will see an error within the POS and something unusual will happen like clear out all of the items selected in the POS or crash the POS.  While this is rare, it can happen.

So the end user (or help desk person) now needs to report the error to the appropriate people within the organization to make sure that it can be investigated since it will more than likely be one of three things: a user error, a bug in the system, or a situational thing like a network or service issue.

Since the person investigating the error cannot step into the code in the POS like you can in  Dynamics AX 2009 or AX 2012 product, it is harder to find out why the code is failing. There is a table in the POS DB that stores all of the actions and errors.

[NOTE: this article was written for when multiple POS DBs per store were supported]

To give some background info, the AX system has a master database and each POS has a database of its own which, in generalities, is a mini-AX database that mirrors tables in AX.  Note that the POS headquarters concept for AX for Retail is different than that of the Dynamics Retail Management Solution (RMS) solution.  The headquarters for AX for Retail is actually a module in AX and not a separate program.  The 'Worksheets' concepts in RMS are called 'Scheduler jobs' in AX but are roughly the same idea.

In AX 2009, the log table is in the [POS DB with the error].[dbo].[POSISLOG].  In here, you should be able to see a line in the table that shows the error stack.
In AX 2012, I don't know the log table but I am guessing it is different since it will mimic the AX DB and the AX table structure is significantly different in the new version.

I won't go into all of the errors but I will let you post yours below if you want.

Hope that helps!

Sunday, March 17, 2013

How to reindex tables AX 2012

There can be performance increases when rebuilding indexes on tables in AX. There are ways in both SQL and AX to do this. As far as I can tell, there is no difference between doing this in SQL vs AX except that SQL can provide more visibility into the process. I'm fine just running it in AX under System Administration -> Periodic -> Database -> 'SQL administration', then clicking 'Index actions' and selecting 'Reindex' (see Figure 1 below)

Figure 1 - Where to reindex the tables in AX 2012

If looking to optimize the system for instance, I would do the following:
  1. rebuild the indexes
  2. do performance benchmarking on key processes
  3. analyze what indexes could be optimized
  4. make those optimization changes to tables in AX AOT
  5. rebuild the indexes
  6. do performance benchmarking on key processes
  7. repeat steps 3-6 as necessary

Wednesday, March 13, 2013

AX 2012 R2 compilation takes a long time

I was asked by a co-worker why the AX 2012 R2 compilations seems to be so much longer than previous versions. The AOS also seems to take longer to restart. He was also inquiring on the overall compiling process like X++ compilation, Full (partial) CIL generation, and finally the database synch and how they all fit together. The CPU seems to get highly utilized (but not fully) on a compilation for R2.

The funny thing with AX is that I've seen a trend with every new release taking longer and longer to compile and AOS restart. When bringing this up with other people in casual conversation they point to the fact that there is more code now and it's more complex yada yada yada. I see that but shouldn't the compilation process be a little more expedient? Hardware prices have come down while software efficiency has gone up. Why does it seem that later releases (or heavily customized systems) take so much longer to run?

Here is an excellent discussion around this topic. Its still a hot topic at the moment so posts are still going on here. I'll summarize some of the content below.
http://community.dynamics.com/ax/f/33/p/102527/195927.aspx#.UUDl1lemgYF
The answer to this is that the compiler won't scale as it is today. There haven't been many updates with the compiler instructions for quite a while and was originally built in 1983. As more code is added, the compilation time will go up. Features like Retail, new table structures like the EcoRes and Global address book, etc will all add significant code. The old architecture was created on memory management techniques when Intel's 8086/iAPX86 were popular (16-bit). The metadata provider the compiler interfaces to is also pretty weak.

Some of the highlights:
  • X++ Compiler doesn't scale well. More code = more time
    • limited to a 32-bit architecture even if running on a 64-bit architecture because AX client is 32-bit (restricts memory that can be used)
  • Adding multiple CPUs will not really help the situation from what people have seen (MAXDOP should be 1 anyways. See DAX Dude - AX MAXDOP settings for SQL performance)
    • The AOS is single threaded and this single thread can only use one processor hence the bottleneck
  • Current Metadata provider the compiler interfaces to doesn't perform well
Possible ways to improve the compilation speed:
  • Build a single tier 'build server' that contains AX client, AOS, and DB. Move completed code via a model store move.
  • Remove best practice checks <- Confirmed that it can cut a table sync from 20 minutes to 10...
  • Compile the code on the AOS server to reduce metadata fetching time
  • Use a CPU with high clock speeds with a high on-chip cache
  • Adequate RAM

Monday, March 11, 2013

Linux Mint 14 error “unable to find a medium containing a live file system”

I have a home PC (aka old work laptop I bought) and was previously running Windows 8 consumer preview on it. Naturally, when I finally booted it up again since November 2012, the preview expired. Rather than buy Windows 8 home or pro, I wanted to switch over to try out Linux Mint 14 Cinnamon. Nothing I like better than Mint and Cinnamon...

The install manuals all talked about burning the ISO to a DVD for booting. It didn't really mention anything about using a USB device to boot from. I did this using 'ISO to USB' but wasn't able to boot from it when the system was restarted despite re-prioritizing the boot order in the BIOS. I then decided to open the directory in the expired Windows 8 system and run the 'mint4win.exe' in the USB. I selected 'Demo and full install' and 'Help me boot from CD'. I then followed the prompts to restart the system.

When the system was restarting, Linux went into its thing but ultimately gave me the error “unable to find a medium containing a live file system”. That was fun. Everything I was reading online mentioned that the install files must've been corrupted or something and I needed to verify the hash using the MD5SUM program, re-burn the DVD at a slower pace, re-download the iso, etc. I tend to not think things like these are the issues and that's a lot of pain in the ass for me... I tried a few things without success until I hit something that worked: 

Resolution: I switched the USB to a different USB port and things worked. Looking a little deeper in the Linux boards, this can happen when using USB 3.0 vs 2.0 for the boot. The only issue is that I don't have any USB 3.0 ports. Mine are all 2.0 but instead of using the ones on the right hand side of my computer, I used the ones in the back.

Friday, March 8, 2013

X++ switch signs for use in matching credits to debits

In certain applications, you may need to switch the sign of an amount variable. For example, $170.00 would be -$170.00 or -$180.00 would be $180.00.  Going from negative to positive is easy with the abs([VALUE]) function but sometimes you don't know if the variable coming in is positive or negative. This would not work for pos to neg.

I used this in a three way auto-match modification so that I could match up debits/credits to each other where the starting amount could be either. Nothing too special but figured the code could potentially help out someone. Just don't use the hardcoded recId or infoLog obviously.

static void daxSwitchSigns(Args _args)
{
    CustTrans   custTrans = CustTrans::find(5637215455);
    Amount      custTransAmount = custTrans.AmountMST > 0 ? -custTrans.AmountMST : abs(custTrans.AmountMST);  
    
    info (strFmt("%1 - Switched signs: %2", CustTrans.AmountMST, custTransAmount));                     
}
Figure 1 - The code to switch signs


Figure 2 - The Output from the code in Figure 1

Wednesday, March 6, 2013

How to get an AX table name from a Table Id

This is a quick post but I'm sure it might help the newbie AX programmers out there.

If you have the id from a table in AX and you need to find out the name of that table, you can use the tableId2Name functionality.

static void Job17(Args _args)
{
    info (strFmt("%1", tableId2name(865)));
}
Figure 1 - The code to get the table name from an id

Figure 2 - The output from the job in Figure 1

static void Job17(Args _args)
{
    info (strFmt("%1", tableName2id('CustTransOpen')));
}
Figure 3 - The code to get the table id from a table name


Figure 4 - The output from the job in Figure 3

Monday, March 4, 2013

AX 2012 for Retail AX to/from POS components changing in new R2 release

In AX 2012 for Retail, there will be significant changes with the R2 release around retail the Retail Transaction Services (RTS) and Store Connect Service. See the following blog post for more information: MSDN Blogs - AX for Retail 2012 R2: Installing the Real-time Service. I'll try to summarize the changes and notes below. This is not around the install, but just general notes.
  1. Retail Transaction Service (RTS) is now Commerce Data Exchange: Real-time Service (CDE-RTS)
  2. Store Connect (SC) is now Commerce Data Exchange: Synch Service (CDE-SS)
  3. CDE-RTS is now an IIS web service instead of a windows service like RTS was
  4. Install of R2's CDE-RTS and CDE-SS are very different than RTS and SS. It is more complicated than previous versions of AX for Retail.
  5. CDE-RTS should not be on an PROD AOS server (now that it is IIS, it should be on an IIS server)whereas RTS was located on an PROD AOS.
  6. In upgrading to AX 2012 for Retail R2, there is backward compatibility with AX 2009 and 2012 for Retail. These will still be RTS windows services on the AOS like before.
There is not much out there in regards to this stuff right now so this is not a comprehensive list. Please add other changes of interest in the comments section. These are just some findings while doing some pre-sales.

One of the biggest features in the new R2 release is Microsoft's push towards Multi-channel sales and the consolidation and management of the components into a centralized location (AX) for a single point of control. Additionally, working in conjunction with SharePoint 2013, there is an awesome customer facing storefront that can be deployed 'out of the box' (OOTB). I'm sure I'll cover this in more detail in a later post as well as the OOTB Facebook integration for authentication.

Here are some other resources that might help you on your AX 2012 for Retail Multi-channel/E-Commerce journey:
technet.microsoft.com: Documentation roadmap for a Microsoft Dynamics AX Retail online store [AX 2012]
technet.microsoft.com: Deploy a Microsoft Dynamics AX Retail online store on a stand-alone server [AX 2012]