Exemple #1
0
        private static void AdjustStockItemQuantity(LineItem lineItem)
        {
            if (lineItem.CatalogEntryId == "0" &&
                String.IsNullOrEmpty(lineItem.CatalogEntryId) &&
                lineItem.CatalogEntryId.StartsWith("@"))
            {
                return;
            }
            var entryDto = CatalogContext.Current.GetCatalogEntryDto(lineItem.CatalogEntryId,
                                                                     new CatalogEntryResponseGroup(CatalogEntryResponseGroup.ResponseGroup.CatalogEntryFull));

            var catalogEntry = GetCatalogEntry(entryDto);

            if (catalogEntry != null && CheckNeedEntryTracking(catalogEntry))
            {
                decimal    changeInInventory = -lineItem.Quantity;
                IWarehouse warehouse         = ServiceLocator.Current.GetInstance <IWarehouseRepository>().Get(lineItem.WarehouseCode);
                if (warehouse != null)
                {
                    IWarehouseInventory inventory = ServiceLocator.Current.GetInstance <IWarehouseInventoryService>()
                                                    .Get(new CatalogKey(catalogEntry), warehouse);
                    if (inventory != null)
                    {
                        AdjustStockInventoryQuantity(lineItem, inventory, changeInInventory);
                    }
                }
            }
        }
Exemple #2
0
        private void ValidateItems()
        {
            CatalogRelationDto relationDto = null;

            CatalogDto.CatalogRow catalogRow = null;

            var marketTester   = new ExcludedCatalogEntryMarketsField();
            var orderMarket    = ServiceLocator.Current.GetInstance <IMarketService>().GetMarket(OrderGroup.MarketId);
            var orderForms     = OrderGroup.OrderForms.ToArray();
            var lineItems      = orderForms.SelectMany(x => x.LineItems.ToArray());
            var validLineItems = lineItems.Where(x => x.CatalogEntryId != "0" && !String.IsNullOrEmpty(x.CatalogEntryId) && !x.CatalogEntryId.StartsWith("@"));

            foreach (var lineItem in validLineItems)
            {
                var entryRow = GetEntryRowForLineItem(lineItem);

                if (entryRow == null)
                {
                    AddWarningSafe(Warnings, "LineItemCodeRemoved-" + lineItem.Id,
                                   String.Format("The catalog entry code that maps to the line item {0} has been removed or changed.  The line item is no longer valid", lineItem.CatalogEntryId));
                    DeleteInvalidItem(orderForms, lineItem);
                    continue;
                }

                if (!marketTester.IsValidForMarket(entryRow, orderMarket))
                {
                    AddWarningSafe(Warnings, "LineItemRemoved-" + lineItem.LineItemId.ToString(),
                                   String.Format("Item \"{0}\" has been removed from the cart because it is not available in your market.",
                                                 lineItem.DisplayName));
                    DeleteInvalidItem(orderForms, lineItem);
                }
                else if (entryRow.IsActive &&
                         entryRow.StartDate < FrameworkContext.Current.CurrentDateTime &&
                         entryRow.EndDate > FrameworkContext.Current.CurrentDateTime)
                {
                    if (catalogRow == null || catalogRow.CatalogId != entryRow.CatalogId)
                    {
                        var catalogDto = CatalogContext.Current.GetCatalogDto(entryRow.CatalogId);
                        catalogRow = catalogDto.Catalog.FirstOrDefault();
                    }

                    // check if catalog is visible
                    if (catalogRow != null && catalogRow.IsActive &&
                        catalogRow.StartDate < FrameworkContext.Current.CurrentDateTime &&
                        catalogRow.EndDate > FrameworkContext.Current.CurrentDateTime)
                    {
                        relationDto = CatalogContext.Current.GetCatalogRelationDto(entryRow.CatalogEntryId);
                        // populate item
                        lineItem.Catalog = catalogRow.Name;
                        lineItem.ParentCatalogEntryId = GetParentCatalogEntryId(entryRow.CatalogEntryId, relationDto);
                        //Inventory Info
                        IWarehouseInventory aggregateInventory = ServiceLocator.Current.GetInstance <IWarehouseInventoryService>()
                                                                 .GetTotal(new CatalogKey(entryRow));
                        PopulateInventoryInfo(aggregateInventory, lineItem);
                        //Variation Info
                        PopulateVariationInfo(entryRow, lineItem);
                    }
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Determines whether the specific inventory has enough quantity for the line item.
        /// </summary>
        /// <param name="inventory">The inventory.</param>
        /// <param name="lineItem">The line item.</param>
        /// <returns>
        ///   <c>true</c> if has enough quantity; otherwise, <c>false</c>.
        /// </returns>
        private bool IsEnoughQuantity(IWarehouseInventory inventory, LineItem lineItem)
        {
            //TODO: Consolidate with CheckInventoryActivity
            decimal quantity = lineItem.Quantity;

            if (lineItem.InventoryStatus == (int)InventoryTrackingStatus.Enabled)
            {
                var entry = CatalogContext.Current.GetCatalogEntry(lineItem.CatalogEntryId, CatalogEntryResponseGroup_InfoWithVariations);
                if (inventory == null)
                {
                    // Treat missing as zeroes
                    inventory = new WarehouseInventory();
                    ((WarehouseInventory)inventory).InventoryStatus = InventoryTrackingStatus.Enabled;
                }
                if (entry.StartDate > FrameworkContext.Current.CurrentDateTime)
                {
                    //not allow preorder or preorder is not available
                    if (!inventory.AllowPreorder || inventory.PreorderAvailabilityDate > FrameworkContext.Current.CurrentDateTime)
                    {
                        return(false);
                    }
                    //allow preorder but quantity is not enough
                    if (quantity > inventory.PreorderQuantity)
                    {
                        return(false);
                    }
                }
                if (inventory.InStockQuantity > 0 && inventory.InStockQuantity >= inventory.ReservedQuantity + quantity)
                {
                    return(true);
                }

                //Not enough quantity in stock, check for backorder
                if (!inventory.AllowBackorder)
                {
                    return(false);
                }
                //Backorder is not available
                if (inventory.BackorderAvailabilityDate > FrameworkContext.Current.CurrentDateTime)
                {
                    return(false);
                }
                //Backorder quantity is not enough
                if (quantity > inventory.InStockQuantity -
                    inventory.ReservedQuantity + inventory.BackorderQuantity)
                {
                    return(false);
                }
            }
            return(true);
        }
        /// <summary>
        /// Gets the items in stock.
        /// </summary>
        /// <param name="entry">The entry.</param>
        /// <returns></returns>
        public static decimal GetItemsInStock(Entry entry)
        {
            if (entry == null)
            {
                return(0);
            }

            if (entry.WarehouseInventories == null)
            {
                return(0);
            }

            IWarehouseInventory sumInventory = SumInventories(entry.WarehouseInventories.WarehouseInventory);

            return(sumInventory.InStockQuantity - sumInventory.ReservedQuantity);
        }
Exemple #5
0
        /// <summary>
        /// Pre processes item record adding additional LineItems if needed.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="record">The record.</param>
        private void PreProcessItemRecord(OrderGroup order, PromotionItemRecord record)
        {
            // We do special logic for the gift promotion reward
            if (record.PromotionReward is GiftPromotionReward)
            {
                // Check if item already in the cart, if not add
                if (((GiftPromotionReward)record.PromotionReward).AddStrategy == GiftPromotionReward.Strategy.AddWhenNeeded)
                {
                    // We assume that all affected entries are the gifts that need to be added to the cart
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        LineItem giftLineItem = FindGiftLineItemInOrder(order, entry.CatalogEntryCode, record);

                        if (!IsOrderHaveSpecifiedGiftPromotion(order, record))
                        {
                            // Didn't find, add it
                            if (giftLineItem == null)
                            {
                                // we should some kind of delegate or common implementation here so we can use the same function in both discount and front end
                                Entry catEntry = CatalogContext.Current.GetCatalogEntry(entry.CatalogEntryCode);
                                giftLineItem = AddNewGiftLineItemToOrder(order, catEntry, entry.Quantity);
                                AddGiftItemToAShipment(giftLineItem);
                                CatalogEntryResponseGroup       responseGroup = new CatalogEntryResponseGroup(CatalogEntryResponseGroup.ResponseGroup.CatalogEntryFull);
                                CatalogEntryDto                 entryDto      = CatalogContext.Current.GetCatalogEntryDto(giftLineItem.CatalogEntryId, responseGroup);
                                CatalogEntryDto.CatalogEntryRow entryRow      = entryDto.CatalogEntry[0];
                                Money?price = GetItemPrice(entryRow, giftLineItem, CustomerContext.Current.CurrentContact);
                                giftLineItem.ListPrice   = price.HasValue ? price.Value.Amount : 0m;
                                giftLineItem.PlacedPrice = giftLineItem.ListPrice;
                                // populate inventory information for giftLineItem
                                IWarehouseInventory aggregateInventory = ServiceLocator.Current.GetInstance <IWarehouseInventoryService>().GetTotal(new CatalogKey(entryRow));
                                PopulateInventoryInfo(aggregateInventory, giftLineItem);
                            }
                            else
                            {
                                giftLineItem.Quantity = Math.Max(entry.Quantity, giftLineItem.Quantity);
                            }
                        }
                        else
                        {
                            entry.Quantity = giftLineItem != null?Math.Min(entry.Quantity, giftLineItem.Quantity) : entry.Quantity;
                        }
                        entry.Owner        = giftLineItem;
                        entry.CostPerEntry = giftLineItem != null ? giftLineItem.ListPrice : 0m;
                    }
                }
            }
        }
        private InventoryRecord InventoryToRecord(IWarehouseInventory warehouseInventory)
        {
            var ir = new InventoryRecord();

            ir.CatalogEntryCode           = warehouseInventory.CatalogKey.CatalogEntryCode;
            ir.WarehouseCode              = warehouseInventory.WarehouseCode;
            ir.IsTracked                  = warehouseInventory.InventoryStatus == InventoryTrackingStatus.Enabled;
            ir.PurchaseAvailableQuantity  = warehouseInventory.InStockQuantity - warehouseInventory.ReservedQuantity;
            ir.PreorderAvailableQuantity  = Math.Max(warehouseInventory.PreorderQuantity, 0);
            ir.BackorderAvailableQuantity = Math.Max(warehouseInventory.AllowBackorder ? warehouseInventory.BackorderQuantity : 0, 0);
            ir.PreorderAvailableUtc       = warehouseInventory.AllowPreorder ? (warehouseInventory.PreorderAvailabilityDate ?? SafeBeginningOfTime) : SafeBeginningOfTime;
            ir.BackorderAvailableUtc      = warehouseInventory.BackorderAvailabilityDate ?? SafeBeginningOfTime;
            ir.AdditionalQuantity         = warehouseInventory.ReservedQuantity;
            ir.ReorderMinQuantity         = warehouseInventory.ReorderMinQuantity;

            return(ir);
        }
        /// <summary>
        /// Determines whether [is available for preorder] [the specified entry].
        /// </summary>
        /// <param name="entry">The entry.</param>
        /// <returns>
        ///     <c>true</c> if [is available for preorder] [the specified entry]; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsAvailableForPreorder(Entry entry)
        {
            if (entry == null)
            {
                return(false);
            }

            if (entry.WarehouseInventories == null)
            {
                return(false);
            }

            IWarehouseInventory sumInventory = SumInventories(entry.WarehouseInventories.WarehouseInventory);

            if (sumInventory.AllowPreorder && sumInventory.PreorderQuantity > 0 && sumInventory.PreorderAvailabilityDate <= DateTime.UtcNow)
            {
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Gets the inventory status.
        /// </summary>
        /// <param name="entry">The entry.</param>
        /// <returns></returns>
        public static string GetInventoryStatus(Entry entry)
        {
            if (IsInStock(entry))
            {
                return("Item is in stock");
            }

            if (entry == null)
            {
                return("");
            }

            if (entry.WarehouseInventories == null)
            {
                return("");
            }

            IWarehouseInventory sumInventory = SumInventories(entry.WarehouseInventories.WarehouseInventory);

            if (IsAvailableForPreorder(entry))
            {
                return("Item is available for preorder");
            }
            else if (sumInventory.AllowPreorder && sumInventory.PreorderAvailabilityDate.HasValue)
            {
                return(String.Format("Item will be available for preorder on {0}", sumInventory.PreorderAvailabilityDate.Value.ToString("MMMM dd, yyyy")));
            }

            if (IsAvailableForBackorder(entry))
            {
                return("Item is available for backorder");
            }
            else if (sumInventory.AllowBackorder && sumInventory.BackorderAvailabilityDate.HasValue)
            {
                return(String.Format("Item will be available for backorder on {0}", sumInventory.BackorderAvailabilityDate.Value.ToString("MMMM dd, yyyy")));
            }

            return("Item is out of stock");
        }
        /// <summary>
        /// Determines whether entry is in stock.
        /// </summary>
        /// <param name="entry">The entry.</param>
        /// <returns>
        ///     <c>true</c> if entry is in stock otherwise, <c>false</c>.
        /// </returns>
        public static bool IsInStock(Entry entry)
        {
            if (entry == null)
            {
                return(false);
            }

            if (entry.WarehouseInventories == null)
            {
                return(false);
            }

            IWarehouseInventory sumInventory = SumInventories(entry.WarehouseInventories.WarehouseInventory);

            // If we don't account inventory return true always
            if (sumInventory.InventoryStatus != InventoryTrackingStatus.Enabled)
            {
                return(true);
            }

            return((GetItemsInStock(entry) > 0) ? true : false);
        }
Exemple #10
0
 protected void PopulateInventoryInfo(IWarehouseInventory inv, LineItem lineItem)
 {
     if (inv != null)
     {
         lineItem.AllowBackordersAndPreorders = inv.AllowBackorder | inv.AllowPreorder;
         // Init quantities once
         lineItem.BackorderQuantity = inv.BackorderQuantity;
         lineItem.InStockQuantity   = inv.InStockQuantity - inv.ReservedQuantity;
         lineItem.PreorderQuantity  = inv.PreorderQuantity;
         lineItem.InventoryStatus   = (int)inv.InventoryStatus;
     }
     else
     {
         var baseEntry = CatalogContext.Current.GetCatalogEntry(lineItem.CatalogEntryId,
                                                                new CatalogEntryResponseGroup(
                                                                    CatalogEntryResponseGroup.ResponseGroup.CatalogEntryInfo |
                                                                    CatalogEntryResponseGroup.ResponseGroup.Variations));
         lineItem.AllowBackordersAndPreorders = false;
         lineItem.InStockQuantity             = 0;
         lineItem.PreorderQuantity            = 0;
         lineItem.InventoryStatus             = (int)baseEntry.InventoryStatus;
     }
 }
 protected void PopulateInventoryInfo(IWarehouseInventory inv, LineItem lineItem)
 {
     PopulateInventoryInfo(InventoryToRecord(inv), lineItem);
 }
 protected void PopulateInventoryInfo(IWarehouseInventory inv, LineItem lineItem)
 {
     if (inv != null)
     {
         lineItem.AllowBackordersAndPreorders = inv.AllowBackorder | inv.AllowPreorder;
         // Init quantities once
         lineItem.BackorderQuantity = inv.BackorderQuantity;
         lineItem.InStockQuantity = inv.InStockQuantity - inv.ReservedQuantity;
         lineItem.PreorderQuantity = inv.PreorderQuantity;
         lineItem.InventoryStatus = (int)inv.InventoryStatus;
     }
     else
     {
         var baseEntry = CatalogContext.Current.GetCatalogEntry(lineItem.Code,
             new CatalogEntryResponseGroup(
                 CatalogEntryResponseGroup.ResponseGroup.CatalogEntryInfo |
                 CatalogEntryResponseGroup.ResponseGroup.Variations));
         lineItem.AllowBackordersAndPreorders = false;
         lineItem.InStockQuantity = 0;
         lineItem.PreorderQuantity = 0;
         lineItem.InventoryStatus = (int)baseEntry.InventoryStatus;
     }
 }
Exemple #13
0
        private decimal GetNewLineItemQty(LineItem lineItem, List <string> changeQtyReason)
        {
            var newLineItemQty = lineItem.Quantity;

            if (newLineItemQty < lineItem.MinQuantity || newLineItemQty > lineItem.MaxQuantity)
            {
                newLineItemQty = Math.Max(lineItem.MinQuantity, newLineItemQty);
                if (newLineItemQty != lineItem.Quantity)
                {
                    changeQtyReason.Add("by Min Quantity setting");
                }
                newLineItemQty = Math.Min(lineItem.MaxQuantity, newLineItemQty);
                if (newLineItemQty != lineItem.Quantity)
                {
                    changeQtyReason.Add("by Max Quantity setting");
                }
            }

            if (lineItem.InventoryStatus == (int)InventoryTrackingStatus.Enabled)
            {
                IWarehouse          warehouse  = ServiceLocator.Current.GetInstance <IWarehouseRepository>().Get(lineItem.WarehouseCode);
                IWarehouseInventory inventory  = null;
                CatalogKey          catalogKey = new CatalogKey(lineItem.Parent.Parent.ApplicationId, lineItem.CatalogEntryId);
                if (warehouse != null)
                {
                    if (!warehouse.IsActive)
                    {
                        return(0);
                    }

                    inventory = ServiceLocator.Current.GetInstance <IWarehouseInventoryService>().Get(
                        new CatalogKey(lineItem.Parent.Parent.ApplicationId, lineItem.CatalogEntryId), warehouse);
                }

                // if no inventory, return 0;
                if (inventory == null)
                {
                    return(0);
                }

                decimal availableQuantity = inventory.InStockQuantity - inventory.ReservedQuantity;
                // item exists with appropriate quantity
                if (availableQuantity < newLineItemQty)
                {
                    if (availableQuantity > 0) // there still exist items in stock
                    {
                        // check if we can backorder some items
                        if ((inventory.AllowBackorder | inventory.AllowPreorder))
                        {
                            //Increase stock qty by backorder qty if
                            var availStockAndBackorderQty = availableQuantity + inventory.BackorderQuantity;
                            if (availStockAndBackorderQty >= newLineItemQty)
                            {
                                //NONE
                            }
                            else
                            {
                                newLineItemQty = availStockAndBackorderQty;
                                changeQtyReason.Add("by BackOrder quantity");
                            }
                        }
                        else
                        {
                            newLineItemQty = availableQuantity;
                        }
                    }
                    else
                    {
                        if ((inventory.AllowBackorder | inventory.AllowPreorder) && inventory.PreorderQuantity > 0)
                        {
                            if (inventory.PreorderQuantity >= newLineItemQty)
                            {
                                //NONE
                            }
                            else
                            {
                                newLineItemQty = inventory.PreorderQuantity;
                                changeQtyReason.Add("by Preorder quantity");
                            }
                        }
                        else if ((inventory.AllowBackorder | inventory.AllowPreorder) && inventory.BackorderQuantity > 0)
                        {
                            if (inventory.BackorderQuantity >= newLineItemQty)
                            {
                            }
                            else
                            {
                                newLineItemQty = inventory.BackorderQuantity;
                                changeQtyReason.Add("by BackOrder quantity");
                            }
                        }
                        else
                        {
                            newLineItemQty = 0;
                        }
                    }
                }
            }
            return(newLineItemQty);
        }
Exemple #14
0
        /// <summary>
        /// Adjusts the stock inventory quantities. Method assumes only inventory TRACKING is enabled.
        /// </summary>
        /// <param name="lineItem">Line item object in cart.</param>
        /// <param name="inventory">Inventory associated with the line item's catalog entry.</param>
        /// <param name="delta">The change in inventory.</param>
        private static void AdjustStockInventoryQuantity(LineItem lineItem, IWarehouseInventory inventory, decimal delta)
        {
            if (inventory == null)
            {
                if (delta != 0)
                {
                    //throw new Exception("Inventory cannot be null with non-zero delta.");
                    return;
                }
                return;
            }

            WarehouseInventory editedInventory = new WarehouseInventory(inventory);

            //arrival
            if (delta > 0)
            {
                // need distribute delta between InStock, Backorder, Preorder.
                if (lineItem.InStockQuantity > 0)
                {
                    var backorderDelta = Math.Min(delta, lineItem.BackorderQuantity - inventory.BackorderQuantity);
                    var preorderdelta  = Math.Min(delta, lineItem.PreorderQuantity - inventory.PreorderQuantity);
                    editedInventory.PreorderQuantity  += preorderdelta;
                    editedInventory.BackorderQuantity += backorderDelta;
                    editedInventory.InStockQuantity   += delta - backorderDelta - preorderdelta;
                }                 //need distribute delta between Preorder and Backorder
                else if (lineItem.InStockQuantity == 0)
                {
                    if (lineItem.PreorderQuantity > 0)
                    {
                        editedInventory.PreorderQuantity += delta;
                    }
                    else if (lineItem.BackorderQuantity > 0)
                    {
                        editedInventory.BackorderQuantity += delta;
                    }
                }
            }            //consumption
            else
            {
                delta = Math.Abs(delta);
                bool inventoryEnabled = inventory.InventoryStatus == InventoryTrackingStatus.Enabled;
                //Instock quantity is larger than delta plus reserved quantity
                if (inventory.InStockQuantity >= delta + inventory.ReservedQuantity) // Adjust the main inventory
                {
                    //just simply subtract from Instock quantity
                    editedInventory.InStockQuantity -= delta;
                }
                //Instock quantity is larger than delta but smaller than delta and reserved quantity
                else if (inventory.InStockQuantity >= inventory.ReservedQuantity)
                {
                    if (inventoryEnabled)
                    {
                        if (editedInventory.AllowPreorder && editedInventory.PreorderAvailabilityDate <= FrameworkContext.Current.CurrentDateTime)
                        {
                            editedInventory.PreorderQuantity -= delta;
                        }

                        if (editedInventory.AllowBackorder && editedInventory.BackorderAvailabilityDate <= FrameworkContext.Current.CurrentDateTime)
                        {
                            editedInventory.BackorderQuantity -= delta - (editedInventory.InStockQuantity - inventory.ReservedQuantity);
                            editedInventory.InStockQuantity    = inventory.ReservedQuantity;
                        }
                    }
                    else
                    {
                        editedInventory.InStockQuantity -= delta;
                    }
                }
                else if (inventory.InStockQuantity > 0) // there still exist items in stock
                {
                    // Calculate difference between currently available and backorder
                    var backorderDelta = delta - (inventory.InStockQuantity - (inventoryEnabled ? inventory.ReservedQuantity : 0));

                    // Update inventory
                    if (inventoryEnabled)
                    {
                        editedInventory.InStockQuantity    = inventory.ReservedQuantity;
                        editedInventory.BackorderQuantity -= backorderDelta;
                    }
                    else
                    {
                        editedInventory.InStockQuantity -= delta;
                    }
                }
                else if (inventory.InStockQuantity == 0)
                {
                    if (inventoryEnabled)
                    {
                        if (inventory.PreorderQuantity == 0)
                        {
                            editedInventory.BackorderQuantity -= delta;
                        }
                        else
                        {
                            editedInventory.PreorderQuantity -= delta;
                        }
                    }
                    else
                    {
                        editedInventory.InStockQuantity = -delta;
                    }
                }
            }

            ServiceLocator.Current.GetInstance <IWarehouseInventoryService>().Save(editedInventory);
        }
        /// <summary>
        /// Adjusts the stock inventory quantities. Method assumes only inventory TRACKING is enabled.
        /// </summary>
        /// <param name="lineItem">Line item object in cart.</param>
        /// <param name="inventory">Inventory associated with the line item's catalog entry.</param>
        /// <param name="delta">The change in inventory.</param>
        private static void AdjustStockInventoryQuantity(LineItem lineItem, IWarehouseInventory inventory, decimal delta)
        {
            if (inventory == null)
            {
                if (delta != 0)
                {
                    //throw new Exception("Inventory cannot be null with non-zero delta.");
                    return;
                }
                return;
            }

            WarehouseInventory editedInventory = new WarehouseInventory(inventory);

            //arrival
            if (delta > 0)
            {
                // need distribute delta between InStock, Backorder, Preorder.
                if (lineItem.InStockQuantity > 0)
                {
                    var backorderDelta = Math.Min(delta, lineItem.BackorderQuantity - inventory.BackorderQuantity);
                    var preorderdelta = Math.Min(delta, lineItem.PreorderQuantity - inventory.PreorderQuantity);
                    editedInventory.PreorderQuantity += preorderdelta;
                    editedInventory.BackorderQuantity += backorderDelta;
                    editedInventory.InStockQuantity += delta - backorderDelta - preorderdelta;
                } //need distribute delta between Preorder and Backorder
                else if (lineItem.InStockQuantity == 0)
                {
                    if (lineItem.PreorderQuantity > 0)
                    {
                        editedInventory.PreorderQuantity += delta;
                    }
                    else if (lineItem.BackorderQuantity > 0)
                    {
                        editedInventory.BackorderQuantity += delta;
                    }
                }
            }//consumption
            else
            {
                delta = Math.Abs(delta);
                bool inventoryEnabled = inventory.InventoryStatus == InventoryTrackingStatus.Enabled;
                if (inventory.InStockQuantity >= delta + inventory.ReservedQuantity) // Adjust the main inventory
                {
                    //just simply subtract from Instock quantity
                    editedInventory.InStockQuantity -= delta;
                }
                //Instock quantity is larger than delta but smaller than delta and reserved quantity
                else if (inventory.InStockQuantity >= inventory.ReservedQuantity)
                {
                    if (inventoryEnabled)
                    {
                        editedInventory.BackorderQuantity -= delta - (editedInventory.InStockQuantity - inventory.ReservedQuantity);
                        editedInventory.InStockQuantity = inventory.ReservedQuantity;
                    }
                    else
                    {
                        editedInventory.InStockQuantity -= delta;
                    }
                }
                else if (inventory.InStockQuantity > 0) // there still exist items in stock
                {
                    // Calculate difference between currently availbe and backorder
                    var backorderDelta = delta - (inventory.InStockQuantity - (inventoryEnabled ? inventory.ReservedQuantity : 0));

                    // Update inventory
                    if (inventoryEnabled)
                    {
                        editedInventory.InStockQuantity = inventory.ReservedQuantity;
                        editedInventory.BackorderQuantity -= backorderDelta;
                    }
                    else
                    {
                        editedInventory.InStockQuantity -= delta;
                    }
                }
                else if (inventory.InStockQuantity <= 0)
                {
                    // Update inventory
                    editedInventory.InStockQuantity = -delta;

                    if (inventoryEnabled)
                    {
                        if (inventory.PreorderQuantity == 0)
                            editedInventory.BackorderQuantity -= delta;
                        else
                            editedInventory.PreorderQuantity -= delta;
                    }
                }
            }

            ServiceLocator.Current.GetInstance<IWarehouseInventoryService>().Save(editedInventory);
        }
        /// <summary>
        /// Determines whether the specific inventory has enough quantity for the line item.
        /// </summary>
        /// <param name="inventory">The inventory.</param>
        /// <param name="lineItem">The line item.</param>
        /// <returns>
        ///   <c>true</c> if has enough quantity; otherwise, <c>false</c>.
        /// </returns>
        private bool IsEnoughQuantity(IWarehouseInventory inventory, LineItem lineItem)
        {
            //TODO: Consolidate with CheckInventoryActivity
            decimal quantity = lineItem.Quantity;
            if (lineItem.InventoryStatus == (int)InventoryTrackingStatus.Enabled)
            {
                var entry = CatalogContext.Current.GetCatalogEntry(lineItem.CatalogEntryId, CatalogEntryResponseGroup_InfoWithVariations);
                if (inventory == null)
                {
                    // Treat missing as zeroes
                    inventory = new WarehouseInventory();
                    ((WarehouseInventory)inventory).InventoryStatus = InventoryTrackingStatus.Enabled;
                }
                if (entry.StartDate > FrameworkContext.Current.CurrentDateTime)
                {
                    //not allow preorder or preorder is not available
                    if (!inventory.AllowPreorder || inventory.PreorderAvailabilityDate > FrameworkContext.Current.CurrentDateTime)
                    {
                        return false;
                    }
                    //allow preorder but quantity is not enough
                    if (quantity > inventory.PreorderQuantity)
                    {
                        return false;
                    }
                }
                if (inventory.InStockQuantity > 0 && inventory.InStockQuantity >= inventory.ReservedQuantity + quantity)
                {
                    return true;
                }

                //Not enough quantity in stock, check for backorder
                if (!inventory.AllowBackorder)
                {
                    return false;
                }
                //Backorder is not available
                if (inventory.BackorderAvailabilityDate > FrameworkContext.Current.CurrentDateTime)
                {
                    return false;
                }
                //Backorder quantity is not enough
                if (quantity > inventory.InStockQuantity -
                    inventory.ReservedQuantity + inventory.BackorderQuantity)
                {
                    return false;
                }
            }
            return true;
        }