예제 #1
0
        /// <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;
			}
		}