Dealing correctly with the cart-to-order process

Vote:
 

Hi

I have a case right now where the call to _orderRepository.SaveAsPurchaseOrder() has succeeded, but where a call to _orderRepository.Save() later has failed, leaving me with an order that is missing important information, including billing info.

The checkout process so far has been to convert the cart into a purchase order first, and then adding the relevant order information afterwards, finishing off with a Save(). Since this is clearly not a safe approach, I thought I'd try doing it the other way, where I'd set all the important information on the cart first, and then convert the cart to an order as the last step. For a lot of the information, this worked okay, but certain things did not get copied over, such as values in the Properties and the Notes properties.

Since that didn't work either, I want to ask: Is there some way to ensure that I either atomically create a complete order or fail entirely without leaving half-completed orders behind?

#187456
Jan 23, 2018 14:02
Vote:
 

" where a call to _orderRepository.Save() later has failed"

What did you do to the order after "SaveAsPurchaseOrder", and what failed?

#187457
Jan 23, 2018 14:26
Vote:
 

Quan,

What gets done to the order after SaveAsPurchaseOrder is

  1. The order's OrderNumber is modified so that the PO prefix is replaced with R.
  2. A shipment is created and added, with a ShippingMethodId
  3. A payment is created and added, with BillingAddress and CustomerName
  4. An order note is added
  5. Several custom Properties are set
  6. _orderRepository.Save()

Unfortunately, I do not know what went wrong, because the log has nothing useful in it. But something clearly went wrong between the two save events, which I can tell because the orders are PO-orders, not R-orders, and they are missing all the expected information added in steps 2-5.

It does't matter all that much to me what exactly went wrong, I'm mostly concerned with how to deal with the situation where it does go wrong. Having this operation be atomic, for instance, where either everything succeeds or nothing succeeds, would be perfect.

#187461
Edited, Jan 23, 2018 15:11
Vote:
 

A few lines code would help here :). Your idea sounds about right, but we need to look into the code. 

#187462
Jan 23, 2018 15:15
Vote:
 

Only way I know is to catch the exception and attempt to cancel the order and restore the cart.

A way to convert an ICart to an IPurchaseOrder in memory without saving it to the database would enable a better handling if the use cases allow it. (If the client demands that all orders should have an unbroken serie of tracking numbers it won't help. :P)

#187467
Jan 23, 2018 17:04
Vote:
 

Quan,

I don't think there's anything especially relevant about the code. It does exactly what I explained; there's nothing particularly unusual about it. It doesn't fail much either. I'd say it works just fine in over 99.99% of cases.

But I think it's unfortunate that it can go wrong. I was just asking for/hoping for there being a way to make the whole operation atomic. That's all. I guess the takeaway is that it's not possible, at least not at the moment.

I saw that the Cart.SaveAsPurchaseOrder() method (decompiled) does its work inside a TransactionScope. It would be really nice if we could be allowed to do our additional order actions within that TransactionScope through a callback or similar.

#187474
Jan 24, 2018 8:38
Vote:
 

I'm not sure I fully understand the problem, but it does sound like you can wrap the entire operation in a big TransactionScope. Either everything succeeds, or they will revert back (except for the payments which might need some extra operations) 

#187503
Jan 24, 2018 17:06
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.