Показать сообщение отдельно
Старый 19.02.2015, 06:14   #1  
Blog bot is offline
Blog bot
24,225 / 809 (75) +++++++
Регистрация: 28.10.2006
axsa: Retail Extensibility in Dynamics AX 2012 R3 CU8 (CRT, RetailServer, MPOS) Part 1
Источник: http://blogs.msdn.com/b/axsa/archive...os-part-1.aspx


The following document will teach some of the basic steps needed to carry out a simple customization. There are quite a few moving parts that use different technologies; even with a simple customization as this sample. Also, some of the tricks shown below can help you to simplify the development mechanics and actually focus on the task at hand: “extending the Retail Solution”.

Attached is a zip file that includes all new and changed files of the sample.

The steps are carried out on the VM image that can be requested via LCS (https://lcs.dynamics.com/Logon/Index) which most partners have access to (Contoso sample). Alternatively, PartnerSource (https://mbs.microsoft.com/partnersource/northamerica/) can be used to download the VM as well. Make sure you get the CU8 version.

It is recommended to review some of the online resources around the Retail solution, either now or during the processes of following this blog (https://technet.microsoft.com/en-us/.../jj710398.aspx).

This blog will focus on a very simple customization, since this is part 1. The basics reviewed in this blog are:

- Extend the CRT by writing a new CRT service (no existing Retail SDK code change)

- Extend RetailServer by writing a new customer action

- Make MPOS UI design changes in AX and push them to the store

- Extend MPOS by using the new RetailServer/CRT functionality from the UI

A future blog will cover topics and suggestions for changing existing CRT code. Stay tuned for that.

This sample customization will update the MPOS terminal to look up a “cross-loyalty discount”. Assume for a moment that our company allows to apply loyalty discounts from another external company. That discount must be looked up (by sending the phone number as an Id), presented to the MPOS operator and if he/she chooses applied to the current transaction. See the screen shots below for the UI flow:

All changes are being made under the login contoso\emmah. If you use a different account, or different demo data altogether please adjust the below steps accordingly.

High-level steps

The following steps need to be carried out:

Setup the Retail SDK CU8 for development

  1. Prepare MPOS to be run from Visual Studio from unchanged SDK code
  2. Activate the MPOS device
  3. Add a new operation and screen layout button to MPOS
  4. Customize MPOS source code
  5. Add new CRT service and register it with RetailServer
  6. Add new RetailServer action and register it with RetailServer
  7. Test
During steps 4, 5 and 6, code changes need to be made. Not all code that needs to be written is added to the text. In order to explain the code changes, the text refers to the files in the zip file.
Detailed steps

Setup the Retail SDK CU8 for development

Main point here is to keep a backup of the original “Retail SDK CU8” folder so we can later roll back or diff against. In my case, the original SDK folder is under the Administrator user’s Documents folder.

- Open a Visual Studio x86 Native tools Command prompt as administrator

- Mkdir "C:\Users\emmah\Documents\Retail SDK CU8"

- Cd "C:\Users\emmah\Documents\Retail SDK CU8"

- robocopy "C:\Users\Administrator\Documents\Retail SDK CU8" "C:\Users\emmah\Documents\Retail SDK CU8" /E

This new folder is now the place to carry out the changes (the work folder). Note, that in a real development environment, it is advised to use source control solutions like TFS, Git, or others.

Prepare MPOS to be run from Visual Studio from unchanged SDK code

- Open MPOS solution in Visual Studio 2013 (C:\Users\emmah\Documents\Retail SDK CU8\POS Clients\Windows\C1\Pos.sln)

- Change target dropdown to “Simulator”

- Build and run in the debugger with F5

- If you get error about MPOS already being installed, see Issues list at the end of this document. Once solved, hitting F5 in VS should bring up MPOS

- "Device activation" screen should be shown

Activate the MPOS device

Now find out which Channel Database RetailServer is configured to use. In inetmgr, browse to RetailServer, hit "Explore", open the web.config file and inspect the ConnectionString. In my case, it is using “RetailHoustonStore”.

Look up which channel is used (USRT/Retail/Setup/Retail Scheduler/Channel integration/Channel Database):

Look up which registers are available (USRT/Retail/Common/Retail Channels/Retail Stores/Open Houston)

And look up of devices already exist (USRT/Retail/Setup/Devices)

I will be re-using the HOUSTON-3 device that is in pending state. Off course, it is also possible to create a new one.

Find RetailServer url for device activation by looking up inetmgr configuration, find port, etc. For CU8, the RetailServer url on my machine looks like this:


Here I am using the operator with Id 000160 and password 123.

Hitting the “Activate” button should continue to the "Sign in" screen

Carry out a dummy transaction to verify all is good.

Note that the device we chose earlier does now show up as activated in AX:

Now that we have verified all is working, we are ready to extend the code. Stop debugger to quickly stop MPOS without having to log off.

Add a new operation and screen layout button to MPOS

In AX, add a new POS operation (USRT/Retail/Setup/POS/Operations)

In the details for the HOUSTON store, find what the screen layout is (USRT/Retail/Common/Retail Channels/Retail Stores/HOUSTON/Screen Layout). In my case, the screen layout for the "Modern POS for Windows" application type is "FABCSH16:9".

Note: Screen layout may also be assigned to a specific register or cashier. In this example, the whole store uses the same layout.

In AX, add new button to the transaction screen 1 (USRT/Retail/Setup/POS/Screen layouts/ FabMGR16:9/Actions/Designer), name it "Cross Loyalty discount lookup"

Associate the button with the operation (in Designer/right click on button/Button properties)

In AX, run 1090 job (USRT/Retail/Periodic/Data distribution/Distribution schedule/1090/Run now)

In AX, verify that the job succeeded (USRT/Retail/Inquiries/CDX/Download sessions/Process Status message)

Launch MPOS with F5, log back on. You should see the new button in the transaction screen 1

Click the button. It will say "Operation is not supported". Makes sense, as MPOS does not know about the operation or how to handle it…

Customize MPOS source code

Unzip the “Retail SDK CU8 - Extensibility Sample 1.zip” file ontop of you “Retail Sdk CU8” work folder. This will update a few files (for MPOS, and adds the code for the CRT and RetailServer customization).

The main code changes in MPOS are:

- In the Framework folder (generic for any client):

  • New activity to call out to RetailServer
  • New operation and operation handler for the whole UI flow (asking user, calling out to RetailServer, asking user for confirmation, applying total discount).
  • Register the new operation handler
- In the C1 folder (MPOS specific):

  • In CartView.ts, making sure the discount is displayed/refreshed
  • Activity implementation

In Visual Studio, clean the whole solution, then rebuild and test with F5.

Now, hit the "Cross loyalty discount lookup" button again. At this point, you will see that the new MPOS sample code is being used. A new dialog pops asking to enter the loyalty number

If you type a phone number, and hit OK, you will get an error. Why?

The reason is that we have not customized RetailServer yet, and MPOS is making the call to the not yet existing action. You can clearly see by using tools like Fiddler, that the POST request to "http://ax2012r2a.contoso.com:35080/R...altyCardAction" fails with a 404 (Not Found).

Add new CRT service and register it with RetailServer

A CRT service is a small, single task (as opposed to a workflow, which is composed of multiple tasks). To accomplish this simple task, all we need to write a function that takes the loyalty number (phone number) and returns a discount. In a real-world system, that function would call another process, web service or similar to get that information. In this sample code, we will have the value hard coded for a few phone numbers.

We need to implement a request class, a response class and the service (the source code with full VS project is part of the zipped folder)

public sealed class GetCrossLoyaltyCardRequest : Request
/// Gets or sets the loyalty card number
public string LoyaltyCardNumber { get; set; }
} public sealed class GetCrossLoyaltyCardResponse : Response
/// Gets or sets the calculated discount value.
public decimal Discount { get; set; }
} public class GetCrossLoyaltyCardService : IRequestHandler The above code adds a simple new CRT service. Note, that another customization approach is to edit existing functionality that is part of the Retail SDK. However, it is suggested to extend the CRT by adding new code instead of existing. It will help to make a potential upgrade to a future version of the SDK easier (a future blog is planned to show some best practices around how and where to write your Retail customizations).

In order to register a new CRT dll with the host, in this case RetailServer, you must edit the commerceruntime.config file, that is in the binary location of the host. Use inetmgr again to find the binary location of RetailServer as you did earlier.

The Visual Studio projects for both the CRT and RetailServer extensions include 2 MSBuild files that make referencing external files and deploying the target files easier. I highly recommend to use some similar approaches in your own development process (not for production deployment).

The first include file, pre.settings is included at the top of each project. It allows to adjust the RetailServer binary path:

The second include file, post.targets is included at the bottom of each project. It needs to be included into any project that needs to “deploy” the newly built binary into RetailServer’s binary folder:

Note: Since the AfterBuild MSBuild target needs to be able to write to the RetailServer binary folder, Visual Studio has to be started elevated (run as Adminstrator).

Add new RetailServer action and register it with RetailServer

public class ExtendedEdmModelFactory : CommerceModelFactory

/// Builds entity sets.
protected override void BuildActions()
var var1 = CommerceModelFactory.BindEntitySetAction("GetCrossLoyaltyCardAction");
[CommerceAuthorization(AllowedRetailRoles = new string[] { CommerceRoles.Employee }, CheckRetailOperation = false)]
public class NewEntitiesController : CustomersController
public decimal GetCrossLoyaltyCardAction(ODataActionParameters parameters)
CommerceRuntime runtime = CommerceRuntimeManager.Runtime;
GetCrossLoyaltyCardResponse resp = runtime.Execute(new GetCrossLoyaltyCardRequest() { LoyaltyCardNumber = (string)parameters["LoyaltyCardNumber"] }, null);
return resp.Discount;

The above code extends the CustomersController class by adding a new action called GetCrossLoyaltyAction. By doing this, the final Url that MPOS uses is:


It makes sense for this sample to extend the CustomersController. In other cases, you may need to add your own custom controller class.

In order to register a new RetailServer dll, you must edit the Web.config file, that is in the root of the RetailServer web application path. Use inetmgr again to find the location.


Run through MPOS. Add a new item. Hit the new button, enter a made up phone number. See it returning 0. Enter "425-999-3333" and see it returning 3.

In fiddler we can see the request and response with valid values:

Issues and solutions:

If you cannot run MPOS from the Pos.sln file because it is already installed, uninstall the app first. This link may also be helpful: http://blogs.msdn.com/b/wsdevsol/arc...lace-this.aspx



Источник: http://blogs.msdn.com/b/axsa/archive...os-part-1.aspx
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору.