/// <summary>
    /// This is a recursive function. Each scenario is determined by working out 'fulfillment capabilities' starting at a particular supplier and then recurse through all other suppliers for 'unfulfilled' products
    /// </summary>
    /// <param name="purchaseRequirements"></param>
    /// <param name="suppliers"></param>
    /// <returns></returns>
    FulfillmentScenario Optimize(IEnumerable <PurchaseRequirement> purchaseRequirements,
                                 IEnumerable <Supplier> suppliers)
    {
        FulfillmentScenario optimalScenario = null;

        // workout a possible scenario starting from one carrier
        // could be done in paralel with Paralel.For
        foreach (Supplier supplier in suppliers)
        {
            FulfillmentScenario scenario = new FulfillmentScenario();

            FulfillmentCapability fulfillmentCapability = DetermineFulfillmentCapability(supplier, purchaseRequirements);

            scenario.Add(fulfillmentCapability);

            // determine requirements current carrier could not fulfill
            IEnumerable <PurchaseRequirement> pendingRequirements = fulfillmentCapability.ProductsWithInsufficientStock.Concat(fulfillmentCapability.UnrecognizedProducts);

            // recuse through other carriers if current supplier unable to fulfill all requirements
            if (pendingRequirements.Count() > 0)
            {
                FulfillmentScenario residualFulfillmentScenario = Optimize(pendingRequirements, suppliers.Where(s => s.ID != supplier.ID));

                scenario.Adopt(residualFulfillmentScenario);
            }

            // Determine if this scenario is the most optimal and keep track
            if (optimalScenario == null || scenario.TotalCost < optimalScenario.TotalCost)
            {
                optimalScenario = scenario;
            }
        }

        return(optimalScenario);
    }
Exemplo n.º 2
0
    /// <summary>
    /// Adds supplier fulfillment capability to scenario
    /// </summary>
    /// <param name="fulfillmentCapability"></param>
    /// <exception cref="DuplicateScenarioCapabilityException"></exception>
    public void Add(FulfillmentCapability fulfillmentCapability)
    {
        if (_supplierFulfillmentCapabilities.ContainsKey(fulfillmentCapability.Supplier.ID))
        {
            throw new DuplicateScenarioCapabilityException();
        }

        add(fulfillmentCapability);
    }
Exemplo n.º 3
0
    /// <summary>
    /// Update supplier fulfillment capability. Used when adding 'insufficient stock' items to existing supplier fulfillment capability (quote)
    /// </summary>
    /// <param name="fulfillmentCapability"></param>
    public void Replace(FulfillmentCapability fulfillmentCapability)
    {
        if (_supplierFulfillmentCapabilities.TryGetValue(fulfillmentCapability.Supplier.ID,
                                                         out FulfillmentCapability original))
        {
            _totalCost -= original.TotalCost;
            _supplierFulfillmentCapabilities.Remove(fulfillmentCapability.Supplier.ID);
        }

        add(fulfillmentCapability);
    }
Exemplo n.º 4
0
    /// <summary>
    /// Internal function to add fulfillment capability to list and keep track of total cost for scenario
    /// </summary>
    /// <param name="fulfillmentCapability"></param>
    void add(FulfillmentCapability fulfillmentCapability)
    {
        _supplierFulfillmentCapabilities.Add(fulfillmentCapability.Supplier.ID, fulfillmentCapability);

        _totalCost += fulfillmentCapability.TotalCost;
    }