Skip to main content

Notifications

Announcements

No record found.

Dynamics 365 Community / Forums / Commerce forum / BeforeCreatingRetailOr...
Commerce forum
Answered

BeforeCreatingRetailOrderLines delegate on RetailTransactionServiceOrders explanation on update needed urgently

Posted on by 1,423

I'm logging this question under the Finance forum because it is X++ code and I will get faster an answer here than on the Retail forum.

I just want to know how the class works because it is not updating when I expected it to update.

The POS orders are created in Finance using the class RetailTransactionServiceOrders.createCustomerOrderNew().

It works weird for me in that it populates a map and it jumps between the map RetailOrderHeaderMap and the actual table: SalesTable.

We have custom in D365 where we assign a payment term to the delivery mode record in some cases. The customer has a delivery mode and it is defaulted to the salesTable on creation. It's the same for the POS order. I have to apply this custom to the POS order too when it is created in D365 via the backend process.  I have changed successfully the payment term on the mapping to the payment term on the delivery mode if there was one assigned to the delivery mode record. So this part of my custom works.

In RetailTransactionServiceOrders::createOrUpdateRetailOrderHeader you will see it has a call to RetailCreateCustomerOrderExtensions::orderHeaderBeforeInsert(args); It is in here where I added my custom to replace the payment term to what is on the delivery mode instead of it taking it from the customer. This part works.

 /* 

public static void orderHeaderBeforeInsert(RetailCustomerOrderHeaderParameters args)
{
// CoC
next orderHeaderBeforeInsert(args);

boolean vCreateNew = args.createNew;
RetailOrderHeaderMap orderHeader = args.orderHeader as RetailOrderHeaderMap;

if(vCreateNew)
{
TMC_OrderTOP top = DlvMode::TMC_GetOrderPaymentTerm(orderHeader.DlvMode);
if(top)
{
orderHeader.getTableInInstanceHierarchy(tableNum(SalesTable)).setFieldValue("Payment", top);
}
}
}

*/

The part that I can't get to work is that I now need to add  a validation  that if the payment term differs from the customer payment term, then I need to set a custom flag flag that indicates that the order is on hold and I have to create an entry in the MCRHoldCodeTrans table. The link is the InventRefId = salesTable.SalesId. My custom fields are only on Salestable, not the RetailOrderHeaderMap. Because the custom was added to D365 a while ago.

Inside the method createCustomerOrderNew, directly after the call to RetailTransactionServiceOrders::createOrUpdateRetailOrderHeader, is a call to a delegate: RetailTransactionServiceOrders::beforeCreatingRetailOrderLines(salesTable, custOrderInfo);.

If one right-click on that delegate and choose: Copy event handler method, it creates the signature as follow:

"

[SubscribesTo(classStr(RetailTransactionServiceOrders), staticDelegateStr(RetailTransactionServiceOrders, beforeCreatingRetailOrderLines))]
public static void RetailTransactionServiceOrders_beforeCreatingRetailOrderLines(SalesTable _salesTable, Microsoft.Dynamics.Commerce.Runtime.Services.CustomerOrder.CustomerOrderInfo _customerOrderInfo)
"

I'm assuming I can just use the _salesTable, run my validation and then update the custom fields on it and also create the MCRHoldCodeTrans record when applicable.

However after the order is created, I can go to All Sales Orders and find my order and the status is not set when it is supposed to be set and there is no MCRHoldCodeTrans record created. It is as if it is not running the code in the delegate. However the payment term on the order has the correct one from the delivery mode.

If you look in createCustomerOrderNew, you will see it has a ttsbegin.

Then it runs RetailTransactionServiceOrders::createOrUpdateRetailOrderHeader and RetailTransactionServiceOrders::beforeCreatingRetailOrderLines and a bunch of other code and at the end it has either a ttsabort or a ttscommit,  depending on what happens in between.

So for my custom in the delegate, do I just update the custom fields on _salesTable or do I include a _salestable.update()?

I did it without the update and with the  update, with the same results. It's not updating _salestable.

Maybe _salestable is not in a SelectForUpdate state maybe ?

Or do I need to switch back to RetailOrderheaderMap and update that instead? Which means I have to add my custom fields to the map too. Then how to I update the MCRHoldcodeTrans record then if the delegate doesn't work.

My code:

/* ******

[SubscribesTo(classStr(RetailTransactionServiceOrders), staticDelegateStr(RetailTransactionServiceOrders, beforeCreatingRetailOrderLines))]
public static void RetailTransactionServiceOrders_beforeCreatingRetailOrderLines(SalesTable _salesTable, Microsoft.Dynamics.Commerce.Runtime.Services.CustomerOrder.CustomerOrderInfo _customerOrderInfo)
{
TMC_ManageInvoiceInCCProcess manageInvoiceInCCProcess = new TMC_ManageInvoiceInCCProcess();

// if the mode of delivery changes the term payment, then put the order on hold
boolean vOK = manageInvoiceInCCProcess.runCCPaymentTermCheck(_salestable);
TMC_CreditCheckEnums vStatus;

if(!vOK)
{
vStatus = TMC_CreditCheckEnums::Fail;
TMC_ManageInvoiceInCCProcess::mcrPutOrderOnHold(_salesTable.SalesId, "Term", strFmt("@TMC:TMC149"));
}
else
{
vStatus = TMC_CreditCheckEnums::Pass;
}
_salesTable.TMC_CreditCheckDate = DateTimeUtil::getToday(DateTimeUtil::getUserPreferredTimeZone());
_salesTable.TMC_CreditCheckStatus = vStatus;
_salesTable.update();
}
}

***** */

Ay help will be much appreciated in understanding this class and the jumping between OrderHeaderMap and SalesTable and which one am I supposed to update to update my custom fields.

I need to get this to work ASAP.

  • Retha Profile Picture
    Retha 1,423 on at
    RE: BeforeCreatingRetailOrderLines delegate on RetailTransactionServiceOrders explanation on update needed urgently

    Hi Guanghui

    I moved the code to RetailCreateCustomerOrderExtensions::orderHeaderBeforeInsert and it worked.

    But because I also have to add an MCROrderHoldTrans record which MCROrderHoldTrans.insert() has business logic to update SalesTable, we have decided to leave this custom out of the POS orders for now.  The only way to bypass the business logic is to use doInsert() which is not a good idea most of the time.

  • Suggested answer
    Guanghui Profile Picture
    Guanghui on at
    RE: BeforeCreatingRetailOrderLines delegate on RetailTransactionServiceOrders explanation on update needed urgently

    Hi,

    I have not tested the code, but could you please try this code in   RetailCreateCustomerOrderExtensions::orderHeaderBeforeInsert(args)

     SalesTable salesTable = orderHeader;

     salesTable.TMC_CreditCheckDate = DateTimeUtil::getToday(DateTimeUtil::getUserPreferredTimeZone());

     salesTable.TMC_CreditCheckStatus = vStatus;

    Please don't call salesTable.update() because I think it will cause update conflict issue

  • André Arnaud de Calavon Profile Picture
    André Arnaud de Cal... 287,995 Super User on at
    RE: BeforeCreatingRetailOrderLines delegate on RetailTransactionServiceOrders explanation on update needed urgently

    Moved to the Dynamics 365 Commerce forum.

Helpful resources

Quick Links

Replay now available! Dynamics 365 Community Call (CRM Edition)

Catch up on the first D365 Community Call held on 7/10

Community Spotlight of the Month

Kudos to Saurav Dhyani!

Congratulations to the June Top 10 community leaders!

These stars go above and beyond . . .

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 287,995 Super User

#2
Martin Dráb Profile Picture

Martin Dráb 225,610 Super User

#3
nmaenpaa Profile Picture

nmaenpaa 101,148

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans