The Microsoft Dynamics AX commerce runtime (CRT) serves as the engine for a retail channel. It connects to a CRT database that stores business data for the channel.. Dynamics AX uses the CRT Architecture in the Retail ePOS, mPOS and in the Sharepoint based eCommerce solution. Also the SiteCore eCommerce solution uses the CRT as the integration to Dynamics AX.
Let’s look at some of the interesting things with CRT.
1. It is a well-documented framework supported by Microsoft. More details on it is available here.
2. It can make it easier to integrate business logics to other eCommerce solutions. Like Magento.
3. We can create CRT web-services that handles information like very advanced retail prices, on-hand shipment, check-outs etc.
4. And MUCH more. This CRT we will have almost everything we need to interact with external system. It Rocks !
Let’s take an example. I would like to utilize the CRT to calculate a sales price with discounts. Price/discounts in AX is very flexible and almost all options you can imagine. Here is a small example of the possibilities we get in Dynamics AX 2012 R3 CU 8.
Let’s say we would like to expose this price/discount structure as a web-service to external parties. Since the CRT is relying on it’s own channel database, it means that the much of the integration is actually not creating a heavy load on the Dynamics AX database. We also have the possibility to “scale out” on the architecture.
The CRT is developed in Visual Studio, and is basically just a bunch of dll’s. I have to admit, that Visual studio, Web-services and is not my strongest side. So I decided to see it I could access and use the CRT framework directly from Dynamics AX. The new call-center module in AX 2012 R3 CU8 is using this, and I wanted to create a very simple job that exemplifies how CRT operates and can be used. Basically I’m looking for this:
I use the standard AX 2012 R3 CU8 contoso demo data, but added the following quantity discount to the Houston store;
Since I know X++, I’ll use X++ job to try this. The infolog I got was the following:
Here we see that the CRT returned the sales price, discounted price, and also information like total amount. Surely it can give everything else, but I wanted to keep the example easy to understand.
I created the following job to play with the framework, and it gives you an idea of how to interact with the CRT from AX.
static void demo_CRT_GetSalesPrice(Args _args)
//To test this code, use the AX 2012 R3 CU8, and use the USRT company
System.Object roundingRule, currencyConverter;
CLRObject clrSalesLines, enumeratorSalesLine;
System.String customerPriceGroup = "";
RetailStoreTable storeTable = RetailStoreTable::find("HOUSTON"); //Lets use houston as an example here
RetailChannelRecId channelId = storeTable.RecId; //This is the recid for a retail channel. A retail store is an extension of a retail channel.
CurrencyCode currencyCode = storeTable.Currency;
appl.setDefaultCompany(storeTable.company(), false); //Setting default company to houstons company
//Creating a unique line ID
lineIdString = System.Guid::NewGuid().toString();
InventDim.InventLocationId = storeTable.inventLocation;
InventDim.InventSiteId = InventLocation::find(storeTable.inventLocation).InventSiteId;
InventDim = InventDim::findOrCreate(InventDim);
//Pricing manager : Encapsulates data access to pricing information.
pricingManager = Microsoft.Dynamics.Commerce.Headquarters.RetailProxy.AxPricingDataManager::BuildDataManager(channelId);
//Price parameters : types of AX discounts (aka trade agreement discounts, aka not Retail Periodic Discounts) are currently activated and should be allowed on the transaction
priceParameters = Microsoft.Dynamics.Commerce.Runtime.Services.PricingEngine.DiscountParameters::CreateAndInitialize(pricingManager);
roundingRule = Microsoft.Dynamics.Commerce.Headquarters.RetailProxy.ServiceHelpers::GetRoundingMethod(currencyCode);
currencyConverter = Microsoft.Dynamics.Commerce.Headquarters.RetailProxy.ServiceHelpers::GetCurrencyConverter(currencyCode);
activeDateTimeOffset = RetailPricingEngineHelper::getSessionDateTimeInChannelTimeZone(channelId);
//Next we create a crtSalesLine, that represents a channel agnostic sales line.
crtSalesLine = new Microsoft.Dynamics.Commerce.Runtime.DataModel.SalesLine();
crtSalesLine.set_ItemId("0001"); //Lets use product 0001 as our example
crtSalesLine.set_Quantity(10); //Lets use quantity 10 as our example
crtSalesLine.set_LineId(lineIdString); //Let give this line a uniqe ID
crtSalesLine.set_UnitOfMeasureSymbol("ea"); //Let use 'ea' as the unit
//We then create a sales transaction, and add the salesline to this.
crtSalesTransaction = new Microsoft.Dynamics.Commerce.Runtime.DataModel.SalesTransaction();
clrObjectSalesLines = crtSalesTransaction.get_SalesLines();
clrObjectSalesLines.Add(crtSalesLine); //This is where the we add the salesLine to the sales transaction
//Lets calculate the prices
//Lets calculate the discounts
//And, let's show what the CRT can give us.
qty = crtSalesLine.get_Quantity();
Price = crtSalesLine.get_Price();
info(strFmt("Normal sales price is %1 when buying %2", price, qty ));
Price = crtSalesLine.get_DiscountAmount();
info(strFmt("Discount amount pr unit is %1, when buying %2", price/qty, qty ));
Price = crtSalesLine.get_NetAmountPerUnit();
info(strFmt("Net amount pr unit is %1, when buying %2", price, qty ));
Price = crtSalesLine.get_TotalAmount();
info(strFmt("Total amount is %1 when buying %2", price, qty ));
Maybe some of you can teach me how to expose the CRT in a web-service, so that we can easily