// todo: function name should be changed to better reflect purpose
 private IEnumerable <ProductStock> DetermineProductSupplierPreference(PurchaseRequirement requirement)
 {
     return
         (requirement.Product.Stock?.Where(
              supplierStock => supplierStock.StockOnHand < requirement.Quantity
              )
          .OrderBy(
              supplier => supplier.Cost
              ));
 }
        private ProductPurchaseOrder FilterPurchaseOrders(PurchaseRequirement purchaseRequirement, ProductPurchaseOrder currentProductOrder, List <PurchaseOrder> filteredOrders)
        {
            // Using recursion to process each purchase order individually
            if (purchaseRequirement.Quantity <= 0 || !currentProductOrder.PurchaseOrders.Any())
            {
                currentProductOrder.PurchaseOrders = filteredOrders;
                return(currentProductOrder);
            }

            // Check is the overall required qty has gone down and update the remaining suppliers qty
            foreach (var purchaseOrder in currentProductOrder.PurchaseOrders.Where(x => x.Quantity > purchaseRequirement.Quantity))
            {
                purchaseOrder.Quantity = purchaseRequirement.Quantity;
            }

            // Order the orders by total price
            currentProductOrder.PurchaseOrders = currentProductOrder.PurchaseOrders.OrderBy(x => x.TotalCost).ToList();

            var currentOrder = currentProductOrder.PurchaseOrders.First();

            // Check if this order can fulfill the requirement qty if not create a purchase order for the stock on hand qty and reduce the overall requirement qty
            if (currentOrder.Quantity == purchaseRequirement.Quantity)
            {
                filteredOrders.Add(currentOrder);

                // Override the old purchase orders with the new filtered orders and return everything
                currentProductOrder.PurchaseOrders = filteredOrders;
                return(currentProductOrder);
            }
            else if (currentOrder.Quantity < purchaseRequirement.Quantity)
            {
                filteredOrders.Add(currentOrder);
                purchaseRequirement.Quantity -= currentOrder.Quantity;
            }
            else if (currentOrder.Quantity > purchaseRequirement.Quantity)
            {
                currentOrder.Quantity = purchaseRequirement.Quantity;
                filteredOrders.Add(currentOrder);

                // Override the old purchase orders with the new filtered orders and return everything
                currentProductOrder.PurchaseOrders = filteredOrders;
                return(currentProductOrder);
            }

            // Remove the processed purchase order from the list once its done
            currentProductOrder.PurchaseOrders.Remove(currentOrder);

            // Call the method again to process the next purchase order
            return(FilterPurchaseOrders(purchaseRequirement, currentProductOrder, filteredOrders));
        }
        private ProductPurchaseOrder CreatePurchaseOrders(PurchaseRequirement purchaseRequirement, ProductPurchaseOrder currentProductOrder)
        {
            // Using recursion to process each purchase order individually
            if (!purchaseRequirement.Product.Stock.Any())
            {
                return(FilterPurchaseOrders(purchaseRequirement, currentProductOrder, new List <PurchaseOrder>()));
            }

            var stock = purchaseRequirement.Product.Stock.First();

            // Check if the stock on hand per supplier can fulfill the requirement qty
            if (stock.StockOnHand >= purchaseRequirement.Quantity)
            {
                currentProductOrder.PurchaseOrders.Add(new PurchaseOrder
                {
                    Supplier     = stock.Supplier,
                    Quantity     = purchaseRequirement.Quantity,
                    ProductCost  = stock.Cost,
                    ShippingCost = stock.Supplier.ShippingCost,
                    ShippingCostMinOrderValue = stock.Supplier.ShippingCostMinOrderValue,
                    ShippingCostMaxOrderValue = stock.Supplier.ShippingCostMaxOrderValue,
                    Type = purchaseRequirement.Product.Type
                });
            }
            else if (stock.StockOnHand > 0)
            {
                currentProductOrder.PurchaseOrders.Add(new PurchaseOrder
                {
                    Supplier     = stock.Supplier,
                    Quantity     = stock.StockOnHand,
                    ProductCost  = stock.Cost,
                    ShippingCost = stock.Supplier.ShippingCost,
                    ShippingCostMinOrderValue = stock.Supplier.ShippingCostMinOrderValue,
                    ShippingCostMaxOrderValue = stock.Supplier.ShippingCostMaxOrderValue,
                    Type = purchaseRequirement.Product.Type
                });
            }

            // Remove the processed purchase order from the list once its done
            purchaseRequirement.Product.Stock.Remove(stock);

            // Call the method again to process the next purchase order
            return(CreatePurchaseOrders(purchaseRequirement, currentProductOrder));
        }
Exemple #4
0
    public PurchaseRequirement GetRequirement(ItemDetails otherItem)
    {
        PurchaseRequirement req = purchaceRequirements.Find(x => { return(x.type == otherItem.type); });

        return(req);
    }
        public IEnumerable <PurchaseOrderItem> ProducePurchaseOrderItem(List <SupplierFulfillmentOptions> fulfillmentOptions, PurchaseRequirement purchaseRequirement)
        {
            var quantityNeeded = purchaseRequirement.Quantity;

            if (fulfillmentOptions.Count() == 0)
            {
                yield return(new PurchaseOrderItem
                {
                    PurchaseRequirement = purchaseRequirement,
                    QuantityFulfilled = quantityNeeded,
                    UnableToFulfill = true,
                    CostToFulfill = 0
                });
            }

            foreach (var option in fulfillmentOptions)
            {
                if (_stockCalculatorService.QuantityLeftToFulfill(quantityNeeded, (int)option.StockAvailableToSupply) == 0)
                {
                    yield return(new PurchaseOrderItem
                    {
                        PurchaseRequirement = purchaseRequirement,
                        QuantityFulfilled = quantityNeeded,
                        SupplierToFulfull = option.Supplier,
                        CostToFulfill = (option.SupplierCost * quantityNeeded) + option.ShippingCost
                    });

                    yield break;
                }

                quantityNeeded -= (int)option.StockAvailableToSupply;
                yield return(new PurchaseOrderItem
                {
                    PurchaseRequirement = purchaseRequirement,
                    QuantityFulfilled = (int)option.StockAvailableToSupply,
                    SupplierToFulfull = option.Supplier,
                    CostToFulfill = (option.SupplierCost * option.StockAvailableToSupply) + option.ShippingCost
                });
            }
        }