Hi,
I created this test with Mspec, and it ran successfully:
public class Test : IntegrationTest { protected static ICart _cart; Establish context = () => { SaveCart(); _cart = SaveCart(); }; private static ICart GetCart() { var customer = Guid.Parse("CD8A9CCB-8550-4E4B-AC5F-5262E7B89491"); return OrderRepository.LoadOrCreateCart<ICart>(customer, "DefaultName"); } private static ICart SaveCart() { var cart = GetCart(); string code = "New-test-variant_1"; var lineItem = cart.CreateLineItem(code); lineItem.Quantity = 1; lineItem.PlacedPrice = 100; cart.AddLineItem(lineItem); var cartLink = OrderRepository.Save(cart); return OrderRepository.Load<ICart>(cartLink.OrderGroupId); } It Should_save_the_cart_successfully = () => _cart.ShouldNotBeNull(); }
Is this the same code which throws exception for you?
Yes, (depending on what is OrderRepository in your code). In mine it is injected IOrderRepository, suppose it's the same.
The code goes through ok first time, and cart is saved and that LineItem is in it when I look for it in Manager. Then on next call it raises exception about InStockQuantity being null.
Only additional thing I managed to notice is that on the first run of the snippet, the line item is of a type Mediachase.Commerce.Orders.LineItem (when Cart is inspected just before the save). After first Save is executed, that line item becomes EPiServer.Commerce.Order.Internal.InMemoryLineItem.
Just before second Save this is returned by GetAllLineItems()
+ [0] {EPiServer.Commerce.Order.Internal.InMemoryLineItem} EPiServer.Commerce.Order.ILineItem {EPiServer.Commerce.Order.Internal.InMemoryLineItem}
+ [1] {Mediachase.Commerce.Orders.LineItem} EPiServer.Commerce.Order.ILineItem {Mediachase.Commerce.Orders.LineItem}
The InMemoryLine item doesn not carry InStockQuantity with it, so it breaks with constrained not-NULL value when cart is Saved second time.
- [0] {EPiServer.Commerce.Order.Internal.InMemoryLineItem} EPiServer.Commerce.Order.ILineItem {EPiServer.Commerce.Order.Internal.InMemoryLineItem} Code "New-test-variant_1" string DisplayName "New test variant" string InventoryTrackingStatus Disabled Mediachase.Commerce.Inventory.InventoryTrackingStatus IsGift false bool IsInventoryAllocated false bool LineItemDiscountAmount 0.00 decimal LineItemId 11071 int OrderLevelDiscountAmount 0.000000000 decimal PlacedPrice 100.000000000 decimal + Properties Count = 7 System.Collections.Hashtable Quantity 1 decimal ReturnQuantity 0 decimal + Non-Public members
Just for sake of reference, the one that was added in second run is like this
- [1] {Mediachase.Commerce.Orders.LineItem} EPiServer.Commerce.Order.ILineItem {Mediachase.Commerce.Orders.LineItem} AllowBackordersAndPreorders false bool BackorderQuantity 0 decimal Catalog "" string CatalogEntryId "New-test-variant_1" string CatalogNode "" string Code "New-test-variant_1" string ConfigurationId "" string + ConnectionHandler {EPiServer.ServiceLocation.Injected<Mediachase.Data.Provider.IConnectionStringHandler>} EPiServer.ServiceLocation.Injected<Mediachase.Data.Provider.IConnectionStringHandler> + Created {29.01.2017 21.30.48} System.DateTime CreatorId null string Description "" string DisableSync false bool + Discounts {Mediachase.Commerce.Orders.LineItemDiscountCollection} Mediachase.Commerce.Orders.LineItemDiscountCollection DisplayName "" string ExtendedPrice 0 decimal + FieldStorage Count = 7 System.Collections.Hashtable {Mediachase.MetaDataPlus.ObservableHashtable} Id -7 int InStockQuantity 0 decimal InventoryStatus 0 int IsGift false bool IsInventoryAllocated false bool + ItemArray {object[7]} object[] + LineItemCalculator {EPiServer.ServiceLocation.Injected<EPiServer.Commerce.Order.ILineItemCalculator>} EPiServer.ServiceLocation.Injected<EPiServer.Commerce.Order.ILineItemCalculator> LineItemDiscountAmount 0 decimal LineItemId -7 int + LineItemOrdering {29.01.2017 21.30.48} System.DateTime ListPrice 0 decimal MaxQuantity 100 decimal + MetaClass {Mediachase.MetaDataPlus.Configurator.MetaClass} Mediachase.MetaDataPlus.Configurator.MetaClass MinQuantity 1 decimal + Modified {29.01.2017 21.30.48} System.DateTime ModifierId null string ObjectState Added Mediachase.MetaDataPlus.MetaObjectState OldQuantity 0 decimal OrderFormId 0 int OrderGroupId 0 int OrderLevelDiscountAmount 0 decimal OrigLineItemId null int? + Parent {Mediachase.Commerce.Orders.OrderForm} Mediachase.Commerce.Orders.OrderForm ParentCatalogEntryId "" string PlacedPrice 100 decimal PreorderQuantity 0 decimal ProviderId "" string Quantity 1 decimal ReturnQuantity 0 decimal ReturnReason "" string ShippingAddressId "" string + ShippingMethodId {00000000-0000-0000-0000-000000000000} System.Guid ShippingMethodName "" string Status "" string + SystemFieldStorage Count = 34 System.Collections.Hashtable WarehouseCode "" string + Static members + Non-Public members
Obviously InStockQuantity is 0 (which is correct for test SKU) which is not NULL.
I can confirm that in QuickSilver 10.2.3. this saving and then saving updated cart works. I have some problem obviously, but am wondering where to start looking for solution to, bcs upgrade process didn't raise any errors. Hm.
Comparing to QuickSilver shows that it works with Seriazable cart, adding SeriazableLineItem, that contains full set of properties including InStockQuantity. So this InMemoryLineItem is pretty suspicious, but I don't know where did that come from.
To isolate the issue I have created a TestController that I call manually:
public ActionResult Index() { var cart = LoadOrCreateCart(Mediachase.Commerce.Orders.Cart.DefaultName); var lineItem1 = cart.CreateLineItem("test-sku123"); lineItem1.Quantity = 1; lineItem1.PlacedPrice = 100; cart.AddLineItem(lineItem1); _orderRepository.Save(cart); var content = new ContentResult { Content = string.Format("<h1>Nr of items in cart: {0}</h1>", cart.GetAllLineItems().Count()) }; return content; } private ICart LoadOrCreateCart(string name) { var customer = Guid.Parse("BD7F334C-2D8A-4836-BB7F-2D3302216D20"); var cart = _orderRepository.LoadOrCreateCart<ICart>(customer, name, _currentMarket); return cart; }
I was unable to reproduce this problem on 10.2.3 (QS), with old or new cart system.
Nr of items in cart: 6
Is there anything special about test-sku123?
No, it's a clean Variation without any properties.
If I turn on SQL Profiler I can see that on 2nd add it calls stored procedure "ecf_LineItem_Update" with @InStockQuantity=NULL. Do you have any idea what could be causing this?
I originally thought it was a database issue, but since I can reproduce it in a fresh db it has to be somthing in the solution.
And: If I run the same code using the old api, it works with no errors. Here is the code:
var custmerGuid = Guid.Parse("9A9510FB-8E32-43BB-BC14-6C13B6A47BDC"); Cart cart = OrderContext.Current.GetCart(Cart.DefaultName, custmerGuid); //Get first orderform or create on if no exists var orderForm = GetOrderForm(cart); var lineItem = new LineItem { Code = "test-sku123", Quantity = 1 }; orderForm.LineItems.Add(lineItem); //now save the changes to the database cart.AcceptChanges();
SKU type doesn't play a role in reproducing the bug. I have just put "ninja" (that doesn't even exist as object) for the Code and saved the cart (first time). Cart is visible in Manager.
When cart is updated and Save called again, same SQL exception breaks with InStockQuantity NULL message.
So the very sku type is not causing it. It breaks the same for variants that work CartHelper (before and after upgrade), test sku that is an empty type (like on beginning of this thread), or just putting any string for code (bcs validation is not called).
Can you zip the project (I assume you can produce it on Quicksilver) and send it to me directly via email.
I suspect this is an urgent matter and we are willing to help - but we need to reproduct the problem first.
Regards,
/Q
I meant "reproduce" - can you replace one of the controller in Quicksilver with your code to see if it happens?
We cannot reproduce this on QuickSilver (as stated in the original post).
OK I missed that. As I can't reproduce this issue, the usual response - contact our developer support service. When we have a bug report we will act on it ASAP.
Hi @Mari,
I just guess your issue when you post "it's a clean Variation without any properties" and code, the reason causes this should related to inventory service.
Not sure but when creating a variation - for testing - we need to add an inventory record for that variation. If not, it might be removed when adding to cart.
Hope this help.
/Son Do
For sake of the test of saving, validation was not called so line item wasn't removed. The problem is solved by upgrading from start.
Hi
After upgrading to 10.2.3 we are experiencing _orderRepository.Save(cart); crashing after cart is updated and saved again. The exception comes from SQL: Cannot insert the value NULL into column 'InStockQuantity', table 'NNNNNNNNNN_10.dbo.LineItem'; column does not allow nulls. UPDATE fails.
For first there is no setting of InStockQuantity by us, but it is passed as not null and Save goes OK. Next time same code is run, it fails. For sake of testing there is one simple entry type:
One entry of that type is created in catalog UI and then this shippet of code is executed:
where GetCart returns always the same named cart
First time cart is saved with no problems, then second call causes exception:
If somebody has an idea what to look for as a reason, it will be much appreciated
Thanks