public void UpdateNextInventory(DateTime day, double change)
        {
            RequirementsDay nextDay;

            if (day.AddDays(1) <= RequirementsHandler.GetLatestDay())
            {
                nextDay            = GetRequirementDay(day.AddDays(1));
                nextDay.Inventory += change;
            }
        }
        public void OutputString(StringBuilder outputString)
        {
            var    product = StaticInventoryTracker.ProductMasterList.FirstOrDefault(x => x.MasterID == MasterItem.MasterID);
            string name    = product?.ProductionCode;

            outputString.Append($"{name}");
            for (int i = 0; i < RequirementsHandler.GetNumDays(); ++i)
            {
                outputString.Append($",{" "}"); // keep columns
            }
            outputString.AppendLine();          // end product line

            StringBuilder grossBuilder    = new StringBuilder();
            StringBuilder onHandBuilder   = new StringBuilder();
            StringBuilder netBuilder      = new StringBuilder();
            StringBuilder purchaseBuilder = new StringBuilder();

            grossBuilder.Append($"{"Gross"},");
            onHandBuilder.Append($"{"OnHand"},");
            netBuilder.Append($"{"Net"},");
            purchaseBuilder.Append($"{"POS"},");

            DateTime current = RequirementsHandler.GetEarliestDay();

            while (current <= RequirementsHandler.GetLatestDay())
            {
                RequirementsDay day = null;
                if (RequiredPieces.ContainsKey(current))
                {
                    day = RequiredPieces[current];
                }
                if (day != null)
                {
                    grossBuilder.Append($"{day.GrossPieces},");
                    onHandBuilder.Append($"{day.Inventory},");
                    netBuilder.Append($"{day.NetRequiredPieces},");
                    purchaseBuilder.Append($"{day.PurchaseOrderPieces},");
                }
                else
                {
                    grossBuilder.Append($"{"0"},");
                    onHandBuilder.Append($"{"0"},");
                    netBuilder.Append($"{"0"},");
                    purchaseBuilder.Append($"{"0"},");
                }
                current = current.AddDays(1);
            }

            outputString.AppendLine(grossBuilder.ToString());
            outputString.AppendLine(onHandBuilder.ToString());
            outputString.AppendLine(netBuilder.ToString());
            outputString.AppendLine(purchaseBuilder.ToString());
        }
        /// <summary>
        /// Factory for product requirements
        /// </summary>
        /// <returns></returns>
        public static ProductRequirements CreateProductRequirements(ProductMasterItem master, Configuration usedConfig)
        {
            var req = new ProductRequirements(master);

            if (usedConfig != null && usedConfig.OutputItems.Any(c => c.MasterID == master.MasterID))
            {
                req.OutPieces = (int)(usedConfig.OutputItems.FirstOrDefault(o => o.MasterID == master.MasterID).Pieces > 0 ? usedConfig.OutputItems.FirstOrDefault(o => o.MasterID == master.MasterID).Pieces : 1);
                req.Input     = usedConfig.InputItems.ToList();
                req.HasConfig = true;
            }
            else
            {
                req.HasConfig = false;
            }
            RequirementsHandler.Register(req);
            return(req);
        }
        /// <summary>
        /// Get the requirements for a day. Creates a new day if there is not one
        /// </summary>
        /// <param name="day"></param>
        /// <returns></returns>
        public RequirementsDay GetRequirementDay(DateTime day)
        {
            var validDay = RequirementsHandler.ValidateDay(day);

            RequirementsDay reqDay = null;

            if (RequiredPieces.ContainsKey(validDay))
            {
                reqDay = RequiredPieces[validDay];
            }
            else
            {
                reqDay = new RequirementsDay(this, validDay);
                RequiredPieces[validDay] = reqDay;
            }

            return(reqDay);
        }
        public void UpdateInventory(DateTime startDay)
        {
            // Validate day
            var validDate = RequirementsHandler.ValidateDay(startDay);

            RequirementsDay reqDay  = null;
            RequirementsDay prevDay = null;

            // add inventory numbers for each day
            reqDay    = GetRequirementDay(validDate);
            validDate = validDate.AddDays(1);

            while (validDate <= RequirementsHandler.GetLatestDay())
            {
                prevDay          = reqDay;
                reqDay           = GetRequirementDay(validDate);
                reqDay.Inventory = prevDay.NextInventoryPieces;
                validDate        = validDate.AddDays(1);
            }
        }
        /// <summary>
        /// Adds a listing to the gross requirements of the item on the date. If another sale is already on that date, the required items are added.
        /// </summary>
        /// <param name="day"></param>
        /// <param name="pieces"></param>
        public void AddSale(DateTime day, double pieces)
        {
            // Validate day
            var validDate = RequirementsHandler.ValidateDay(day);

            // Safe access to dictionary. Creates new entry if needed.
            RequirementsDay requirement = null;

            if (RequiredPieces.ContainsKey(validDate))
            {
                requirement = RequiredPieces[validDate];
                requirement.AddGrossRequirement(pieces);
            }
            else
            {
                requirement = new RequirementsDay(this, validDate);
                RequiredPieces[validDate] = requirement;
                requirement.AddGrossRequirement(pieces);
            }
        }
        /// <summary>
        /// Adds the number of pieces to on hand inventory
        /// </summary>
        /// <param name="day"></param>
        /// <param name="pieces"></param>
        public void AddOnHandInventory(int pieces)
        {
            // Validate day
            var validDate = RequirementsHandler.GetEarliestDay();

            RequirementsDay reqDay  = null;
            RequirementsDay prevDay = null;

            // Safe Access.
            if (RequiredPieces.ContainsKey(validDate))
            {
                reqDay = RequiredPieces[validDate];
                reqDay.AddOnHand(pieces);
            }
            else
            {
                reqDay = new RequirementsDay(this, validDate);
                RequiredPieces[validDate] = reqDay;
                reqDay.Inventory          = pieces;
            }
        }
Example #8
0
        public static void UpdateGross(DateTime POdate, double change, ProductRequirements requirements)
        {
            DateTime grossDate = POdate.AddDays(-RequirementsHandler.LeadTimeDays);

            // get each item required to make this
            foreach (var configItem in requirements.Input)
            {
                var conversionRatio = requirements.OutPieces / configItem.Pieces;
                var prodRequirement = RequirementsHandler.GetRequirements(configItem.MasterID);

                if (prodRequirement == null)
                {
                    Configuration childConfiguration = MachineHandler.Instance.AllConfigurations.FirstOrDefault(conf => conf.CanMake(configItem.MasterItem));
                    prodRequirement = ProductRequirements.CreateProductRequirements(configItem.MasterItem, childConfiguration);
                }

                if (prodRequirement != null)
                {
                    var reqDay = prodRequirement.GetRequirementDay(grossDate);
                    reqDay.GrossPieces += (change * conversionRatio);
                }
            }
        }
        public void SetInventory(double pieces)
        {
            var day = GetRequirementDay(RequirementsHandler.GetEarliestDay());

            day.Inventory = pieces;
        }
        public void GenerateSchedule(GenerationSettings settings)
        {
            GenerationSettings = settings;
            if (GenerationData == null)
            {
                GenerationData = new GenerationData();
            }

            if (!MachineHandler.Instance.IsLoaded)
            {
                MachineHandler.Instance.Load();
            }
            if (!MachineHandler.Instance.IsLoaded)
            {
                MessageBox.Show("Could not load machine config data. Please open the machine config file.");
                if (!MachineHandler.Instance.LoadDialog())
                {
                    MessageBox.Show("Failed to load or canceled. Cannot generate schedule without machine config data. Stopping generation.");
                    return;
                }
            }

            if (StaticInventoryTracker.ProductMasterList.Count == 0)
            {
                MessageBox.Show("No master loaded. Please load master before generating schedule.");
                return;
            }

            if (MachineHandler.Instance.MachineList.Count == 0)
            {
                MessageBox.Show("No machines configured/loaded. Please load or configure the plant machines before generating schedule.");
                return;
            }
            if (!StaticFactoryValuesManager.Loaded)
            {
                StaticFactoryValuesManager.LoadValues();
                if (!StaticFactoryValuesManager.Loaded)
                {
                    MessageBox.Show("No machines configured/loaded. Please load or configure the plant machines before generating schedule.");
                    return;
                }
            }

            try
            {
                CoatingSchedule.CurrentSchedule?.ChildrenLogic.Clear();

                CoatingScheduleWindow scheduleWindow = new CoatingScheduleWindow(schedule);
                scheduleWindow.Show();
                PressScheduleWindow pressScheduleWindow = new PressScheduleWindow();
                pressScheduleWindow.Show();
                PressManager.PlateConfigurations.Clear();
                pressScheduleWindow.UpdateControls();



                // add the first shift to the schedule
                schedule.AddLogic();
                scheduleDay      = (CoatingScheduleDay)schedule.ChildrenLogic[0];
                scheduleDay.Date = GenerationSettings.StartGen;
                scheduleDay.AddLogic();
                scheduleLine = (CoatingScheduleLine)scheduleDay.ChildrenLogic[0];

                GenerationData.InitializeData(RequirementsHandler.GetMakeOrders(GenerationSettings.SalesOutlook),
                                              GenerationSettings);


                // get list of items that can be made in the coating plant
                List <ProductMasterItem> masterItemsAvailableToMake =
                    StaticInventoryTracker.ProductMasterList.Where(
                        m => m.MadeIn.ToUpper().Equals("COATING")).ToList();

                List <ProductMasterItem> unmakeableItems =
                    masterItemsAvailableToMake.Where(
                        item => MachineHandler.Instance.AllConfigurations.All(c => !c.CanMake(item))).ToList();

                if (unmakeableItems.Any())
                {
                    StringBuilder badItems = new StringBuilder();
                    badItems.AppendLine("No configuration found for " + unmakeableItems.Count + " items:");
                    foreach (var productMasterItem in unmakeableItems)
                    {
                        masterItemsAvailableToMake.Remove(productMasterItem);
                        badItems.AppendLine(productMasterItem.ToString());
                    }
                    badItems.AppendLine(
                        "Please note that these items cannot be scheduled in coating until they have configurations that output their masterID.");
                    MessageBox.Show(badItems.ToString());
                }

                // While we have not reached the end of the schedule
                while (GenerationData.CurrentDay <= GenerationSettings.EndGen)
                {
                    int  itemIndex    = 0;
                    bool wasScheduled = false;
                    bool skipShift    = false;

                    // attempt to schedule the highest priority item until the line is full. Also as long as we have not tried every item on this shift
                    while (GenerationData.ScheduledItem.Any(s => !s.Value) && !LineIsFull() && !skipShift && GenerationData.CurrentDay <= GenerationSettings.EndGen)
                    {
                        wasScheduled = false;
                        // try each coating line
                        for (var index = 0; GenerationData.CurrentDay <= GenerationSettings.EndGen && index < StaticFactoryValuesManager.CoatingLines.Count; index++)
                        {
                            var coatingLine = StaticFactoryValuesManager.CoatingLines[index];
                            // Get item with highest priority
                            GenerationData.CreatePriorityList(masterItemsAvailableToMake, coatingLine);

                            if (itemIndex >= GenerationData.PriorityList.Count)
                            {
                                skipShift = true;
                                break;
                            }

                            // Use the next item in the prereq. list as the most favorable.
                            PriorityItem currentItem = GenerationData.GetPriorityItem(itemIndex);

                            if (currentItem.Item.MadeIn.ToUpper().Equals("COATING"))
                            {
                                wasScheduled = ScheduleCoating(currentItem.Item, coatingLine);
                            }
                            else if (currentItem.Item.MadeIn.ToUpper().Equals("PRESS"))
                            {
                                // make the target supply, unless 0, then use 1 and fill.
                                var unitsToMake = currentItem.Item.TargetSupply > 0 ? currentItem.Item.TargetSupply : 1;
                                // should have a sale if scheduling here.
                                var sale =
                                    GenerationData.SalesList.FirstOrDefault(s => s.MasterID == currentItem.Item.MasterID);
                                if (sale != null)
                                {
                                    unitsToMake = sale.PiecesToMake * currentItem.Item.PiecesPerUnit;
                                }
                                SchedulePress(currentItem.Item, unitsToMake);
                                wasScheduled = true; // don't move on due to a press scheduling.
                            }
                            else
                            {
                                // error
                                MessageBox.Show(
                                    "ERROR: Attempted to schedule item that cannot be made in coating or press. Could not make item " + currentItem.Item);
                            }
                            // move to next item

                            // Check if all the lines have been scheduled or if we have tried all the items and none can be scheduled, move on
                            if (GenerationData.ScheduledItem.All(s => s.Value) ||
                                itemIndex >= GenerationData.PriorityList.Count)
                            {
                                AddControl();
                            }
                        }
                        if (!wasScheduled)
                        {
                            // move to the next item, as the highest priority item can't be made currently.
                            itemIndex++;
                        }
                    }

                    // if all items have been run, reset the counter. If there have been no schedulings, then also add a shift
                    if (skipShift || LineIsFull())
                    {
                        AddControl();
                    }
                }
                pressScheduleWindow.UpdateControls();

                while (_errors.Count > 0)
                {
                    MessageBox.Show(_errors.Dequeue());
                }

                MessageBox.Show("Schedule done generating");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }