SchedulePanel.xaml.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Linq;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Media;
  8. using System.Windows.Media.Imaging;
  9. using System.Windows.Shapes;
  10. using Comal.Classes;
  11. using InABox.Clients;
  12. using InABox.Configuration;
  13. using InABox.Core;
  14. using InABox.WPF;
  15. namespace PRSDesktop
  16. {
  17. /// <summary>
  18. /// Interaction logic for SchedulePanel.xaml
  19. /// </summary>
  20. public partial class SchedulePanel : UserControl, IPanel<ScheduleBooking>
  21. {
  22. private List<ScheduleBooking> _bookings = new();
  23. //Dictionary<String,List<Tuple<String,Guid>>> Groups = new Dictionary<string,List<Tuple<String, Guid>>>();
  24. private string CurrentFactory = "";
  25. //private void DoChangeGroup(PanelAction obj)
  26. //{
  27. // Group = obj.Caption;
  28. // Refresh();
  29. //}
  30. private readonly Random generator = new(Guid.NewGuid().GetHashCode());
  31. private FactorySetup settings;
  32. private Dictionary<Guid, string> StepNames = new();
  33. public ObservableCollection<Tuple<string, BitmapImage>> FactoryList { get; private set; }
  34. public bool IsReady { get; set; }
  35. public Dictionary<string, object[]> Selected()
  36. {
  37. return new Dictionary<string, object[]> { { typeof(ScheduleBooking).EntityName(), new CoreRow[] { } } };
  38. }
  39. public void Setup()
  40. {
  41. settings = new GlobalConfiguration<FactorySetup>().Load();
  42. Filter<Document> imageFilter = null;
  43. foreach (var group in settings.Groups)
  44. if (group.Thumbnail.ID != Guid.Empty)
  45. {
  46. var newfilter = new Filter<Document>(x => x.ID).IsEqualTo(group.Thumbnail.ID);
  47. if (imageFilter == null)
  48. imageFilter = newfilter;
  49. else
  50. imageFilter.Ors.Add(newfilter);
  51. }
  52. var Images = new Client<Document>().Load(imageFilter);
  53. FactoryList = new ObservableCollection<Tuple<string, BitmapImage>>();
  54. FactoryList.Add(new Tuple<string, BitmapImage>("All Sections", PRSDesktop.Resources.factory.AsBitmapImage()));
  55. //FactorySetup settings = new GlobalConfiguration<FactorySetup>().Load();
  56. foreach (var group in settings.Groups)
  57. {
  58. var groups = new List<string>();
  59. if (!FactoryList.Any(x => x.Item1.Equals(group.Group)))
  60. {
  61. var bOK = false;
  62. foreach (var section in settings.Sections)
  63. if (section.Group.Equals(group.Group) && !section.Shared)
  64. bOK = true;
  65. if (bOK)
  66. {
  67. var image = Images.FirstOrDefault(x => x.ID.Equals(group.Thumbnail.ID));
  68. //byte[] data = image != null ? image.Data : null;
  69. BitmapImage img = null;
  70. if (image != null && image.Data != null && image.Data.Length > 0)
  71. {
  72. img = new BitmapImage();
  73. img.LoadImage(image.Data);
  74. }
  75. else
  76. {
  77. img = PRSDesktop.Resources.factory.AsBitmapImage();
  78. }
  79. FactoryList.Add(new Tuple<string, BitmapImage>(group.Group, img));
  80. }
  81. }
  82. }
  83. Factories.ItemsSource = FactoryList;
  84. Factories.SelectedIndex = Factories.Items.Count > 1 ? 1 : 0;
  85. //foreach (FactorySection section in settings.Sections)
  86. //{
  87. // StepNames[section.ID] = section.Name;
  88. // if (!section.Shared)
  89. // {
  90. // String group = String.IsNullOrEmpty(section.Group) ? "General" : section.Group;
  91. // if (!Groups.ContainsKey(group))
  92. // Groups[group] = new List<Tuple<String,Guid>>();
  93. // Groups[group].Add(new Tuple<String,Guid>(section.Name,section.ID));
  94. // }
  95. //}
  96. //if (Groups.Count > 0)
  97. // CurrentFactory = Groups.Keys.First();
  98. Refresh();
  99. }
  100. public void Shutdown()
  101. {
  102. }
  103. public void CreateToolbarButtons(IPanelHost host)
  104. {
  105. host.CreatePanelAction(new PanelAction
  106. { Caption = "Recalculate", OnExecute = DoRecalculateSchedule, Image = PRSDesktop.Resources.clock });
  107. //foreach (String group in Groups.Keys)
  108. // host.CreateToolbarButton(new PanelAction() { Caption = group, OnExecute = DoChangeGroup, Image = PRSDesktop.Resources.shared });
  109. }
  110. public event DataModelUpdateEvent OnUpdateDataModel;
  111. public void Refresh()
  112. {
  113. // ResizeIntervals(Schedule.ActualHeight);
  114. // //Client<Job> jobclient = new Client<Job>();
  115. // //Job[] jobs = jobclient.Load();
  116. // Schedule.Appointments.Clear();
  117. //_bookings.Clear();
  118. //ResourceType restyp = new ResourceType() { TypeName = "Stations" };
  119. //var sections = settings.Sections.Where(x => !x.Shared && (String.IsNullOrEmpty(CurrentFactory) || x.Group.Equals(CurrentFactory)));
  120. //foreach (var section in sections)
  121. //{
  122. // restyp.ResourceCollection.Add(new Resource() { DisplayName = section.Name, ResourceName = section.ID.ToString() });
  123. //}
  124. //Schedule.ScheduleResourceTypeCollection.Clear();
  125. //Schedule.ScheduleResourceTypeCollection.Add(restyp);
  126. //Schedule.DayViewColumnCount = restyp.ResourceCollection.Count;
  127. // CoreTable setouts = new Client<ManufacturingPacket>().Query(new Filter<ManufacturingPacket>(x => x.Completed).IsEqualTo(DateTime.MinValue));
  128. //if (setouts.Rows.Count() > 0)
  129. //{
  130. // Comal.Classes.Calendar calendar = new Client<Comal.Classes.Calendar>().Load(new Filter<Comal.Classes.Calendar>(x => x.IsActive).IsEqualTo(true)).FirstOrDefault();
  131. // if (calendar != null)
  132. // {
  133. // foreach (CalendarBooking booking in calendar.Bookings)
  134. // {
  135. // CoreRow packet = setouts.Rows.Where(x => x.Get<Guid>("ID").Equals(booking.Packet)).FirstOrDefault();
  136. // if (packet != null)
  137. // {
  138. // ScheduleBooking appt = new ScheduleBooking()
  139. // {
  140. // SetoutID = packet.Get<ManufacturingPacket, Guid>(x=>x.SetoutLink.ID),
  141. // StartTime = booking.Start,
  142. // EndTime = booking.End,
  143. // Subject = packet.Get<ManufacturingPacket, String>(x=>x.SetoutLink.Description),
  144. // //SetoutNumber = packet.Get<ManufacturingPacket, String>(x => x.Se),
  145. // Description = String.Format("{0} {1}", packet.Get<ManufacturingPacket, String>(x => x.SetoutLink.Number), packet.Get<ManufacturingPacket, String>(x => x.Serial)),
  146. // AllDay = false
  147. // };
  148. // if (booking.End > packet.Get<DateTime>("DueDate"))
  149. // {
  150. // appt.AppointmentBackground = CreateBrush(Colors.Firebrick, booking.IsShared);
  151. // appt.AppointmentForeground = CreateBrush(Colors.Yellow, false);
  152. // }
  153. // else if (booking.End > packet.Get<DateTime>("DueDate").Subtract(new TimeSpan(1, 0, 0, 0)))
  154. // {
  155. // appt.AppointmentBackground = CreateBrush(Colors.Orange, booking.IsShared);
  156. // appt.AppointmentForeground = CreateBrush(Colors.Black, false);
  157. // }
  158. // else
  159. // {
  160. // appt.AppointmentBackground = CreateBrush(Colors.LightGreen, booking.IsShared);
  161. // appt.AppointmentForeground = CreateBrush(Colors.Black, false);
  162. // }
  163. // appt.ResourceCollection.Add(new Resource() { ResourceName = booking.Station.ToString(), TypeName = "Stations" });
  164. // _bookings.Add(appt);
  165. // Schedule.Appointments.Add(appt);
  166. // }
  167. // }
  168. // }
  169. //}
  170. #region Old Code
  171. /*
  172. Factory factory = new Factory();
  173. foreach (FactorySection section in settings.Sections)
  174. {
  175. factory.Sections.Add(new Section(section.Name, section.ID, section.Stations));
  176. }
  177. if (factory.Sections.Count == 0)
  178. {
  179. System.Windows.MessageBox.Show("Factory has not been configured!");
  180. return;
  181. }
  182. Client<Setout> client = new Client<Setout>();
  183. Setout[] setouts = client.Load(
  184. new Filter<Setout>(x => x.ID, Operator.NotEqualTo, Guid.Empty),
  185. new SortOrder<Setout>(x => x.DueDate, SortOrder.Ascending)
  186. );
  187. foreach(Setout setout in setouts)
  188. {
  189. List<Step> steps = new List<Step>();
  190. Guid _stage = Guid.Empty;
  191. String _status = "";
  192. setout.GetStage(out _stage, out _status);
  193. if (!_stage.Equals(Guid.Empty))
  194. {
  195. foreach (SetoutStage stage in setout.Stages)
  196. {
  197. if (stage.Completed.IsEmpty())
  198. steps.Add(new Step(stage.SectionID, stage.Minutes * setout.Quantity, stage.Sequence));
  199. }
  200. }
  201. if (steps.Count > 0)
  202. {
  203. factory.Widgets.Add
  204. (
  205. new Widget(setout.Title,setout.Job.Name,setout.Number,setout.DueDate,steps.ToArray())
  206. );
  207. }
  208. }
  209. //for (int i = 0; i < 100; i++)
  210. //{
  211. // DateTime date = DateTime.Today.AddDays(GetRandom(10F, 90F, 1F));
  212. // double cut = GetRandom(10F, 480F, 10F);
  213. // double mac = GetRandom(30F, 90F, 10F);
  214. // double fab = GetRandom(30F, 180F, 10F);
  215. // double ass = GetRandom(60F, 180F, 10F);
  216. // factory.Widgets.Add
  217. // (
  218. // new Widget
  219. // (
  220. // String.Format("{0:D2}", i + 1),
  221. // date,
  222. // new Step[]
  223. // {
  224. // new Step(StepType.Cutting , cut),
  225. // new Step(StepType.Machining , mac),
  226. // new Step(StepType.Fabricating , fab),
  227. // new Step(StepType.Assembling , ass)
  228. // }
  229. // )
  230. // );
  231. //}
  232. StringBuilder summary = new StringBuilder();
  233. //summary.AppendLine("Widget Due Date Cut Mac Fab Ass ");
  234. //summary.AppendLine("====== ========== ===== ===== ===== =====");
  235. //List<Widget> Widgets = factory.Widgets.OrderBy(x => x.DueDate).ToList();
  236. //foreach (Widget Widget in Widgets)
  237. //{
  238. // summary.AppendLine(String.Format("{0,-6} {1:dd/MM/yyyy} {2,5:hh\\:mm} {3,5:hh\\:mm} {4,5:hh\\:mm} {5,5:hh\\:mm}",
  239. // Widget.Name,
  240. // Widget.DueDate,
  241. // Widget.Steps[0].Duration,
  242. // Widget.Steps[1].Duration,
  243. // Widget.Steps[2].Duration,
  244. // Widget.Steps[3].Duration
  245. // ));
  246. //}
  247. //summary.AppendLine();
  248. factory.ProcessWidgets(DateTime.Today.AddHours(7), summary);
  249. summary.AppendLine();
  250. foreach (Section section in factory.Sections)
  251. {
  252. bool bFound = false;
  253. foreach (Tuple<String,Guid> tuple in Groups[Group])
  254. {
  255. if (tuple.Item2.Equals(section.ID))
  256. {
  257. bFound = true;
  258. break;
  259. }
  260. }
  261. if (bFound)
  262. {
  263. int i = 1; ;
  264. foreach (Station station in section.Stations)
  265. {
  266. StringBuilder line = new StringBuilder();
  267. String Heading = String.Format("Booking Schedule for {0} Station {1:D2}", section.Name, i);
  268. summary.AppendLine(Heading);
  269. summary.AppendLine(new string('=', Heading.Length));
  270. List<Booking> bookings = station.Bookings.OrderBy(x => x.Start).ToList();
  271. foreach (Booking booking in bookings)
  272. {
  273. summary.AppendLine(String.Format("From {1:HH:mm} until {2:HH:mm}, process {0}", booking.Widget.Name, booking.Start, booking.End));
  274. //if (station.StepType == StepType.Machining)
  275. //{
  276. Classes.Calendar appt = new Classes.Calendar()
  277. {
  278. SetoutNumber = booking.Widget.SetoutNumber,
  279. JobName = booking.Widget.JobName,
  280. DueDate = booking.Widget.DueDate,
  281. StartTime = booking.Start,
  282. EndTime = booking.End,
  283. Subject = booking.Widget.Name,
  284. AllDay = false
  285. };
  286. if (booking.End > booking.Widget.DueDate)
  287. {
  288. appt.AppointmentBackground = CreateBrush(Colors.Firebrick, booking.Shared);
  289. appt.AppointmentForeground = CreateBrush(Colors.Yellow, false);
  290. }
  291. else if (booking.End > booking.Widget.DueDate.Subtract(new TimeSpan(1, 0, 0, 0)))
  292. {
  293. appt.AppointmentBackground = CreateBrush(Colors.Orange, booking.Shared);
  294. appt.AppointmentForeground = CreateBrush(Colors.Black, false);
  295. }
  296. else
  297. {
  298. appt.AppointmentBackground = CreateBrush(Colors.LightGreen, booking.Shared);
  299. appt.AppointmentForeground = CreateBrush(Colors.Black, false);
  300. }
  301. appt.ResourceCollection.Add(new Resource() { ResourceName = station.ID.ToString(), TypeName = "Stations" });
  302. Schedule.Appointments.Add(appt);
  303. //}
  304. }
  305. summary.AppendLine();
  306. i++;
  307. }
  308. }
  309. }
  310. File.WriteAllText("factory.txt", summary.ToString());
  311. */
  312. #endregion
  313. }
  314. public DataModel DataModel(Selection selection)
  315. {
  316. return new ScheduleDataModel();
  317. }
  318. public void Heartbeat(TimeSpan time)
  319. {
  320. }
  321. private void DoRecalculateSchedule(PanelAction obj)
  322. {
  323. // Progress.Show("Recalculating Calendar");
  324. //Comal.Classes.Calendar calendar = new Comal.Classes.Calendar();
  325. // calendar.IsActive = true;
  326. // Progress.Show("Loading Manufacturing Packets");
  327. // var packets = new Client<ManufacturingPacket>().Load(new Filter<ManufacturingPacket>(x => x.Issued).IsNotEqualTo(DateTime.MinValue).And(x => x.Completed).IsEqualTo(DateTime.MinValue), new SortOrder<ManufacturingPacket>(x => x.DueDate));
  328. // Progress.Show("Rebuilding Calendar");
  329. // calendar.Build(packets);
  330. // Progress.Show("Saving Calendar");
  331. // new Client<Comal.Classes.Calendar>().Save(calendar, "Calendar Manually Built");
  332. // Progress.Close();
  333. // MessageBox.Show("Calculation Complete");
  334. // Refresh();
  335. }
  336. private double GetRandom(double minimum, double maximum, double step)
  337. {
  338. var value = generator.NextDouble() * (maximum - minimum) + minimum;
  339. value = Math.Round(value / step, 0) * step;
  340. return value;
  341. }
  342. public Brush CreateBrush(Color color, bool shared)
  343. {
  344. if (shared)
  345. {
  346. double dia1 = 1.5F;
  347. double dia2 = 2.0F;
  348. var vb = new VisualBrush();
  349. vb.TileMode = TileMode.Tile;
  350. vb.Viewport = new Rect(0, 0, dia1, dia1);
  351. vb.ViewportUnits = BrushMappingMode.Absolute;
  352. vb.Viewbox = new Rect(0, 0, dia2, dia2);
  353. vb.ViewboxUnits = BrushMappingMode.Absolute;
  354. var ellipse = new Ellipse();
  355. ellipse.Stroke = new SolidColorBrush(color);
  356. ellipse.Fill = new SolidColorBrush(Colors.DimGray);
  357. ellipse.Width = dia1;
  358. ellipse.Height = dia1;
  359. vb.Visual = ellipse;
  360. return vb;
  361. }
  362. return new SolidColorBrush(color);
  363. }
  364. private void ResizeIntervals(double height)
  365. {
  366. Schedule.IntervalHeight = (height - 130F) / 18F;
  367. }
  368. public Type DataType()
  369. {
  370. return typeof(ScheduleBooking);
  371. }
  372. private void Schedule_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
  373. {
  374. e.Action = DragAction.Cancel;
  375. }
  376. private void ProgressSetout_Click(object sender, RoutedEventArgs e)
  377. {
  378. }
  379. private void Factories_SelectionChanged(object sender, SelectionChangedEventArgs e)
  380. {
  381. if (e.AddedItems.Count == 0 || Factories.SelectedIndex == 0)
  382. {
  383. CurrentFactory = "";
  384. }
  385. else
  386. {
  387. var selected = (Tuple<string, BitmapImage>)e.AddedItems[0];
  388. CurrentFactory = selected.Item1;
  389. }
  390. Refresh();
  391. }
  392. private void Schedule_SizeChanged(object sender, SizeChangedEventArgs e)
  393. {
  394. ResizeIntervals(e.NewSize.Height);
  395. }
  396. }
  397. }