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; } }