public void RemoveFilledSales()
    {
        List <MakeOrder> filledSales = new List <MakeOrder>();

        // Sales list already sorted by due date. No issue with filling in order.
        foreach (var saleOrder in SalesList)
        {
            var invItem = CurrentInventory.FirstOrDefault(i => saleOrder.MasterID == i.MasterID);
            if (invItem != null)
            {
                // If enough in inventory, fill order and remove from inventory
                if (invItem.TotalPieces >= saleOrder.PiecesToMake)
                {
                    invItem.Units -= (saleOrder.PiecesToMake / invItem.PiecesPerUnit);
                    filledSales.Add(saleOrder);
                }
                else
                {
                    // not enough inventory. Remove what we can from inventory and reduce the sale order needed.
                    saleOrder.PiecesToMake -= invItem.TotalPieces;
                    invItem.Units           = 0;
                }
            }
        }

        foreach (var filledSale in filledSales)
        {
            SalesList.Remove(filledSale);
        }
    }
    private List <MakeOrder> GetPredictions()
    {
        var predictions = new List <MakeOrder>();

        foreach (var master in StaticInventoryTracker.ProductMasterList) //.Where(p => p.MadeIn.Equals("Coating")))
        {
            double pieces = master.PiecesPerUnit * master.TargetSupply;

            StaticFunctions.OutputDebugLine("Creating new prediction for " + master);
            MakeOrder newOrder = new MakeOrder(master.MasterID, pieces)
            {
                DueDay = CurrentDay
            };
            // assume the current day is the due date unless we have inventory data (Could have no inventory)
            // forecast out when the order should be due
            var inv = CurrentInventory.FirstOrDefault(i => i.MasterID == master.MasterID);
            if (inv != null)
            {
                double currentInv  = inv.Units;
                double usedPerDay  = GetAvgUnitsPerDay(master) * 30;
                int    daysTillOut = (int)Math.Floor(currentInv / usedPerDay);
                newOrder.DueDay = CurrentDay.AddDays(daysTillOut);
                StaticFunctions.OutputDebugLine("Found inventory of " + currentInv + " for prediction " + master +
                                                " predicted to run out in " + daysTillOut + " days");
            }
            predictions.Add(newOrder);
        }

        return(predictions);
    }
    /// <summary>
    /// Update schedule generation data with the last scheduled item on the line
    /// </summary>
    /// <param name="item"></param>
    /// <param name="lineIndex"></param>
    public void MarkItemScheduled(ProductMasterItem item, int lineIndex, double unitsMade)
    {
        int pcsMade = (int)(unitsMade * item.PiecesPerUnit);
        var line    = StaticFactoryValuesManager.CoatingLines[lineIndex];

        LastWidth[line]     = item.Width;
        LastThickness[line] = item.Thickness;

        // remove prediction
        var prediction = PredictionList.FirstOrDefault(p => p.MasterID == item.MasterID);

        if (prediction != null)
        {
            PredictionList.Remove(prediction);
        }

        // remove sale
        var sale        = SalesList.FirstOrDefault(s => s.MasterID == item.MasterID);
        int pcsToRemove = pcsMade;

        while (sale != null)
        {
            if (sale.PiecesToMake > pcsToRemove)
            {
                sale.PiecesToMake -= pcsToRemove;
            }
            else
            {
                // made more or equal to the amount for this sale
                pcsToRemove -= sale.PiecesToMake;
                SalesList.Remove(sale);
                sale = SalesList.FirstOrDefault(s => s.MasterID == item.MasterID);
            }
        }

        // update inventory
        var invItem = CurrentInventory.FirstOrDefault(i => i.MasterID == item.MasterID);

        if (invItem != null)
        {
            invItem.Units += unitsMade;
        }
        CurrentWaste += item.Waste * unitsMade;
    }
    private void AddPressProduction(DateTime start, DateTime end)
    {
        // current day already moved
        var production = PressManager.Instance.GetProduction(start, end);

        foreach (var tuple in production)
        {
            // add inventory
            var inv = CurrentInventory.FirstOrDefault(i => i.MasterID == tuple.Item1.MasterID);
            if (inv != null)
            {
                inv.Units += tuple.Item2;
            }
            else
            {
                InventoryItem newInv = new InventoryItem(tuple.Item1, tuple.Item2, "DEALER");
                CurrentInventory.Add(newInv);
            }
        }
    }