Microsoft Dynamics 365 Blog

One of the easiest and fastest ways to extend the AX for Retail POS is by using the Blank Operation.  Blank Operations can be assigned to buttons in your Retail POS till layout – and you can deploy as many of them as you wish, which makes using them very flexible.  Certain aspects of the the BlankOperations plug-in may a bit of a mystery, so here are a few tips to get you started.

[Note:  The Blank Operation has not changed from AX for Retail 2009 and AX for Retail 2012, so this article pertains to both versions.]

Creating the Blank Operation button in POS

The Till Layout designer is a good place to start understanding how the BlankOperations plug-in works.  In a production environment you would do this in the Dynamics AX client (Retail Headquarters > Setup > POS > Retail POS > Till layout), but for quick testing, you can modify buttons directly in the POS.  Just remember that your changes will be overwritten the next time you run the N-1090 job.

If you are using the sample layout, launch POS and go to the Tasks menu.  Right-click on an empty button and select Button Properties.  In the resulting window, select Blank Operation as the Action Item:


After you select Blank Operation, you will see that two new fields are added to the window:  Operation Number and Blank Operation Param.  These two fields are used to make each instance of a Blank Operation button unique and they are the key for how the the POS communicates to the BlankOperations plug-in.  Both of these fields are simple string fields; you don’t have to actually send in a number for the Operation number.

Developing the BlankOperations Plug-in

When you first open the BlankOperations.cs file, you’ll see that it is a very simple class:  just a constructor and one method.  Here is the starting code for the method (I removed some of the code):

       public void BlankOperation(ref BlankOperationInfo operationInfo, ref PosTransaction posTransaction)

StringBuilder comment = new StringBuilder(128);
comment.AppendFormat(ApplicationLocalizer.Language.Translate(50700), operationInfo.OperationId);
comment.AppendFormat(ApplicationLocalizer.Language.Translate(50701), operationInfo.Parameter);
using (LSRetailPosis.POSProcesses.frmMessage dialog = new LSRetailPosis.POSProcesses.frmMessage(comment.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error))

By default, all this code does is open a message box with the two strings that were passed from the POS.  For instance, if I passed in “Hello” and “World”, this is what would appear when the button was pressed:


As you can see by the BlankOperation() method, you have two parameters available to you:  a BlankOperationInfo variable and a PosTransaction variable.

If you examine the BlankOperationInfo datatype, you’ll see that there are two main properties, both string values:  operationID and parameter.  These match up with the two values passed from the button.  In addition, there are a few other values that get passed from the POS, including the currently selected item line and payment line.

Also of great interest is the POSTransaction parameter.  This is a substantial object which represents everything to do with the current transaction:  all of the items, including price, discount, and tax; all of the payments that have been made so far; any customer information; etc.  Explaining the POSTransaction is beyond the scope of this article, but if you set a breakpoint at the start of the BlankOperation() method, you can examine the properties of the POSTransaction object and get an idea of the information available to you.  Hopefully the examples I provide will help you get started.

The key to making a multi-purposed BlankOperations plug-in is to separate your code based on the Operation Number passed in.  This can be done with a simple Case statement on the operationInfo.OperationId value:

            switch (operationInfo.OperationId)

                case “GetLoyaltyStatus”:
//add code here to echo current Loyalty balance for customer
case “Price”:
// add % amount to the last item added
case “Bing”:
//open an Internet Explorer window with results of a bing search
case “Image”:
//open a window with an image for the item
//default, just echo the operation number and parameter value

If you download the project attached to this article, I have included code for each of these operations.

After deciding which block of code needs to be executed, you have at your disposal two main pieces of information:  the POSTransaction parameter mentioned earlier, and the operationInfo.Parameter value, which is the string passed in from the second box on the button. 

In the “Price” example, you might want a separate button for +10%, +20%, +30%, etc.  You would set up three buttons passing in “10”, “20”, “30”.  Your code would then be responsible for using the value passed in (and from converting from a string to a numeric value).  If you need to get more complicated, you could pass in multiple values, delimiting them accordingly.  If you need to add 20% to all yellow items in the transaction, you could pass in “20;yellow”.  Your code would simply break apart the two values that it needs.

Tips for the BlankOperations Plug-in:

The attached project will show you some fun stuff that you can do with the Blank Operation.  All of the operations were done as proof-of-concept so they would definitely need to be cleaned up before using them.  A few other notes:

  • Make sure to use plenty of try/catch blocks in your code and do lots of type-checking.  You don’t know what will be passed in from the button, and there or infinite combinations of what will be in the POSTransaction object.  Don’t make any assumptions on what you will get.


  • You’ll notice that the POSTransaction is also declared as a “ref” parameter. This means you have full read-write access to all values in the transaction! While this means you have incredible flexibility, you can also get into trouble if you’re not careful.


  • There is only one BlankOperations plug-in available.  This means that all of your code has to be shared into one single DLL.  Since multiple developers (and possibly other organizations!) can be developing functionality for this plug-in, you will want to modularize your code as much as possible and just put in calling stubs from the BlankOperations() method.


  • There are two additional files in the BlankOperations project:  SupportClasses\LogOff.cs and SupportClasses\ItemSale.cs.  The latter can be used to programmatically add items to the transaction.  There are two bugs in these support classes which I will address in another article.

Hopefully this will get you started down the road of adding functionality to your POS implementation.  Please use the comments below to share any ideas you have for the BlankOperations plug-in or any issues you may have run into.

We're always looking for feedback and would like to hear from you. Please head to the Dynamics 365 Community to start a discussion, ask questions, and tell us what you think!