Saturday, June 21, 2014

Mysterious issue of missing R3 Retail "Active price" in Retail Product Pricing

Dynamics AX 2012 R3 Retail HQ you will be able to see the Store specific pricing for each of the products. The form can be accessed either from Stores or Products from the Retail ribbon bar. The Retail price list form consolidates the details from various sources like assortment, product pricing and Trade agreements. So it can be "laggy" when you open the form if you have lots of products or stores.

There are various columns for price and discounts, my focus at this time is on the column "Active price". It is supposed to show the final product price after computing from the trade agreements if any or just the base sales price. But in my application it was showing as Zero, even if I had an appropriate trade agreement applicable for the Product. 

Deeper investigation reveals that the actual pricing is computed by the PricingEngine dll from Reference assembly Microsoft.Dynamics.Commerce.Runtime and which is inturn handled by the DLL Microsoft.Dynamics.Commerce.Runtime.Services.PricingEngine.dll from the RetailPricingEngine class. It always broke without error during the invocation of the dll function. Was wondering why it was breaking exactly at this point. While I checked and compared with another environment that was working as expected for price computation. Compared the DLL size/modified date/contents and it seemed everything was same except the calculation was not showing correctly.

Finally after an exhaustive search(coincidentally Retail POS was also not showing correct product prices which prompted for a detailed function call by call trace) found the issue on the HQ was due to simple setting at the AOS. Due to the back and forth hot swapping of assemblies between the client and server, bringing my Debugger in between crashed the DLL function call of pricing engine. I was hoping for a decent error or warning to indicate something wrong with the dll but it just ended quietly without triggering any messages. So I disabled my hot swapping of assemblies at the AOS and restarted the AOS service. Active prices came back and the Pricing Engine DLL did its job as expected to return the exact prices which would be seen in the Retail POS.

An interesting point to note is both the HQ and the POS use the same Pricing Engine DLL to get the product price for the store with all other parameters included for consideration. So if you see the Product price in the HQ pricing form, it is guaranteed to be same on the POS price window(conditional discounts, promotions, etc not applicable) for a unit of that product.

Dynamics AX 2012 R3 Retail - Install Async Client - Things to Note

A couple of things to note to check for the installation of the Async Client

1. AsyncServer - Installed and configured properly
You should receive a IIS webserver reply(Contents are not configured to be listed - 403 Error) when you visit the URL(https://FullyQualifiedServerName:Port/ASyncServer/) from the browser from the Machine that you want to install the Async Client

2. Create Channel Database - In Microsoft Dynamics AX create the Channel Database from Retail > Setup > Retail Scheduler > Channel Database and follow the details in the MSDN help for the Form fields
Do a Full Meta Data Sync from Retail Scheduler Parameters, this is to create a an entry in the Async Server DB that the new Channel DB is configured at the HQ
Make sure the DB name is the AsyncServerHQMsgDB

3. User Name & Password - Provide the user name and password for the Async Client to execute on the local machine.

4. Server Certificate - Make sure to export the Server certificate that was provided for the Async Server from the MMC console( MMC > Add snap-in console > Certificates), also import on the ASyncClient machine using the MMC(Normal install certificate is not enough) to Trusted Root Certification Authority in Local computer

AX 2012 R3 Retail POS Error - Microsoft.SqlServer.Types Error - System cannot find the file specified

You might come across this error when you deploy a standard R3 POS while performing an operation for Getting Product Price, or Adding New Customer, etc essentially any operation that involves sending limited commands to the POS Store DB on another server from the POS machine.

On certain occasions you might have a centralized Store DB which is used by all the POS machines and you would not need a offline DB(SQL Express) because you are absolutely sure that the network is always on for the POS. But still the POS requires a minimum of feature pack components for all the operations dll that does DML operations on the store DB.

Some of the impact of these missing SQL components are unable to create new customer(Write to Store DB ) or Calculate Product prices (Pricing Engine) will return zero price.

If you already have a SQL server express then all the necessary components are already covered else the minimum two components of the SQL Server feature pack - SharedManagementObjects.msi and SQLSysCLRTypes.msi

Restart your POS and your Microsoft.SqlServer.Types error will no longer occur and you should be able to see the R3 Retail functionality to work as expected. Hope the post solves someone issue.

Detailed Error Message:

LSRetailPosis.POSProcesses.ProcessInput: System.IO.FileNotFoundException: Could not load file or assembly

'Microsoft.SqlServer.Types, Version=, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its

dependencies. The system cannot find the file specified.
File name: 'Microsoft.SqlServer.Types, Version=, Culture=neutral, PublicKeyToken=89845dcd8080cc91'
   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity,

RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean

forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity,

RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean

forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity,

RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean

forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.Assembly.Load(AssemblyName assemblyRef)
   at System.Data.SqlClient.SqlConnection.ResolveTypeAssembly(AssemblyName asmRef, Boolean throwOnError)
   at System.Data.SqlClient.SqlConnection.<>c__DisplayClass19.<CheckGetExtendedUDTInfo>b__17(AssemblyName asmRef)
   at System.TypeNameParser.ResolveAssembly(String asmName, Func`2 assemblyResolver, Boolean throwOnError, StackCrawlMark&

   at System.TypeNameParser.ConstructType(Func`2 assemblyResolver, Func`4 typeResolver, Boolean throwOnError, Boolean

ignoreCase, StackCrawlMark& stackMark)
   at System.TypeNameParser.GetType(String typeName, Func`2 assemblyResolver, Func`4 typeResolver, Boolean throwOnError,

Boolean ignoreCase, StackCrawlMark& stackMark)
   at System.Type.GetType(String typeName, Func`2 assemblyResolver, Func`4 typeResolver, Boolean throwOnError)
   at System.Data.SqlClient.SqlConnection.CheckGetExtendedUDTInfo(SqlMetaDataPriv metaData, Boolean fThrow)
   at System.Data.SqlClient.SqlDataReader.GetValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData metaData)
   at System.Data.SqlClient.SqlDataReader.GetValueInternal(Int32 i)
   at System.Data.SqlClient.SqlDataReader.GetValue(Int32 i)
   at Microsoft.Dynamics.Commerce.Runtime.DataModel.CommerceEntity.Populate(SqlDataReader sqlDataReader, TimeZoneInfo

   at Microsoft.Dynamics.Commerce.Runtime.Data.DatabaseAccessor.ExecuteReader[T](SqlPagedQuery query)
   at Microsoft.Dynamics.Commerce.Runtime.Data.DatabaseAccessor.ExecuteSelect[T](SqlPagedQuery query)
   at Microsoft.Dynamics.Commerce.Runtime.Data.ChannelDatabaseAccessor.GetStoreById(Int64 channelId)
   at Microsoft.Dynamics.Commerce.Runtime.Data.ChannelDataManager.GetStoreById(Int64 channelId)
   at Microsoft.Dynamics.Commerce.Runtime.CommerceRuntime.CreateRequestContext(Request request)
   at Microsoft.Dynamics.Retail.Pos.PriceService.Price.GetPrice(IRetailTransaction retailTransaction)
   at LSRetailPosis.BusinessLogic.ItemSystem.CalculatePriceDiscount(IPosTransaction transaction)
   at LSRetailPosis.BusinessLogic.ItemSystem.CalculatePriceTaxDiscount(IPosTransaction transaction)
   at LSRetailPosis.POSProcesses.ItemSale.Execute()
   at LSRetailPosis.POSProcesses.Operation.RunOperation()
   at LSRetailPosis.POSProcesses.ProcessInput.Execute()

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].