web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics AX (Archived)

Extending the Cart Line in MPOS

(0) ShareShare
ReportReport
Posted on by 312

Hi All,

I am trying to add a field to the Cart Line entity in MPOS using the Extensibility Framework described in following links

http://blogs.msdn.com/b/axsa/archive/2015/02/17/extensibility-in-dynamics-ax-2012-r3-cu8-crt-retailserver-mpos-part-1.aspx

http://blogs.msdn.com/b/axsa/archive/2015/05/20/extensibility-in-dynamics-ax-2012-r3-cu8-crt-retailserver-mpos-part-2-new-data-entity.aspx

 

however the above links talk about Extending the customer entity in which we have a corresponding SQL view.

But AFAIK for the transaction lines there is no corresponding SQL View as the data is stored as a binary field on the CartView. Any ideas how we can achieve the addition of the field?

 

Regards

Hitesh

*This post is locked for comments

I have the same question (0)
  • SergeyP Profile Picture
    2,928 on at

    I assume you are using CTP8. You can leverage CartLine.ExtensionProperties collection to store/retrieve your custom properties but you need to make some changes in CRT (project Runtime.Workflow in the SDK) to get that work. Open file CartWorkflowHelper.cs and:

    1. Line #399 belongs to the method

    public static void PerformSaveCartOperations

    there is a loop over CartLines, add the following code before that line:

    cartLine.LineData.ExtensionProperties = cartLine.ExtensionProperties;


    2. Line #643 belongs to the method

    public static Cart ConvertToCart(RequestContext context, SalesTransaction salesTransaction)


    add the following code before that line:

    cartLine.ExtensionProperties = salesLine.ExtensionProperties;


    3. Line #701  belongs to the method

    public static SalesTransaction ConvertToSalesTransaction(Cart cart)

    add the following code before that line:

    salesLine.ExtensionProperties = cartLine.ExtensionProperties;


    Then compile the project and replace the DLL in Retail Server's directory. Now you should be able to add (on Retail Server Proxy side) your own properties to CartLine.ExtensionProperties collection.

  • Hitesh Manglani Profile Picture
    312 on at

    Hello Sergey,

    Thank you so much for replying, i did try the same however i am able to successfully set the field to the transaction line but on viewing Show Journal the transaction lines do not seem to retain the value. I am assuming that by setting the Extension Property the CRT Framework will do the underlying work of persisting it in SQL. Is that correct or am i missing something?

    Regards

    Hitesh Manglani

  • SergeyP Profile Picture
    2,928 on at

    This was my understanding of your issue:

    You needed to store some custom properties on CartLine level and you need to be able to store/retrieve them while working with Retail Server's Carts API.

    If my understanding is correct then the steps I outlined above will help you achieving your goal, if I misunderstood your question please provide more details why you cannot use that solution.

    The above solution results in those custom properties (added into the collection ExtensionProperties) serialized and stored in SQL and then retrieved and de-serialized on Read Cart operations.

  • Hitesh Manglani Profile Picture
    312 on at

    Hi Sergey,

    Thank you for your answer, can you let me know if i can persist custom properties in the database transactions tables too i.e. i hope to see them in the RetailTransactionSalesTrans table. However on investigating i  find that CRT uses a UDT called  [crt].[RETAILTRANSACTIONSALESTRANSTABLETYPE] for saving the sales line of the transaction and I dont know how i can extend this to include the custom properties.

    Regards

    Hitesh

  • Verified answer
    SergeyP Profile Picture
    2,928 on at

    Sounds like you need to be able to access those custom properties in Sales Order as well. Sales Order consists of number of SQL tables, the table which corresponds to a Sales Line (which is originating from a Cart Line) is RetailTransactionSalesTrans so you need to extend that table by adding a column, let's say CustomString (for this example I will specify its type as  NVARCHAR(50) but you can have any other type. Then you need to customize CRT (see below) to store data corresponding to the Extension Property in that table. Eventually, when CRT reads an order's sales lines it is using SQL View crt.RetailTransactionSalesTransView, therefore that view should also be updated by including into the SELECT statement just added column. Once the View is modified the CRT will automatically include that column into a collection of ExtensionProperties of the SalesLine and finally you will be able to use its value in Retail Server client (POS in your case) the way you want.

    Below are more specific details:

    1. In the Data.Services project find a class SalesTransactionDataService and modify its method

    private static NullResponse SaveSalesTransaction(SaveSalesTransactionDataRequest request)
    

    by adding one more DataTable around line #1412 (here we are instantiating a DataTable which will hold ExtensionProperties values):

    using (DataTable linesExtensionPropertiesTable = new DataTable("RETAILTRANSACTIONPROPERTIESTABLETYPE"))
    


    While in the same method, a little bit further you will see several calls to such functions like PopulateXSchema, so, add there one more line (this is a call to the method which will fill the table with the schema):

    PopulateExtensionPropertiesSchema(linesExtensionPropertiesTable);
    


    While in the same method locate a call to FillOrderLines and add there an additional parameter which corresponds to just created DataTable, so the call would like something like this (note the new parameter linesExtensionPropertiesTable):

     

    FillOrderLines(
      request.SalesTransaction,
      linesTable,
      incomeExpenseTable,
      markupTable,
      taxTable,
      addressTable,
      discountTable,
      reasonCodeTable,
      propertiesTable,
      affiliationsTable,
      invoiceTable,
      customerAccountDepositTable,
      linesExtensionPropertiesTable,
      request.RequestContext);


    Last change in this method, almost at the end of it, will be to insert the following line (this way we will be able to pass newly created DataTable to the layer which works with Sql Server):

    insertTablesRequest.SetProperty("extensionProperties", linesExtensionPropertiesTable);
    

    right before this one:

    request.RequestContext.Runtime.Execute<NullResponse>(insertTablesRequest, request.RequestContext);


    2. While in the same file locate the function

    private static void FillOrderLines
    


    and add an additional argument to it:

    DataTable linesExtensionPropertiesTable
    


    Then, in the same method, find a call to FillItemLine and pass there new parameter linesExtensionPropertiesTable which was just introduced.

    3. Modify the function FillItemLine by adding a new parameter

    DataTable linesExtensionPropertiesTable
    

     

    Then, at the very end of the method add the following call:

    FillExtensionProperties(transaction, salesLine, linesExtensionPropertiesTable, context);
    


    4. While in the same file add couple of new function which were referenced by the changes above:

                private static void PopulateExtensionPropertiesSchema(DataTable table)
                {
                    ThrowIf.Null(table, nameof(table));
                    table.Columns.Add(DataAreaIdColumn, typeof(string)).MaxLength = 4;
                    table.Columns.Add(StoreColumn, typeof(string)).MaxLength = 10;
                    table.Columns.Add(TerminalIdColumn, typeof(string)).MaxLength = 10;
                    table.Columns.Add(TransactionIdColumn, typeof(string)).MaxLength = 44;
                    table.Columns.Add(SaleLineNumColumn, typeof(decimal));
                    table.Columns.Add(NameColumn, typeof(string)).MaxLength = 32;
                    table.Columns.Add(ValueColumn, typeof(string));
                }
    
    
                private static void FillExtensionProperties(SalesTransaction transaction, SalesLine salesLine, DataTable propertiesTable, RequestContext context)
                {
                    ThrowIf.Null(transaction, nameof(transaction));
                    ThrowIf.Null(salesLine, nameof(salesLine));
                    ThrowIf.Null(propertiesTable, nameof(propertiesTable));
    
                    ChannelConfiguration channelConfiguration = context.GetChannelConfiguration();
    
                    foreach (CommerceProperty commerceProperty in salesLine.ExtensionProperties)
                    {
                        DataRow row = propertiesTable.NewRow();
    
                        SetField(row, DataAreaIdColumn, channelConfiguration.InventLocationDataAreaId);
                        SetField(row, StoreColumn, transaction.StoreId ?? string.Empty);
                        SetField(row, TerminalIdColumn, transaction.TerminalId ?? string.Empty);
                        SetField(row, TransactionIdColumn, transaction.Id);
                        SetField(row, SaleLineNumColumn, salesLine.LineNumber);
                        SetField(row, NameColumn, commerceProperty.Key);
                        SetField(row, ValueColumn, commerceProperty.Value.GetPropertyValue());
                        propertiesTable.Rows.Add(row);
                    }
                }
    


    This completes changes to the file SalesTransactionDataService.cs.

    5. Find the file SalesTransactionSqlServerDataService.cs in the project Data.Services.SqlServer, it cntains the function

    private static NullResponse InsertSalesTransactionTables(InsertSalesTransactionTablesDataRequest request)
    


    which contains, at the very beginning, several similar lines where parameters are set, add there one more line:

    parameters["@tvp_LinesExtensionProperties"] = request.GetProperty("extensionProperties");
    


    This completes C# changes, what we have so far: we have modified a code so it now provides Extension Properties's values to the DB layer so in next steps we will need to modify couple of Stored Procs to leverage the new parameter added above.

    6. Modify Stored Procedure crt.InsertSalesOrder by adding one more parameter:

    @TVP_LINESEXTENSIONPROPERTIES       [crt].[RETAILTRANSACTIONPROPERTIESTABLETYPE] READONLY


    While in the same Stored Procedure, find a call to the Stored Procedure crt.InsertSalesTrans and add one more parameter to that call - @TVP_LINESEXTENSIONPROPERTIES

    7. Modify Stored Procedure crt.InsertSalesTrans by adding new parameter there (the same parameter you added to the Stored Procedure above):

    @TVP_LINESEXTENSIONPROPERTIES [crt].[RETAILTRANSACTIONPROPERTIESTABLETYPE] READONLY
    


    This is basically it - we have passed the extension properties all the way down to the stored proc where it should be saved and now you need to update the SQL in the way which is the best for your specific needs (depends whether you have one custom property or more of them and whether al o them of the same type or not and so on), as a sample I am providing the following code which assumes that you have just 1 (per sales line) Extension Property which will be stored I the column CustomString NVARCHAR, but, gain, you should modify the SQL the way it fits your needs:

    UPDATE [ax].RETAILTRANSACTIONSALESTRANS 
    	SET CustomString = properties.VALUE
    	FROM [ax].RETAILTRANSACTIONSALESTRANS lines
    	JOIN @TVP_LINESEXTENSIONPROPERTIES AS properties ON properties.TRANSACTIONID = lines.TRANSACTIONID
    	 AND properties.SALELINENUM = lines.LINENUM
    	 AND properties.DATAAREAID = lines.DATAAREAID
    	 AND lines.CHANNEL = @bi_ChannelId
    
    	SELECT @i_Error = @@ERROR;
        IF @i_Error <> 0
        BEGIN
            SET @i_ReturnCode = @i_Error;
            GOTO exit_label;
        END;
    

  • Hitesh Manglani Profile Picture
    312 on at

    Thanks a lot Sergey, that works like a charm!!!

  • Suspended Transaction Profile Picture
    25 on at

    Hi Sergey,

    Thank you for your useful reply but i just want to confirm that if we need to add custom property in CartLine to save and retrieve from database than we only need to write the above piece of code that u mentioned? that' it? and changing in view is required any other part that is missing than please let me know.

    Thanks

  • SergeyP Profile Picture
    2,928 on at

    In this thread I made 2 posts containing code changes:

    a) the first one shows how to store/retrieve custom properties in Cart's (not an Order) CartLine only.

    b) the second one shows how to store/retrieve custom properties (which were added to a Cart's CartLine) in an Order's Sales Lines

    Depending on what you need you should apply (a) ONLY or (a) AND (b).

  • Suspended Transaction Profile Picture
    25 on at

    ok great, thanks Sergey. 

  • Community Member Profile Picture
    on at

    Hi,

    I'm trying to do this in CU9.  Can't find the class that you mention.  Can this be done in CU9?

    Regards,

    Miguel

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics AX (Archived)

#1
Martin Dráb Profile Picture

Martin Dráb 4 Most Valuable Professional

#1
Priya_K Profile Picture

Priya_K 4

#3
MyDynamicsNAV Profile Picture

MyDynamicsNAV 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans