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

Issue
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.




Reason:
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.

Resolution:
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=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its

dependencies. The system cannot find the file specified.
File name: 'Microsoft.SqlServer.Types, Version=10.0.0.0, 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&

stackMark)
   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

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].
.


Issue



Friday, May 23, 2014

Dynamics AX 2012 R3 Demo VM Launched

Dynamics AX 2012 R3 Demo VM has finally been launched featuring fully loaded demo data and instantiated application. This is the first release for R3 as the previous releases were mainly CTP demo versions which are actually WIP preview releases for R3.
The VM can be easily downloaded from both Partnersource and Customersource, and there are tons of materials both documents, videos and blog posts for trying out the new functionality incorporated in AX 2012 R3 expecially on the Retail, Wax &Trax, Mobile etc. Microsoft has improved a lot on the documentation front with these additions compared to the previous version releases.
For those who have active Azure subscriptions, the demoVM is available in just a few clicks via the Life cycle services portal, without the need for complicated disk and ram requirements to run the demo VM.
Here is the link for Partnersource to download the Demo VM

Tuesday, May 6, 2014

Dynamics AX 2012 R3 is now live!

Dynamics AX 2012 R3 is now in GA mode, you can now easily download it from both Customersource and Partnersource.

Every new release has brought lots of expectations about the changes and R3 is no different. For the starters, AX 2012 R3 can be hosted on Azure in addition to on-premise, which means the product can be officially hosted on the cloud and clients can access it via internet.
Most of the functionality changes seems to be on the improvements of the existing modules or verticals. The changes are mainly highlighted on the Retail, Warehouse and Transportation management and full integration with SCOM for application monitoring.

On the Retail vertical front I noted,
Architecture change in the data transfer between the Retail Stores and HQ. The R3 version works as WCF hosted on IIS, which allows for greater scalability than previous versions as a windows service. And A-jobs has been replaced by SQL change tracking, needing to eliminate the A-jobs from AX side.

From Retail functionality wise - Kits, advanced discounts and loyalty is much improved in the new version.

For the complete list, please take a look at the Getting started with AX 2012 R3 which has direct links to Technet and MSDN for detailed information on each of the release details.


Monday, April 7, 2014

Modify the System fields in a Table

The system fields in Dynamics AX are the CreatedBy, ModifiedBy, Created Date Time, Modified Date Time, Partition, DataareaId, RecId, these fields are not directly modifiable by the users as they are auto generated during insert and update operations. If in any case you are doing a migration or would need to capture some relevant user id or created/modified date time you can still do it. Here is how,

First inform the kernel and as proper permission for the OverwriteSystemfieldsPermission.assert() and then activate the relevant table's overwriteSystemFieldsmethod - True to indicate these tables system fields values will be provided, however for the values that you don't provided the system will still populate with the default values. To refer to the fields use the tables field id's rather than the intellisense field name. Update remaining business column values and then insert the record. Make sure to set back the overwriteSystemFields method - False to revert to the settings. 

So the sample code would look like this.

Table      sampleTable;

ttsbegin;

new OverwriteSystemFieldsPermission().assert();
sampleTable.clear();
sampleTable.overwriteSystemFields(True);
sampleTable.(fieldNum(Table, CreatedBy) = 'DM-Admin'; //User id - If possible get from SysUserInfo table
sampleTable.(fieldNum(Table, ...othersystemFields)) = //Use appropirate assignment for the system fields
sampleTable.NormalColumns = //Your normal business column values
sampleTable.insert();
sampleTable.overwriteSystemFields(false);

CodeAccessPermission::revertAssert();

ttscommit;


Wednesday, March 12, 2014

SQL Error: String or Binary data would be truncated

Issue: SQL error during Insertion of records to a custom table
"String or Binary data would be truncated" and the SQL insert command is shown in the error infolog.

Description:
The issue will occur only if you have modified the field column length of a table after the records are created in Dynamics AX. When you are trying to insert the records, even though your data is within the column length, the existing rows might be inconsistent with the new data inserted. No synchronization errors are shown but the error will be only upon insert.

Resolution:
Delete the affected column and recreate the column with the correct length, impact existing data might be lost. Make sure to evaluate the issue's pro's and con's before actually deleting the columns and as a Golden rule always always backup the Database/Table before any columns are deleted. You don't want to have nasty surprises or abnormal behaviors after the deletion.