/// <summary> /// Checks the warehouse assigned to an order line item to determine if it is a valid shipment fulfillment location /// (i.e. will ship items to a customer address) /// </summary> /// <param name="warehouse">The intended source warehouse.</param> /// <param name="lineItem">The order line item.</param> /// <param name="checkInventory">Set to false to override the check against current stock.</param> /// <returns> /// true if the warehouse can ship the item and a pickup method is not already chosen; otherwise false /// (i.e. the warehouse cannot ship the item, or the line item has an in-store pickup method selected). /// </returns> private bool IsValidFulfillment(IWarehouse warehouse, LineItem lineItem, CheckInventoryMode checkInventory) { if (warehouse == null || lineItem == null) { throw new ArgumentNullException(); } var shippingMethod = ShippingManager.GetShippingMethod(lineItem.ShippingMethodId).ShippingMethod.FirstOrDefault(); if (shippingMethod != null && ShippingManager.IsHandoffShippingMethod(shippingMethod.Name)) { return(false); } var lineApplicationId = lineItem.Parent.Parent.ApplicationId; if ((warehouse.ApplicationId != lineApplicationId) || !warehouse.IsActive || !warehouse.IsFulfillmentCenter) { return(false); } if (checkInventory == CheckInventoryMode.Ignore) { return(true); } var catalogKey = new Mediachase.Commerce.Catalog.CatalogKey(lineItem.Parent.Parent.ApplicationId, lineItem.CatalogEntryId); var inventory = InventoryService.Service.Get(catalogKey, warehouse); return(IsEnoughQuantity(inventory, lineItem)); }
/// <summary> /// Attempts to pick the correct source warehouse that can ship an order line item to a customer location /// </summary> /// <param name="lineItem">The item being processed.</param> /// <param name="checkInventory">Set to false to override the check against current stock.</param> /// <returns>the assignable warehouse if one exists; otherwise null.</returns> /// <remarks> /// This represents the main logic for fulfilling orders via shipments. Custom implementations (e.g. multi-warehouse fulfillment) /// should be focused here. /// </remarks> private IWarehouse GetFulfillmentWarehouse(LineItem lineItem, CheckInventoryMode checkInventory) { CheckMultiWarehouse(); var applicationId = lineItem.Parent.Parent.ApplicationId; var defaultWarehouse = WarehouseRepository.Service.List().Where(w => (w.ApplicationId == applicationId) && w.IsActive && w.IsFulfillmentCenter) .SingleOrDefault(); if (defaultWarehouse == null) { return(null); } if (IsValidFulfillment(defaultWarehouse, lineItem, checkInventory)) { return(defaultWarehouse); } return(null); }
/// <summary> /// Checks the warehouse assigned to an order line item to determine if it is a valid pickup location /// </summary> /// <param name="orderGroup">The order group parent for the line item.</param> /// <param name="lineItem">The item being processed.</param> /// <param name="checkInventory">Set to false to override the check against current stock.</param> /// <returns>true if the assigned warehouse is an active pickup location; otherwise false.</returns> /// <remarks> /// With no shipping method selected, this can only be a "could be valid" check rather than an /// explicit "is valid", and thus this can report positives that will eventually be processed for /// delivery instead of pickups. /// </remarks> private bool IsValidPickupFromLineItem(OrderGroup orderGroup, LineItem lineItem, CheckInventoryMode checkInventory) { if (string.IsNullOrEmpty(lineItem.WarehouseCode)) { return(false); } var lineApplicationId = lineItem.Parent.Parent.ApplicationId; var lineItemWarehouse = WarehouseRepository.Service.List() .Where(w => w.ApplicationId == lineApplicationId && w.Code == lineItem.WarehouseCode && w.IsActive && (w.IsPickupLocation || w.IsDeliveryLocation) // TODO: Validate that should be both rather than just pickup ) .FirstOrDefault(); if (lineItemWarehouse == null) { return(false); } // In case lineItem shipping method is InStorePickup , check if lineItemWarehouse is pickup location // If not, return false. if (lineItem.ShippingMethodName == ShippingManager.PickupShippingMethodName && !lineItemWarehouse.IsPickupLocation) { return(false); } if (checkInventory == CheckInventoryMode.Ignore) { return(true); } var catalogKey = new Mediachase.Commerce.Catalog.CatalogKey(lineApplicationId, lineItem.CatalogEntryId); var pickupInventory = InventoryService.Service.List(catalogKey).FirstOrDefault(i => i.WarehouseCode.Equals(lineItem.WarehouseCode, StringComparison.OrdinalIgnoreCase)); return(IsEnoughQuantity(pickupInventory, lineItem)); }
/// <summary> /// Validates that an order line item has a valid in-store pickup set as its shipment method /// </summary> /// <param name="orderGroup">The order group parent for the line item.</param> /// <param name="lineItem">The item being processed.</param> /// <param name="checkInventory">Set to false to override the check against current stock.</param> /// <returns>true if the shipment is set and is a valid pickup; otherwise false.</returns> /// <remarks> /// In the standard workflow process the inventory is checked in a later step by the CheckInventoryActivity, so it may be /// useful to override the inventory processing here. It also allows us to distinguish between insufficient inventory and /// an error in the warehouse configuration. /// </remarks> private bool IsValidPickupFromShipment(OrderGroup orderGroup, LineItem lineItem, CheckInventoryMode checkInventory) { return(GetValidPickupFromShipment(orderGroup, lineItem, checkInventory) != null); }
/// <summary> /// Matches the shipment information attached to an order line item to against the pickup warehouses to find the source warehouse, or /// validates the assigned warehouse if one is set already /// </summary> /// <param name="orderGroup">The order group parent for the line item.</param> /// <param name="lineItem">The item being processed.</param> /// <param name="checkInventory">Set to false to override the check against current stock.</param> /// <returns>the matching warehouse if all of the following are true: the shipment is set, is a valid active pickup location, and matches the line /// item warehouse (if set); otherwise null.</returns> private IWarehouse GetValidPickupFromShipment(OrderGroup orderGroup, LineItem lineItem, CheckInventoryMode checkInventory) { var shippingMethod = ShippingManager.GetShippingMethod(lineItem.ShippingMethodId).ShippingMethod.FirstOrDefault(); if (shippingMethod == null || !ShippingManager.IsHandoffShippingMethod(shippingMethod.Name)) { return(null); } var pickupAddress = orderGroup.OrderAddresses.ToArray().FirstOrDefault(x => x.Name == lineItem.ShippingAddressId); if (pickupAddress == null) { return(null); } var pickupWarehouse = ShippingManager.GetHandoffLocationFromAddressName(pickupAddress.Name); if (pickupWarehouse == null || (!string.IsNullOrEmpty(lineItem.WarehouseCode) && (pickupWarehouse.Code != lineItem.WarehouseCode))) { return(null); } var lineApplicationId = lineItem.Parent.Parent.ApplicationId; if ((pickupWarehouse.ApplicationId != lineApplicationId) || !pickupWarehouse.IsActive || (!pickupWarehouse.IsPickupLocation && !pickupWarehouse.IsDeliveryLocation)) { return(null); } if (checkInventory == CheckInventoryMode.Check) { var catalogKey = new Mediachase.Commerce.Catalog.CatalogKey(lineApplicationId, lineItem.CatalogEntryId); var pickupInventory = InventoryService.Service.Get(catalogKey, pickupWarehouse); if (pickupInventory == null) { return(null); } if (!IsEnoughQuantity(pickupInventory, lineItem)) { pickupWarehouse = null; } } return(pickupWarehouse); }
/// <summary> /// Checks the warehouse assigned to an order line item to determine if it is a valid pickup location /// </summary> /// <param name="orderGroup">The order group parent for the line item.</param> /// <param name="lineItem">The item being processed.</param> /// <param name="checkInventory">Set to false to override the check against current stock.</param> /// <returns>true if the assigned warehouse is an active pickup location; otherwise false.</returns> /// <remarks> /// With no shipping method selected, this can only be a "could be valid" check rather than an /// explicit "is valid", and thus this can report positives that will eventually be processed for /// delivery instead of pickups. /// </remarks> private bool IsValidPickupFromLineItem(OrderGroup orderGroup, LineItem lineItem, CheckInventoryMode checkInventory) { if (string.IsNullOrEmpty(lineItem.WarehouseCode)) { return false; } var lineApplicationId = lineItem.Parent.Parent.ApplicationId; var lineItemWarehouse = WarehouseRepository.Service.List() .Where(w => w.ApplicationId == lineApplicationId && w.Code == lineItem.WarehouseCode && w.IsActive && (w.IsPickupLocation || w.IsDeliveryLocation) // TODO: Validate that should be both rather than just pickup ) .FirstOrDefault(); if (lineItemWarehouse == null) { return false; } // In case lineItem shipping method is InStorePickup , check if lineItemWarehouse is pickup location // If not, return false. if (lineItem.ShippingMethodName == ShippingManager.PickupShippingMethodName && !lineItemWarehouse.IsPickupLocation) { return false; } if (checkInventory == CheckInventoryMode.Ignore) { return true; } var catalogKey = new Mediachase.Commerce.Catalog.CatalogKey(lineApplicationId, lineItem.CatalogEntryId); var pickupInventory = InventoryService.Service.List(catalogKey).FirstOrDefault(i=>i.WarehouseCode.Equals(lineItem.WarehouseCode, StringComparison.OrdinalIgnoreCase)); return IsEnoughQuantity(pickupInventory, lineItem); }
/// <summary> /// Validates that an order line item has a valid in-store pickup set as its shipment method /// </summary> /// <param name="orderGroup">The order group parent for the line item.</param> /// <param name="lineItem">The item being processed.</param> /// <param name="checkInventory">Set to false to override the check against current stock.</param> /// <returns>true if the shipment is set and is a valid pickup; otherwise false.</returns> /// <remarks> /// In the standard workflow process the inventory is checked in a later step by the CheckInventoryActivity, so it may be /// useful to override the inventory processing here. It also allows us to distinguish between insufficient inventory and /// an error in the warehouse configuration. /// </remarks> private bool IsValidPickupFromShipment(OrderGroup orderGroup, LineItem lineItem, CheckInventoryMode checkInventory) { return (GetValidPickupFromShipment(orderGroup, lineItem, checkInventory) != null); }
/// <summary> /// Checks the warehouse assigned to an order line item to determine if it is a valid shipment fulfillment location /// (i.e. will ship items to a customer address) /// </summary> /// <param name="warehouse">The intended source warehouse.</param> /// <param name="lineItem">The order line item.</param> /// <param name="checkInventory">Set to false to override the check against current stock.</param> /// <returns> /// true if the warehouse can ship the item and a pickup method is not already chosen; otherwise false /// (i.e. the warehouse cannot ship the item, or the line item has an in-store pickup method selected). /// </returns> private bool IsValidFulfillment(IWarehouse warehouse, LineItem lineItem, CheckInventoryMode checkInventory) { if (warehouse == null || lineItem == null) { throw new ArgumentNullException(); } var shippingMethod = ShippingManager.GetShippingMethod(lineItem.ShippingMethodId).ShippingMethod.FirstOrDefault(); if (shippingMethod != null && ShippingManager.IsHandoffShippingMethod(shippingMethod.Name)) { return false; } var lineApplicationId = lineItem.Parent.Parent.ApplicationId; if ((warehouse.ApplicationId != lineApplicationId) || !warehouse.IsActive || !warehouse.IsFulfillmentCenter) { return false; } if (checkInventory == CheckInventoryMode.Ignore) { return true; } var catalogKey = new Mediachase.Commerce.Catalog.CatalogKey(lineItem.Parent.Parent.ApplicationId, lineItem.CatalogEntryId); var inventory = InventoryService.Service.Get(catalogKey, warehouse); return IsEnoughQuantity(inventory, lineItem); }
/// <summary> /// Matches the shipment information attached to an order line item to against the pickup warehouses to find the source warehouse, or /// validates the assigned warehouse if one is set already /// </summary> /// <param name="orderGroup">The order group parent for the line item.</param> /// <param name="lineItem">The item being processed.</param> /// <param name="checkInventory">Set to false to override the check against current stock.</param> /// <returns>the matching warehouse if all of the following are true: the shipment is set, is a valid active pickup location, and matches the line /// item warehouse (if set); otherwise null.</returns> private IWarehouse GetValidPickupFromShipment(OrderGroup orderGroup, LineItem lineItem, CheckInventoryMode checkInventory) { var shippingMethod = ShippingManager.GetShippingMethod(lineItem.ShippingMethodId).ShippingMethod.FirstOrDefault(); if (shippingMethod == null || !ShippingManager.IsHandoffShippingMethod(shippingMethod.Name)) { return null; } var pickupAddress = orderGroup.OrderAddresses.ToArray().FirstOrDefault(x => x.Name == lineItem.ShippingAddressId); if (pickupAddress == null) { return null; } var pickupWarehouse = ShippingManager.GetHandoffLocationFromAddressName(pickupAddress.Name); if (pickupWarehouse == null || (!string.IsNullOrEmpty(lineItem.WarehouseCode) && (pickupWarehouse.Code != lineItem.WarehouseCode))) { return null; } var lineApplicationId = lineItem.Parent.Parent.ApplicationId; if ((pickupWarehouse.ApplicationId != lineApplicationId) || !pickupWarehouse.IsActive || (!pickupWarehouse.IsPickupLocation && !pickupWarehouse.IsDeliveryLocation)) { return null; } if (checkInventory == CheckInventoryMode.Check) { var catalogKey = new Mediachase.Commerce.Catalog.CatalogKey(lineApplicationId, lineItem.CatalogEntryId); var pickupInventory = InventoryService.Service.Get(catalogKey, pickupWarehouse); if (pickupInventory == null) { return null; } if (!IsEnoughQuantity(pickupInventory, lineItem)) { pickupWarehouse = null; } } return pickupWarehouse; }
/// <summary> /// Attempts to pick the correct source warehouse that can ship an order line item to a customer location /// </summary> /// <param name="lineItem">The item being processed.</param> /// <param name="checkInventory">Set to false to override the check against current stock.</param> /// <returns>the assignable warehouse if one exists; otherwise null.</returns> /// <remarks> /// This represents the main logic for fulfilling orders via shipments. Custom implementations (e.g. multi-warehouse fulfillment) /// should be focused here. /// </remarks> private IWarehouse GetFulfillmentWarehouse(LineItem lineItem, CheckInventoryMode checkInventory) { CheckMultiWarehouse(); var applicationId = lineItem.Parent.Parent.ApplicationId; var foo = WarehouseRepository.Service.List(); var defaultWarehouse = WarehouseRepository.Service.List().Where(w => (w.ApplicationId == applicationId) && w.IsActive && w.IsFulfillmentCenter) .SingleOrDefault(); if (defaultWarehouse == null) { return null; } if (IsValidFulfillment(defaultWarehouse, lineItem, checkInventory)) { return defaultWarehouse; } return null; }
/// <summary> /// Attempts to pick the correct source warehouse that can ship an order line item to a customer location /// </summary> /// <param name="lineItem">The item being processed.</param> /// <param name="checkInventory">Set to false to override the check against current stock.</param> /// <returns>the assignable warehouse if one exists; otherwise null.</returns> /// <remarks> /// This represents the main logic for fulfilling orders via shipments. Custom implementations (e.g. multi-warehouse fulfillment) /// should be focused here. /// </remarks> private IWarehouse GetFulfillmentWarehouse(LineItem lineItem, CheckInventoryMode checkInventory) { var defaultWarehouse = CheckMultiWarehouse(); if (defaultWarehouse == null) { return null; } if (IsValidFulfillment(defaultWarehouse, lineItem, checkInventory)) { return defaultWarehouse; } return null; }
/// <summary> /// Checks the warehouse assigned to an order line item to determine if it is a valid pickup location /// </summary> /// <param name="orderGroup">The order group parent for the line item.</param> /// <param name="lineItem">The item being processed.</param> /// <param name="checkInventory">Set to false to override the check against current stock.</param> /// <returns>true if the assigned warehouse is an active pickup location; otherwise false.</returns> /// <remarks> /// With no shipping method selected, this can only be a "could be valid" check rather than an /// explicit "is valid", and thus this can report positives that will eventually be processed for /// delivery instead of pickups. /// </remarks> private bool IsValidPickupFromLineItem(OrderGroup orderGroup, LineItem lineItem, CheckInventoryMode checkInventory) { if (string.IsNullOrEmpty(lineItem.WarehouseCode)) { return false; } var lineApplicationId = lineItem.Parent.Parent.ApplicationId; var lineItemWarehouse = WarehouseRepository.List() .Where(w => w.ApplicationId == lineApplicationId && w.Code == lineItem.WarehouseCode && w.IsActive && (w.IsPickupLocation || w.IsDeliveryLocation) // TODO: Validate that should be both rather than just pickup ) .FirstOrDefault(); if (lineItemWarehouse == null) { return false; } // In case lineItem shipping method is InStorePickup , check if lineItemWarehouse is pickup location // If not, return false. if (lineItem.ShippingMethodName == ShippingManager.PickupShippingMethodName && !lineItemWarehouse.IsPickupLocation) { return false; } if (checkInventory == CheckInventoryMode.Ignore) { return true; } return IsEnoughQuantity(lineItem, lineItemWarehouse.Code); }