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); } } } }
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); } } } }
/// <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); }
/// <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); }
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; } }
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); }
/// <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; }