Esempio n. 1
0
        public void OnUpdated(Shipment entity)
        {
            var orderItems = entity.ShipmentItems.Select(x => x.OrderItem).ToList();

            foreach (var orderItem in orderItems)
            {
                _purchaseAccountant.EvaluateOrderStatus(orderItem.Order);
            }

            //if the shipment status is InTransit/Returned, that means we should update the inventory, as the item has been shipped/returned
            if (entity.ShipmentStatus == ShipmentStatus.InTransit || entity.ShipmentStatus == ShipmentStatus.Returned)
            {
                var warehouseId       = entity.WarehouseId;
                var shippedProductIds = orderItems.Select(x => x.ProductId).ToList();
                var inventories       = _warehouseInventoryService.GetByProducts(shippedProductIds, warehouseId).ToList();
                foreach (var shippedItem in entity.ShipmentItems)
                {
                    var quantityShipped  = shippedItem.Quantity;
                    var shippedProductId = shippedItem.OrderItem.ProductId;
                    var variantId        = shippedItem.OrderItem.ProductVariantId;
                    var inventory        = shippedItem.OrderItem.ProductVariantId > 0
                        ? inventories.FirstOrDefault(x => x.ProductVariantId == variantId)
                        : inventories.FirstOrDefault(x => x.ProductId == shippedProductId);
                    if (inventory == null)
                    {
                        continue; //weird it's not there. but we can't do anything for this. something is wrong. this shouldn't have hit
                    }
                    if (entity.ShipmentStatus == ShipmentStatus.InTransit)
                    {
                        inventory.ReservedQuantity -= quantityShipped;
                        inventory.TotalQuantity    -= quantityShipped;
                    }
                    else
                    {
                        inventory.TotalQuantity += quantityShipped;
                    }
                    _warehouseInventoryService.Update(inventory);
                }
            }

            //update shipment history
            //get the history
            var shipmentHistoryItems = _shipmentStatusHistoryService.Get(x => x.ShipmentId == entity.Id).OrderByDescending(x => x.Id).ToList();

            //if the current status is already there as the latest one, no need to do anything,
            if (shipmentHistoryItems.Any() && shipmentHistoryItems.First().ShipmentStatus ==
                entity.ShipmentStatus)
            {
                return;
            }
            //we'll add this to the history now
            var shipmentHistory = new ShipmentHistory()
            {
                CreatedOn      = DateTime.UtcNow,
                ShipmentStatus = entity.ShipmentStatus,
                ShipmentId     = entity.Id
            };

            _shipmentStatusHistoryService.Insert(shipmentHistory);
        }
Esempio n. 2
0
        /// <summary>
        /// Gets order fulfillments based on the following rules.
        /// - If all the products in an order are present in multiple warehouses, select a warehouse that has lowest order and can fulfill all the products
        /// - If all the products in an order are present in only one of the warehouses, select that warehouse irrespective of order
        /// - If some products are present in one warehouse and others are present in other warehouse, apply warehouse selection based on their order for each product.
        /// </summary>
        private IList <OrderFulfillment> GetAutoOrderFulfillments(Order order, OrderFulfillmentType orderFulfillmentType)
        {
            //the product ids for this order
            var productIds           = order.OrderItems.Select(x => x.ProductId).Distinct().ToList();
            var warehouseInventories = _warehouseInventoryService.GetByProducts(productIds).ToList();
            var availableWarehouses  = warehouseInventories.Select(x => x.Warehouse).Distinct().OrderBy(x => x.DisplayOrder).ToList();
            var fulfillments         = new List <OrderFulfillment>();

            foreach (var warehouse in availableWarehouses)
            {
                var wInventories          = warehouseInventories.Where(x => x.WarehouseId == warehouse.Id).ToList();
                var warehouseCheckSuccess = true;
                foreach (var orderItem in order.OrderItems)
                {
                    if (fulfillments.Any(x => x.OrderItemId == orderItem.Id && x.Quantity == orderItem.Quantity))
                    {
                        continue; //do we already have fulfilled this item, yes and so skip the item now
                    }
                    WarehouseInventory warehouseInventory;
                    if (orderItem.ProductVariantId > 0)
                    {
                        warehouseInventory = wInventories.FirstOrDefault(x =>
                                                                         x.ProductVariantId == orderItem.ProductVariantId &&
                                                                         x.AvailableQuantity >= orderItem.Quantity);

                        //do we have any inventory for this variant in this warehouse, if not, we don't need to proceed
                        if (warehouseInventory == null)
                        {
                            if (orderFulfillmentType == OrderFulfillmentType.WholeFromSingleWarehouse)
                            {
                                warehouseCheckSuccess = false;
                                break;
                            }
                        }
                    }
                    else
                    {
                        warehouseInventory = wInventories.FirstOrDefault(x =>
                                                                         x.ProductId == orderItem.ProductId &&
                                                                         x.AvailableQuantity >= orderItem.Quantity);
                        //do we have any inventory for this product in this warehouse, if not, we don't need to proceed
                        if (warehouseInventory == null)
                        {
                            if (orderFulfillmentType == OrderFulfillmentType.WholeFromSingleWarehouse)
                            {
                                warehouseCheckSuccess = false;
                                break;
                            }
                        }
                    }
                    //add only if fulfillment can be done
                    if (warehouseInventory?.AvailableQuantity >= orderItem.Quantity)
                    {
                        fulfillments.Add(new OrderFulfillment()
                        {
                            Warehouse          = warehouse,
                            Order              = order,
                            OrderItem          = orderItem,
                            OrderId            = order.Id,
                            OrderItemId        = orderItem.Id,
                            Quantity           = orderItem.Quantity,
                            WarehouseId        = warehouse.Id,
                            Verified           = false,
                            WarehouseInventory = warehouseInventory
                        });
                    }
                    else
                    {
                        warehouseCheckSuccess = false;
                        break;
                    }
                }

                if (!warehouseCheckSuccess)
                {
                    if (orderFulfillmentType == OrderFulfillmentType.WholeFromSingleWarehouse)
                    {
                        fulfillments.Clear(); //avoid the fulfillment by this warehouse
                    }
                }
                else
                {
                    return(fulfillments); //we got the warehouse, so return
                }
            }

            return(fulfillments);
        }