/// <summary> /// Create, Add, Update the orderline /// </summary> /// <param name="order"></param> /// <param name="orderLineId">The Id of the orderline</param> /// <param name="productId">The productId</param> /// <param name="action">The action (add, update, delete, deleteall)</param> /// <param name="itemCount">The amount of items to be added</param> /// <param name="variantsList">The variants ID's added to the pricing</param> /// <param name="fields">Custom Fields</param> /// <exception cref="System.ArgumentException"> /// productId and orderLineId equal or lower to 0 /// or /// itemCountToAdd can't be smaller than 0 /// </exception> /// <exception cref="System.Exception"> /// Orderline not found /// </exception> public void AddOrUpdateOrderLine(OrderInfo order, int orderLineId, int productId, string action, int itemCount, IEnumerable <int> variantsList, Dictionary <string, string> fields = null) { //todo: function is too long // separate control and logic //todo: function needs testing // todo: DIP var isWishList = order != null && order.Status == OrderStatus.Wishlist; if (!_cmsApplication.RequestIsInCMSBackend(HttpContext.Current) && !isWishList) { if (order == null || order.Paid.GetValueOrDefault(false) || (order.Status != OrderStatus.PaymentFailed && order.Status != OrderStatus.Incomplete && order.Status != OrderStatus.WaitingForPayment)) { Log.Instance.LogDebug("Starting new order for user" + (order == null ? "" : ", previous order: " + order.UniqueOrderId)); order = OrderHelper.CreateOrder(); } if (order.Status == OrderStatus.PaymentFailed || order.Status == OrderStatus.WaitingForPayment) { Log.Instance.LogDebug("Orderstatus WILL BE CHANGED FROM: " + order.Status); order.Status = OrderStatus.Incomplete; } } if (order == null) { return; } // clear some stored values so they can be recalculated order.ClearCachedValues(); if (itemCount == 0 && action != "update") { itemCount = 1; } if (productId <= 0 && orderLineId <= 0) { throw new ArgumentException("productId <= 0 && orderLineId <= 0"); } if (itemCount < 0) { throw new ArgumentException("itemCount can't be smaller than 0"); } Log.Instance.LogDebug("AddOrUpdateOrderLine Before action"); var variants = variantsList.Where(v => v != 0).OrderBy(v => v); OrderLine orderLine = null; if (orderLineId != 0 && action != "new") { orderLine = order.OrderLines.FirstOrDefault(line => line.OrderLineId == orderLineId); } if (orderLine == null && action != "new") { orderLine = order.OrderLines.FirstOrDefault(line => line.ProductInfo.Id == productId && line.VariantsMatch(variants)); } if (orderLineId != 0 && orderLine == null && action != "new") { throw new Exception("Orderline not found"); } if (productId == 0 && orderLine != null) { productId = orderLine.ProductInfo.Id; } if (action == "add" || action == "new") { action = "update"; if (orderLine != null) { itemCount = (int)(orderLine.ProductInfo.ItemCount + itemCount); } } Log.Instance.LogDebug("AddOrUpdateOrderLine Before stock"); if (productId != 0 && !isWishList) { var requestedItemCount = itemCount; var tooMuchStock = false; var localization = StoreHelper.CurrentLocalization; var product = _productService.GetById(productId, localization); if (product == null) { Log.Instance.LogError("AddOrUpdateOrderLine can't find product with Id " + productId); } var higherItemList = new List <int>(); foreach (var variant in variantsList.Select(variantId => _productVariantService.GetById(variantId, localization))) { if (variant != null && variant.StockStatus && !variant.BackorderStatus && variant.Stock < requestedItemCount) { higherItemList.Add(variant.Id); var stock = variant.Stock; itemCount = stock; tooMuchStock = true; } } if (product != null && !product.UseVariantStock && product.StockStatus && !product.BackorderStatus && product.Stock < itemCount) { higherItemList.Add(product.Id); itemCount = product.Stock; tooMuchStock = true; } if (HttpContext.Current != null && higherItemList.Any()) { // todo: dit moet ook in handleobject komen Session.Add(Constants.OrderedItemcountHigherThanStockKey, higherItemList); } if (HttpContext.Current != null) // todo: better decoupling { ClientErrorHandling.SetOrClearErrorMessage(!tooMuchStock, "Ordered higher quantity than available stock. Updated the basked to available stock count", "Stock", requestedItemCount.ToString()); } } if (itemCount < 1) { itemCount = 0; } if (action == "update" && itemCount == 0) { action = "delete"; } Log.Instance.LogDebug("AddOrUpdateOrderLine Before update"); #region update if (action == "update") { var beforeUpdatedEventArgs = order.FireBeforeOrderLineUpdatedEvent(orderLine); if (beforeUpdatedEventArgs == null || !beforeUpdatedEventArgs.Cancel) // todo: test the cancel { if (orderLine == null) { order.FireBeforeOrderLineCreatedEvent(); if (orderLineId == 0) { orderLine = OrderProduct(productId, variants, itemCount, order); if (!order.OrderLines.Any()) { orderLine.OrderLineId = 1; } else { var firstOrDefault = order.OrderLines.OrderByDescending(x => x.OrderLineId).FirstOrDefault(); if (firstOrDefault != null) { var highestOrderLineId = firstOrDefault.OrderLineId; orderLine.OrderLineId = highestOrderLineId + 1; } } } if (orderLine == null) { throw new Exception("Order line not found"); } order.OrderLines.Add(orderLine); order.FireAfterOrderLineCreatedEvent(orderLine); } if (orderLineId != 0) { orderLine.ProductInfo.ItemCount = itemCount; // todo: double with a few lines below? // onderstaande regel gooit variants weg als ze niet in de lijst met ids zitten, dat is by design orderLine.ProductInfo.ProductVariants = variants.Select( variant => new ProductVariantInfo(DomainHelper.GetProductVariantById(variant), orderLine.ProductInfo, itemCount)).ToList(); } orderLine.ProductInfo.ChangedOn = DateTime.Now; orderLine.ProductInfo.ItemCount = itemCount; UpdateProductInfoDiscountInformation(orderLine.ProductInfo); foreach (var variant in orderLine.ProductInfo.ProductVariants) { variant.ChangedOn = DateTime.Now; } order.FireAfterOrderLineUpdatedEvent(orderLine); } //Log.Instance.LogDebug("AddOrUpdateOrderLine() UPDATE END: " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt")); } #endregion #region delete if (action == "delete") { BeforeOrderLineDeletedEventArgs beforeDeletedEventArgs = order.FireBeforeOrderLineDeletedEvent(orderLine); if (beforeDeletedEventArgs == null || !beforeDeletedEventArgs.Cancel) { order.OrderLines.Remove(orderLine); order.FireAfterOrderLineDeletedEvent(); } } #endregion // UPDATE SHIPPING & SET UPDATESHIPPINGCOSTS TO TRUE AFTER BASKET UPDATE //Log.Instance.LogDebug( "AddOrUpdateOrderLine() AutoSelectShippingProvider START: " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt")); //AutoSelectShippingProvider(); //Log.Instance.LogDebug( "AddOrUpdateOrderLine() AutoSelectShippingProvider END: " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt")); order.ShippingCostsMightBeOutdated = true; //Log.Instance.LogDebug( "AddOrUpdateOrderLine() function END: " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt")); if (fields == null) { return; } var xDoc = new XDocument(new XElement("Fields")); Log.Instance.LogDebug("AddOrUpdateOrderLine Before xdoc"); if (orderLine != null && orderLine.ProductInfo != null && orderLine.ProductInfo.CatalogProduct != null) { AddFieldsToXDocumentBasedOnCMSDocumentType(xDoc, fields, orderLine.ProductInfo.CatalogProduct.NodeTypeAlias()); orderLine._customData = xDoc; } }
/// <summary> /// Create, Add, Update the orderline /// </summary> /// <param name="order"></param> /// <param name="orderLineId">The Id of the orderline</param> /// <param name="productId">The productId</param> /// <param name="action">The action (add, update, delete, deleteall)</param> /// <param name="itemCount">The amount of items to be added</param> /// <param name="variantsList">The variants ID's added to the pricing</param> /// <param name="fields">Custom Fields</param> /// <exception cref="System.ArgumentException"> /// productId and orderLineId equal or lower to 0 /// or /// itemCountToAdd can't be smaller than 0 /// </exception> /// <exception cref="System.Exception"> /// Orderline not found /// </exception> public void AddOrUpdateOrderLine(OrderInfo order, int orderLineId, int productId, string action, int itemCount, IEnumerable<int> variantsList, Dictionary<string, string> fields = null) { //todo: function is too long // separate control and logic //todo: function needs testing // todo: DIP var isWishList = order != null && order.Status == OrderStatus.Wishlist; if (!_cmsApplication.RequestIsInCMSBackend(HttpContext.Current) && !isWishList) { if (order == null || order.Paid.GetValueOrDefault(false) || (order.Status != OrderStatus.PaymentFailed && order.Status != OrderStatus.Incomplete && order.Status != OrderStatus.WaitingForPayment)) { Log.Instance.LogDebug("Starting new order for user" + (order == null ? "" : ", previous order: " + order.UniqueOrderId)); order = OrderHelper.CreateOrder(); } if (order.Status == OrderStatus.PaymentFailed || order.Status == OrderStatus.WaitingForPayment) { Log.Instance.LogDebug("Orderstatus WILL BE CHANGED FROM: " + order.Status); order.Status = OrderStatus.Incomplete; } } if (order == null) return; // clear some stored values so they can be recalculated order.ClearCachedValues(); if (itemCount == 0 && action != "update") itemCount = 1; if (productId <= 0 && orderLineId <= 0) { throw new ArgumentException("productId <= 0 && orderLineId <= 0"); } if (itemCount < 0) { throw new ArgumentException("itemCount can't be smaller than 0"); } Log.Instance.LogDebug("AddOrUpdateOrderLine Before action"); var variants = variantsList.Where(v => v != 0).OrderBy(v => v); OrderLine orderLine = null; if (orderLineId != 0 && action != "new") { orderLine = order.OrderLines.FirstOrDefault(line => line.OrderLineId == orderLineId); } if (orderLine == null && action != "new") { orderLine = order.OrderLines.FirstOrDefault(line => line.ProductInfo.Id == productId && line.VariantsMatch(variants)); } if (orderLineId != 0 && orderLine == null && action != "new") throw new Exception("Orderline not found"); if (productId == 0 && orderLine != null) productId = orderLine.ProductInfo.Id; if (action == "add" || action == "new") { action = "update"; if (orderLine != null) { itemCount = (int) (orderLine.ProductInfo.ItemCount + itemCount); } } Log.Instance.LogDebug("AddOrUpdateOrderLine Before stock"); if (productId != 0 && !isWishList) { var requestedItemCount = itemCount; var tooMuchStock = false; var localization = StoreHelper.CurrentLocalization; var product = _productService.GetById(productId, localization); if (product == null) { Log.Instance.LogError("AddOrUpdateOrderLine can't find product with Id " + productId); } var higherItemList = new List<int>(); foreach (var variant in variantsList.Select(variantId => _productVariantService.GetById(variantId, localization))) { if (variant != null && variant.StockStatus && !variant.BackorderStatus && variant.Stock < requestedItemCount) { higherItemList.Add(variant.Id); var stock = variant.Stock; itemCount = stock; tooMuchStock = true; } } if (product != null && !product.UseVariantStock && product.StockStatus && !product.BackorderStatus && product.Stock < itemCount) { higherItemList.Add(product.Id); itemCount = product.Stock; tooMuchStock = true; } if (HttpContext.Current != null && higherItemList.Any()) { // todo: dit moet ook in handleobject komen Session.Add(Constants.OrderedItemcountHigherThanStockKey, higherItemList); } if (HttpContext.Current != null) // todo: better decoupling ClientErrorHandling.SetOrClearErrorMessage(!tooMuchStock, "Ordered higher quantity than available stock. Updated the basked to available stock count", "Stock", requestedItemCount.ToString()); } if (itemCount < 1) { itemCount = 0; } if (action == "update" && itemCount == 0) { action = "delete"; } Log.Instance.LogDebug("AddOrUpdateOrderLine Before update"); #region update if (action == "update") { var beforeUpdatedEventArgs = order.FireBeforeOrderLineUpdatedEvent(orderLine); if (beforeUpdatedEventArgs == null || !beforeUpdatedEventArgs.Cancel) // todo: test the cancel { if (orderLine == null) { order.FireBeforeOrderLineCreatedEvent(); if (orderLineId == 0) { orderLine = OrderProduct(productId, variants, itemCount, order); if (!order.OrderLines.Any()) { orderLine.OrderLineId = 1; } else { var firstOrDefault = order.OrderLines.OrderByDescending(x => x.OrderLineId).FirstOrDefault(); if (firstOrDefault != null) { var highestOrderLineId = firstOrDefault.OrderLineId; orderLine.OrderLineId = highestOrderLineId + 1; } } } if (orderLine == null) { throw new Exception("Order line not found"); } order.OrderLines.Add(orderLine); order.FireAfterOrderLineCreatedEvent(orderLine); } if (orderLineId != 0) { orderLine.ProductInfo.ItemCount = itemCount; // todo: double with a few lines below? // onderstaande regel gooit variants weg als ze niet in de lijst met ids zitten, dat is by design orderLine.ProductInfo.ProductVariants = variants.Select( variant => new ProductVariantInfo(DomainHelper.GetProductVariantById(variant), orderLine.ProductInfo, itemCount)).ToList(); } orderLine.ProductInfo.ChangedOn = DateTime.Now; orderLine.ProductInfo.ItemCount = itemCount; UpdateProductInfoDiscountInformation(orderLine.ProductInfo); foreach (var variant in orderLine.ProductInfo.ProductVariants) variant.ChangedOn = DateTime.Now; order.FireAfterOrderLineUpdatedEvent(orderLine); } //Log.Instance.LogDebug("AddOrUpdateOrderLine() UPDATE END: " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt")); } #endregion #region delete if (action == "delete") { BeforeOrderLineDeletedEventArgs beforeDeletedEventArgs = order.FireBeforeOrderLineDeletedEvent(orderLine); if (beforeDeletedEventArgs == null || !beforeDeletedEventArgs.Cancel) { order.OrderLines.Remove(orderLine); order.FireAfterOrderLineDeletedEvent(); } } #endregion // UPDATE SHIPPING & SET UPDATESHIPPINGCOSTS TO TRUE AFTER BASKET UPDATE //Log.Instance.LogDebug( "AddOrUpdateOrderLine() AutoSelectShippingProvider START: " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt")); //AutoSelectShippingProvider(); //Log.Instance.LogDebug( "AddOrUpdateOrderLine() AutoSelectShippingProvider END: " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt")); order.ShippingCostsMightBeOutdated = true; //Log.Instance.LogDebug( "AddOrUpdateOrderLine() function END: " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt")); if (fields == null) return; var xDoc = new XDocument(new XElement("Fields")); Log.Instance.LogDebug("AddOrUpdateOrderLine Before xdoc"); if (orderLine != null && orderLine.ProductInfo != null && orderLine.ProductInfo.CatalogProduct != null) { AddFieldsToXDocumentBasedOnCMSDocumentType(xDoc, fields, orderLine.ProductInfo.CatalogProduct.NodeTypeAlias()); orderLine._customData = xDoc; } }