PostEndTransactionTrigger – The trigger that may not trigger.

So here is an interesting tidbit from a recent incident in which I was supporting the customer on Dynamics 365 for Operations – Retail.

Few transactions were suddenly reported as “Missing”  by the customer. The customer provided transaction details including CCTV grab along with Credit Card Slip. I started my investigation the server logs and found that the transaction id seemed be used across two transactions. This meant that the cart was not got getting cleared. In my customization I needed to access the cart information post the cart checkout and my cart clearing code was written in the PostEndTransactionTrigger.

We also logged a support ticket with MS and over time understood from MS that the MPOS is being exited by the cashier without closing the Change Due Dialog, which resulted in the PostEndTransactionTrigger not executing.

Long story short, if you are using this Trigger, make sure it contains non -critical code as it may not trigger if user exits MPOS without closing the above change due dialog. 

This article is based on 7.1 Retail SDK but should be applicable to later releases too unless a fix for this has been released.

Hope this helps

-Hitesh Manglani

 

 

 

Debugging Cloud POS on Microsoft hosted VM with no admin rights

If you are on a MSDyn365FO 8.1 Microsoft hosted VM, you won’t have admin rights. In this case when you open the Cloud POS solution from the Retail SDK itself you get an error.

The error occurs as you do not have rights on IIS unless you run Visual Studio with Admin rights

Cloud POS Solution Error

So to get around this issue, follow the article below to resolve the issue.

https://docs.microsoft.com/en-gb/dynamics365/unified-operations/retail/dev-itpro/cloud-dev-box

Note –  For step 2 you will find the aspnet.config and redirection.config files in C:\Program Files\IIS Express\config\templates\PersonalWebServer

Following the steps will make sure your Cloud POS runs on IISExpress instead of IIS and thus allowing you to to run Cloud POS and debug by attaching to iisexpress.exe.

 

-Hitesh Manglani

(Special thanks to my mentor Mugunthan Mani from Microsoft for this tip )

RetailCdxSeedData class – Create custom tables mapping in Retail scheduler automatically

In this post, I would like to draw your attention to RetailCdxSeedData class.

The RetailCdxSeedData class is called when you trigger the following option in Dynamics 365 for Operations

Retail and commerce->Headquarters setup -> Retail scheduler ->Initialise retail scheduler 

If you have added some custom tables that need to be synced  between your HQ and Channel Database using CDX (Commerce Data eXchange), then you should customize the RetailCdxSeedData class to include the custom tables. If you do not not customize the RetailCdxSeedData class, you will need to do the CDX table mapping manually in all the environments and in every DB refresh and increasing the chances of missing out some fields if you have a lot of tables.

Please refer the following link from Microsoft on how you can customise this class with an extension.

https://docs.microsoft.com/en-us/dynamics365/unified-operations/retail/dev-itpro/cdx-extensibility

Hope this helps

– Hitesh Manglani

 

[MPOS Technical Development]- Refactoring/Renaming of a CRT Entity in Extensions

If you decide to refactor or rename a Commerce Runtime (CRT) entity (lets say OldEntityName to NewEntityName) inheriting from CommerceEntity, one issue that I have faced is in Retail Server extension assembly the build fails with errors due to the RetailProxy classes relying on the definition of your old entity name.

Example of the error messages that you would see in this scenario are as follows-

Could not load type OldEntityName from assembly… and the command ‘bin\CommerceProxyGenerator.exe’ ..

Retail Proxy Error

The solution to this issue is a little tricky one. You need to compile the CRT data dlls keeping the OldEntityName in the References folder.

You need to then comment any reference to NewEntityName in the Retail Server Extension assembly. Then do a clean and a build of the solution.

If this succeeds with no errors, you can now go ahead to uncomment all references to NewEntityName in the Retail Server Extension assembly.

<Update>This article is based on 7.1 Retail SDK </Update>

-Hitesh Manglani

 

 

 

 

 

Custom error messages in MPOS

This post is for describing how we can show custom error messages in MPOS.

MPOS standard error handlers require that the strings to be shown as error messages are entered in the following format within the resources.json file (en-US).

“string_55001” : “This is a custom error.”,

Within MPOS we could use the following snippet to display any custom error messages

let displayMessageActivity: Commerce.Activities.DisplayMessageActivity = new Commerce.Activities.DisplayMessageActivity({
title: ‘Custom Error’,
message: Commerce.ViewModelAdapter.getResourceString(“string_55001“)
});
displayMessageActivity.execute().done(() => {
// code to run on successful display of the error dialog
}).fail(() => {
// code to run on failure in displaying the error dialog
});

If however the error condition is met in the Commerce Run Time (CRT) you need to show the error message in MPOS, you can leverage the CommerceRunTimeException

throw new CommerceException(“string_55047”, “CUSTOM ERROR MESSAGE”);

 

One possibility is that the error messages could be coming from a third party application. On a recent integration I received a list of predefined error codes with error messages from the application.I then defined an enum in the CRT which had the values as this status codes and names as the error messages

e.g.

INVALID_OPTION = 152

ERROR_NEW_PASSWORD_CANNOT_BE_THE_SAME_AS_OLD_PASSWORD = 180

I defined a corresponding Enum in the CRT

public enum AppError
{

INVALID_OPTION = 152

ERROR_NEW_PASSWORD_CANNOT_BE_THE_SAME_AS_OLD_PASSWORD = 180

}

After deserializing the response I checked the ReturnStatus code from the application and used an offset (50050) to throw the correct error message from the resources.json file

if (Enum.IsDefined(typeof(AppError), res.ReturnStatus))
{
AppError err = (AppError)res.ReturnStatus;
throw new CommerceException(“string_” + (50050 + res.ReturnStatus) , err.ToString().Replace(“_”, ” “));
}

<Update>One thing you need to be aware is that the Error Status Code and Error Messages returned by the application should be constant. Any changes would mean that the MPOS package will need to be regenerated and redeployed.

I got following suggestion from my Mentor Mani (from Microsoft) for displaying the custom error messages- you can set custom properties in the response (CRT) and then parse the response in MPOS and show your message, you can also use extension properties and then parse it in MPOS. With this approach no need to define the error messages in resources.json.

</Update>

Hope this helps

-Hitesh Manglani

 

 

 

 

 

 

 

 

MPOS, Retail Server – JSON API Integration

Recently I had to work on developing an integration between MPOS and a CRM application via Retail Server/CRT. The REST APIs provided where JSON based and I needed C# classes to deserialize the response.

My gut feel said that there should be a tool to do this and I need not create the required classes and properties manually.

Sure enough after some web search, I found https://jsonutils.com/

This is an awesome site where you can provide a sample JSON API response and get the C# classes that can be used to deserialize the JSON.

Hope this helps  you save some time, just as it helped me.

-Hitesh Manglani

Export X++ and Binary Hotfixes description from LCS

As it stands, I have spent quite some time painfully extracting X++ and Binary hotfixes description one at a time from LCS preparing release notes for my clients. This is because there is no feature in LCS (yet) which can allow export of this information.

If you are in the same boat, and you need to prepare release notes urgently, here is a tool by Tomek Melissa that you must try. Please note that its not a Microsoft supported release so you need to try it at your own risk.

https://github.com/Microsoft/2LCS/releases

 

PS: I have tried it and it works like a charm! Its not limited to just what I mentioned in this post.

-Hitesh Manglani