ManufacturingPanel.xaml.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  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.Input;
  8. using System.Windows.Media.Imaging;
  9. using System.Windows.Threading;
  10. using Comal.Classes;
  11. using InABox.Clients;
  12. using InABox.Configuration;
  13. using InABox.Core;
  14. using InABox.DynamicGrid;
  15. using InABox.WPF;
  16. using InABox.Wpf;
  17. using Syncfusion.UI.Xaml.Kanban;
  18. using System.ComponentModel;
  19. namespace PRSDesktop
  20. {
  21. public partial class ManufacturingPanel : UserControl, IPanel<ManufacturingPacket>, IPropertiesPanel<ManufacturingPanelProperties, CanConfigureManufacturingPanels>
  22. {
  23. private readonly List<IManufacturingPanelColumn> _columns = new();
  24. #region Settings Fields
  25. private bool bIncludeCompleted;
  26. private bool bIncludeHeld;
  27. private ManufacturingSettings.FilterOrdersOptions filterOrders;
  28. private ManufacturingViewType ViewType;
  29. private Guid CurrentFactory = Guid.Empty;
  30. private bool SortByDueDate = true;
  31. private ManufacturingSettings settings = new();
  32. public ManufacturingPanelProperties Properties { get; set; }
  33. #endregion
  34. private readonly DispatcherTimer columnsizer = new();
  35. private Document[] FactoryImages = Array.Empty<Document>();
  36. private int iCombo;
  37. private bool JobChanging;
  38. private readonly ManufacturingPanelData Data = new();
  39. private CoreTable packets;
  40. private Guid SelectedJob;
  41. public ManufacturingPanel()
  42. {
  43. InitializeComponent();
  44. //columnsizer.Interval = new TimeSpan(0, 0, 0, 0, 500);
  45. //columnsizer.Tick += Columnsizer_Tick;
  46. //columnsizer.IsEnabled = true;
  47. IncludeCompleted.IsChecked = false;
  48. }
  49. //public List<String> CheckedKanbans = new List<string>();
  50. public bool IsReady { get; set; }
  51. public Dictionary<string, object[]> Selected()
  52. {
  53. return new Dictionary<string, object[]> { { typeof(ManufacturingPacket).EntityName(), new CoreRow[] { } } };
  54. }
  55. public void Setup()
  56. {
  57. settings = new UserConfiguration<ManufacturingSettings>().Load();
  58. var FactorySource = new ObservableCollection<Tuple<string, BitmapImage, Guid>>();
  59. FactorySource.Add(new Tuple<string, BitmapImage, Guid>("All Sections", PRSDesktop.Resources.factory.AsBitmapImage(), Guid.Empty));
  60. var tables = ClientFactory.MultiQuery(
  61. new QueryDef<ManufacturingFactory>(null, null, null),
  62. new QueryDef<ManufacturingSection>(null, null, null),
  63. new QueryDef<ManufacturingTemplate>(null, null, null),
  64. new QueryDef<Job>(
  65. LookupFactory.DefineFilter<Job>(),
  66. new Columns<Job>(
  67. x => x.ID,
  68. x => x.JobNumber,
  69. x => x.Name
  70. ),
  71. LookupFactory.DefineSort<Job>()
  72. ),
  73. new QueryDef<JobITP>(null, null, null),
  74. new QueryDef<PurchaseOrderItem>(
  75. new Filter<PurchaseOrderItem>(x => x.Packet).LinkValid()
  76. .And(x => x.Packet.Completed).IsEqualTo(DateTime.MinValue),
  77. new Columns<PurchaseOrderItem>(
  78. x => x.ID,
  79. x => x.ReceivedDate,
  80. x => x.Consignment.EstimatedWarehouseArrival,
  81. x => x.DueDate,
  82. x => x.PurchaseOrderLink.SupplierLink.Code,
  83. x => x.PurchaseOrderLink.PONumber,
  84. x => x.ReceivedReference
  85. ),
  86. null
  87. )
  88. );
  89. Data.Factories = tables[0].Rows.Select(x => x.ToObject<ManufacturingFactory>())
  90. .ToArray(); //new Client<ManufacturingFactory>().Load(null, new SortOrder<ManufacturingFactory>(x=>x.Sequence));
  91. Data.Sections = tables[1].Rows.Select(x => x.ToObject<ManufacturingSection>())
  92. .ToArray(); //new Client<ManufacturingSection>().Load(null, new SortOrder<ManufacturingSection>(x=>x.Sequence));
  93. Data.Templates = tables[2].Rows.Select(x => x.ToObject<ManufacturingTemplate>())
  94. .ToArray(); //new Client<ManufacturingTemplate>().Load(null, new SortOrder<ManufacturingTemplate>(x=>x.Code));
  95. Data.Jobs = tables[3]; //.Rows.Select(x => x.ToObject<Job>()).ToArray();
  96. Data.ITPs = tables[4]; //.Rows.Select(x => x.ToObject<JobITP>()).ToArray();
  97. Data.Properties = Properties;
  98. foreach (var orderrow in tables[5].Rows)
  99. {
  100. var id = orderrow.Get<PurchaseOrderItem, Guid>(x => x.ID);
  101. var receiveddate = orderrow.Get<PurchaseOrderItem, DateTime>(c => c.ReceivedDate);
  102. var estimatedwarehousearrival = orderrow.Get<PurchaseOrderItem, DateTime>(c => c.Consignment.EstimatedWarehouseArrival);
  103. if (estimatedwarehousearrival.IsEmpty())
  104. estimatedwarehousearrival = orderrow.Get<PurchaseOrderItem, DateTime>(c => c.DueDate);
  105. var suppliercode = orderrow.Get<PurchaseOrderItem, string>(c => c.PurchaseOrderLink.SupplierLink.Code);
  106. var ponumber = orderrow.Get<PurchaseOrderItem, string>(c => c.PurchaseOrderLink.PONumber);
  107. var poreference = orderrow.Get<PurchaseOrderItem, string>(c => c.ReceivedReference);
  108. var tag = receiveddate.IsEmpty() ? "ETA" : "RCVD";
  109. Data.OrderItems.Add(new Tuple<Guid, DateTime, string>(
  110. id,
  111. receiveddate,
  112. string.Format("{0} ({1}) {2} {3:dd MMM yy} {4}",
  113. suppliercode,
  114. ponumber,
  115. tag,
  116. receiveddate.IsEmpty() ? estimatedwarehousearrival : receiveddate,
  117. string.IsNullOrWhiteSpace(poreference) ? "" : ": " + poreference
  118. )
  119. ));
  120. }
  121. //OrderItems = tables[5]; //.Rows.Select(x => x.ToObject<PurchaseOrderItem>()).ToArray();
  122. if (Data.Factories.Any())
  123. {
  124. Filter<Document>? imageFilter = null;
  125. foreach (var Factory in Data.Factories)
  126. if (Factory.Thumbnail.IsValid())
  127. imageFilter = imageFilter == null
  128. ? new Filter<Document>(x => x.ID).IsEqualTo(Factory.Thumbnail.ID)
  129. : imageFilter.Or(x => x.ID).IsEqualTo(Factory.Thumbnail.ID);
  130. FactoryImages = new Client<Document>().Load(imageFilter);
  131. }
  132. else
  133. FactoryImages = Array.Empty<Document>();
  134. var iFact = 1;
  135. foreach (var Factory in Data.Factories)
  136. {
  137. var groups = new List<string>();
  138. if (!FactorySource.Any(x => x.Item1.Equals(Factory.Name)))
  139. {
  140. var image = FactoryImages.FirstOrDefault(x => x.ID.Equals(Factory.Thumbnail.ID));
  141. BitmapImage img;
  142. if (image != null && image.Data != null && image.Data.Length > 0)
  143. {
  144. img = new BitmapImage();
  145. img.LoadImage(image.Data);
  146. }
  147. else
  148. {
  149. img = PRSDesktop.Resources.factory.AsBitmapImage();
  150. }
  151. FactorySource.Add(new Tuple<string, BitmapImage, Guid>(Factory.Name, img, Factory.ID));
  152. if (settings.FactoryID == Factory.ID)
  153. iFact = FactorySource.Count - 1;
  154. }
  155. }
  156. FactoryListBox.ItemsSource = FactorySource;
  157. FactoryListBox.SelectedIndex = iFact < FactorySource.Count ? iFact : 0;
  158. SortBy.SelectedIndex = settings.SortByDueDate ? 1 : 0;
  159. View.SelectedIndex = (int)ViewType;
  160. bIncludeHeld = settings.IncludeHeld;
  161. IncludeHeld.IsChecked = bIncludeHeld;
  162. filterOrders = settings.FilterOrders;
  163. FilterOrders.SelectedIndex = (int)filterOrders;
  164. bIncludeCompleted = settings.IncludeCompleted;
  165. IncludeCompleted.IsChecked = bIncludeCompleted;
  166. //new Client<Job>().Query(
  167. // LookupFactory.DefineFilter<Job>(),
  168. // LookupFactory.DefineColumns<Job>(),
  169. // LookupFactory.DefineSort<Job>(),
  170. // (table, error) =>
  171. // {
  172. // Dictionary<Guid, String> jobs = new Dictionary<Guid, string>() { { CoreUtils.FullGuid, "All Jobs" } };
  173. // foreach (var row in table.Rows)
  174. // jobs[row.Get<Job, Guid>(x => x.ID)] = String.Format("{0}: {1}", row.Get<Job, String>(x => x.JobNumber), row.Get<Job, String>(x => x.Name));
  175. // Dispatcher.Invoke(() =>
  176. // {
  177. // JobChanging = true;
  178. // Job.ItemsSource = jobs;
  179. // Job.SelectedValue = CoreUtils.FullGuid;
  180. // //Level.IsEnabled = false;
  181. // //Zone.IsEnabled = false;
  182. // ITP.IsEnabled = false;
  183. // JobChanging = false;
  184. // });
  185. // });
  186. var jobs = new Dictionary<Guid, string> { { CoreUtils.FullGuid, "All Jobs" } };
  187. foreach (var row in Data.Jobs.Rows)
  188. jobs[row.Get<Job, Guid>(c => c.ID)] =
  189. string.Format("{0}: {1}", row.Get<Job, string>(c => c.JobNumber), row.Get<Job, string>(c => c.Name));
  190. JobChanging = true;
  191. Job.ItemsSource = jobs;
  192. Job.SelectedValue = CoreUtils.FullGuid;
  193. SelectedJob = CoreUtils.FullGuid;
  194. ITP.IsEnabled = false;
  195. JobChanging = false;
  196. }
  197. public void Shutdown(CancelEventArgs? cancel)
  198. {
  199. }
  200. public void CreateToolbarButtons(IPanelHost host)
  201. {
  202. ManufacturingSetupActions.Standard(host);
  203. host.CreateSetupAction(
  204. new PanelAction()
  205. {
  206. Caption = "Template Groups",
  207. Image = PRSDesktop.Resources.specifications,
  208. OnExecute =
  209. action =>
  210. {
  211. var list = new MasterList(typeof(ManufacturingTemplateGroup));
  212. list.ShowDialog();
  213. }
  214. }
  215. );
  216. }
  217. public string SectionName => "Manufacturing Packets";
  218. public DataModel DataModel(Selection selection)
  219. {
  220. var ids = new List<Guid>();
  221. foreach (var column in _columns)
  222. {
  223. var rows = selection == Selection.None
  224. ? Enumerable.Empty<ManufacturingPacket>()
  225. : selection == Selection.Selected
  226. ? column.GetSelectedPackets()
  227. : column.GetPackets();
  228. ids.AddRange(rows.Select(r => r.ID));
  229. }
  230. return new ManufacturingPacketDataModel(new Filter<ManufacturingPacket>(x => x.ID).InList(ids.ToArray()));
  231. }
  232. public void Refresh()
  233. {
  234. Application.Current.Dispatcher.Invoke(() => { Mouse.OverrideCursor = Cursors.Wait; });
  235. var now = DateTime.Now;
  236. ReloadFactories();
  237. var elapsed = DateTime.Now - now;
  238. Logger.Send(LogType.Information, ClientFactory.UserID, string.Format("Refreshed Factories in {0}ms", elapsed.TotalMilliseconds));
  239. now = DateTime.Now;
  240. ReloadPackets();
  241. elapsed = DateTime.Now - now;
  242. Logger.Send(LogType.Information, ClientFactory.UserID, string.Format("Refreshed Packets in {0}ms", elapsed.TotalMilliseconds));
  243. Application.Current.Dispatcher.Invoke(() => { Mouse.OverrideCursor = null; });
  244. }
  245. public event DataModelUpdateEvent? OnUpdateDataModel;
  246. //private void ChangeDate_Click(object sender, RoutedEventArgs e)
  247. //{
  248. // MenuItem item = (MenuItem)sender;
  249. // KanbanModel model = (KanbanModel)item.Tag;
  250. // var pkts = GetSelectedPackets(model.ID);
  251. // DateTime? date = null;
  252. // foreach (var pkt in pkts)
  253. // {
  254. // if (!date.HasValue)
  255. // date = pkt.DueDate;
  256. // else if (!date.Value.Equals(pkt.DueDate))
  257. // date = date > pkt.DueDate ? date : pkt.DueDate;
  258. // }
  259. // DateTime date2 = !date.HasValue ? DateTime.Today.AddDays(14) : date.Value;
  260. // if (InABox.WPF.DateEdit.Execute("Required Completion Date", ref date2))
  261. // {
  262. // Progress.SetMessage("Updating Packets");
  263. // foreach (var pkt in pkts)
  264. // pkt.DueDate = date2;
  265. // new Client<ManufacturingPacket>().Save(pkts, String.Format("Changed Due Date To {0:dd MMM yy}", date2));
  266. // CheckedKanbans.Clear();
  267. // Progress.Close();
  268. // Refresh();
  269. // }
  270. //}
  271. //private void UpdatePriority(object sender, bool priority)
  272. //{
  273. // MenuItem item = (MenuItem)sender;
  274. // KanbanModel model = (KanbanModel)item.Tag;
  275. // Progress.Show("");
  276. // var pkts = GetSelectedPackets(model.ID);
  277. // for (int i = 0; i < pkts.Length; i++)
  278. // {
  279. // var packet = pkts[i];
  280. // packet.Priority = priority;
  281. // }
  282. // Progress.SetMessage("Updating Packets");
  283. // new Client<ManufacturingPacket>().Save(pkts, "Priority Flag "+ (priority ? "Set" : "Cleared"));
  284. // CheckedKanbans.Clear();
  285. // Progress.Close();
  286. // Refresh();
  287. //}
  288. //private void SetPriority_Click(object sender, RoutedEventArgs e)
  289. //{
  290. // UpdatePriority(sender, true);
  291. //}
  292. //private void ClearPriority_Click(object sender, RoutedEventArgs e)
  293. //{
  294. // UpdatePriority(sender, false);
  295. //}
  296. //private void UpdateHold(object sender, bool hold)
  297. //{
  298. // MenuItem item = (MenuItem)sender;
  299. // KanbanModel model = (KanbanModel)item.Tag;
  300. // Progress.Show("");
  301. // var pkts = GetSelectedPackets(model.ID);
  302. // for (int i = 0; i < pkts.Length; i++)
  303. // {
  304. // var packet = pkts[i];
  305. // packet.OnHold = hold;
  306. // }
  307. // Progress.SetMessage("Updating Packets");
  308. // new Client<ManufacturingPacket>().Save(pkts, "Hold Flag " + (hold ? "Set" : "Cleared"));
  309. // CheckedKanbans.Clear();
  310. // Progress.Close();
  311. // Refresh();
  312. //}
  313. //private void SetHold_Click(object sender, RoutedEventArgs e)
  314. //{
  315. // UpdateHold(sender, true);
  316. //}
  317. //private void ClearHold_Click(object sender, RoutedEventArgs e)
  318. //{
  319. // UpdateHold(sender, false);
  320. //}
  321. //private void CompeteItem_Click(object sender, RoutedEventArgs e)
  322. //{
  323. // MenuItem item = (MenuItem)sender;
  324. // KanbanModel model = (KanbanModel)item.Tag;
  325. // Progress.Show("");
  326. // var pkts = GetSelectedPackets(model.ID);
  327. // Progress.SetMessage("Loading Stages");
  328. // Filter<ManufacturingPacketStage> stgflt = null;
  329. // foreach (var pkt in pkts)
  330. // stgflt = stgflt == null ? new Filter<ManufacturingPacketStage>(x => x.ManufacturingPacketLink.ID).IsEqualTo(pkt.ID) : stgflt.Or(x => x.ManufacturingPacketLink.ID).IsEqualTo(pkt.ID);
  331. // ManufacturingPacketStage[] stgs = new Client<ManufacturingPacketStage>().Load(stgflt, new SortOrder<ManufacturingPacketStage>(x => x.Sequence));
  332. // while (pkts.Any(x => x.Completed.IsEmpty()))
  333. // {
  334. // ManufacturingPacket.Progress(pkts, stgs);
  335. // }
  336. // Progress.SetMessage("Progressing Items");
  337. // new Client<ManufacturingPacketStage>().Save(stgs.Where(x => x.IsChanged()), "ManufacturingPacket Marked as Complete");
  338. // new Client<ManufacturingPacket>().Save(pkts.Where(x => x.IsChanged()), "ManufacturingPacket Marked as Complete");
  339. // Progress.Close();
  340. // CheckedKanbans.Clear();
  341. // Refresh();
  342. //}
  343. public void Heartbeat(TimeSpan time)
  344. {
  345. }
  346. private void Job_SelectionChanged(object sender, SelectionChangedEventArgs e)
  347. {
  348. var oldID = SelectedJob;
  349. var newID = Job.SelectedValue != null ? (Guid)Job.SelectedValue : Guid.Empty;
  350. SelectedJob = newID;
  351. //Dictionary<Guid, String> Levels = new Dictionary<Guid, string>() { { CoreUtils.FullGuid, "All Levels" } };
  352. //Dictionary<Guid, String> Zones = new Dictionary<Guid, string>() { { CoreUtils.FullGuid, "All Zones" } };
  353. var itps = new Dictionary<Guid, string> { { CoreUtils.FullGuid, "All ITPs" } };
  354. if (SelectedJob == Guid.Empty || SelectedJob == CoreUtils.FullGuid)
  355. {
  356. iCombo = 1;
  357. //Level.ItemsSource = Levels;
  358. //Level.SelectedValue = CoreUtils.FullGuid;
  359. //Level.IsEnabled = false;
  360. //Zone.ItemsSource = Zones;
  361. //Zone.SelectedValue = CoreUtils.FullGuid;
  362. //Zone.IsEnabled = false;
  363. ITP.ItemsSource = itps;
  364. ITP.SelectedValue = CoreUtils.FullGuid;
  365. ITP.IsEnabled = false;
  366. iCombo = 0;
  367. }
  368. else
  369. {
  370. iCombo = 1;
  371. foreach (var row in Data.ITPs.Rows.Where(r => r.Get<JobITP, Guid>(c => c.Job.ID).Equals(SelectedJob)))
  372. itps[row.Get<JobITP, Guid>(c => c.Job.ID)] =
  373. string.Format("{0}: {1}", row.Get<JobITP, string>(c => c.Code), row.Get<JobITP, string>(c => c.Description));
  374. ITP.ItemsSource = itps;
  375. ITP.SelectedValue = CoreUtils.FullGuid;
  376. ITP.IsEnabled = true;
  377. iCombo--;
  378. }
  379. if (newID != CoreUtils.FullGuid && ViewType == ManufacturingViewType.Job)
  380. {
  381. View.SelectedIndex = (int)ManufacturingViewType.Full;
  382. }
  383. else
  384. {
  385. if (!JobChanging && iCombo == 0)
  386. {
  387. ReloadPackets();
  388. }
  389. }
  390. }
  391. private void Unit_SelectionChanged(object sender, SelectionChangedEventArgs e)
  392. {
  393. if (JobChanging || iCombo > 0)
  394. return;
  395. ReloadPackets();
  396. }
  397. private void AddColumn<TColumn>(string title, Guid category, TColumn column)
  398. where TColumn : FrameworkElement, IManufacturingPanelColumn
  399. {
  400. column.Margin = new Thickness(_columns.Any() ? 2 : 0, 0, 0, 0);
  401. column.Title = title;
  402. column.Data = Data;
  403. column.Category = category;
  404. column.SetValue(Grid.ColumnProperty, _columns.Count);
  405. column.OnCollapsed += Column_OnCollapsed;
  406. Columns.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  407. Columns.Children.Add(column);
  408. _columns.Add(column);
  409. }
  410. private void CreateColumn(string title, Guid category)
  411. {
  412. var job = SelectedJob;
  413. if (ViewType == ManufacturingViewType.Job)
  414. {
  415. var column = new ManufacturingPanelJobColumn();
  416. column.OnSelectJob += Column_OnSelectJob;
  417. AddColumn(title, category, column);
  418. }
  419. else
  420. {
  421. var column = new ManufacturingPanelColumn();
  422. column.CompactView = ViewType == ManufacturingViewType.Compact;
  423. column.OnChanged += Column_OnChanged;
  424. AddColumn(title, category, column);
  425. }
  426. }
  427. private void Column_OnSelectJob(Guid jobID)
  428. {
  429. Job.SelectedValue = jobID;
  430. }
  431. private void Column_OnCollapsed(object sender, bool collapsed)
  432. {
  433. var index = _columns.IndexOf((IManufacturingPanelColumn)sender);
  434. Columns.ColumnDefinitions[index].Width = new GridLength(1, collapsed ? GridUnitType.Auto : GridUnitType.Star);
  435. }
  436. private void Column_OnChanged(object? sender, EventArgs e)
  437. {
  438. Refresh();
  439. }
  440. private void ReloadFactories()
  441. {
  442. columnsizer.IsEnabled = false;
  443. Columns.Children.Clear();
  444. _columns.Clear();
  445. Columns.ColumnDefinitions.Clear();
  446. CreateColumn("To Be Issued", Guid.Empty);
  447. //Kanban.Columns.Clear();
  448. //Kanban.Columns.Add(new KanbanColumn() { Title = "To be Issued", Categories = Guid.Empty.ToString() });
  449. foreach (var factory in Data.Factories)
  450. if (CurrentFactory.Equals(Guid.Empty) || CurrentFactory.Equals(factory.ID))
  451. foreach (var section in Data.Sections)
  452. if (section.Factory.ID.Equals(factory.ID) && !section.Hidden)
  453. CreateColumn(section.Factory.Name + ":" + section.Name, section.ID);
  454. //Kanban.Columns.Add(new KanbanColumn() { Title = Section.Factory.Name + ":" + Section.Name, Categories = Section.ID.ToString() });
  455. if (bIncludeCompleted)
  456. CreateColumn("Completed", CoreUtils.FullGuid);
  457. //Kanban.Columns.Add(new KanbanColumn() { Title = "Completed", Categories = CoreUtils.FullGuid.ToString() });
  458. //foreach (KanbanColumn column in Kanban.Columns)
  459. //{
  460. // ContextMenu menu = new ContextMenu();
  461. // menu.Tag = column;
  462. // MenuItem item = new MenuItem() { Header = "Select All " + column.Title + " Tasks", Tag = column };
  463. // item.Click += SelectAll_Click;
  464. // menu.Items.Add(item);
  465. // item = new MenuItem() { Header = "Unselect All " + column.Title + " Tasks", Tag = column };
  466. // item.Click += UnSelectAll_Click;
  467. // menu.Items.Add(item);
  468. // column.ContextMenu = menu;
  469. // column.AllowDrag = false;
  470. // column.AllowDrop = false;
  471. //}
  472. //ResizeColumns();
  473. //columnsizer.IsEnabled = true;
  474. }
  475. //private void SetSelectedItems(KanbanColumn column, bool selected)
  476. //{
  477. // foreach (ManufacturingKanban model in Kanbans)
  478. // {
  479. // if ((string)model.Category == column.Categories)
  480. // {
  481. // if (!CheckedKanbans.Contains(model.ID))
  482. // CheckedKanbans.Add(model.ID);
  483. // model.Checked = selected;
  484. // }
  485. // }
  486. // Kanban.ItemsSource = null;
  487. // Kanban.ItemsSource = Kanbans;
  488. //}
  489. //private void UnSelectAll_Click(object sender, RoutedEventArgs e)
  490. //{
  491. // KanbanColumn column = ((MenuItem)sender).Tag as KanbanColumn;
  492. // SetSelectedItems(column, false);
  493. //}
  494. //private void SelectAll_Click(object sender, RoutedEventArgs e)
  495. //{
  496. // KanbanColumn column = ((MenuItem)sender).Tag as KanbanColumn;
  497. // SetSelectedItems(column, true);
  498. //}
  499. private void CheckBox_Checked(object sender, RoutedEventArgs e)
  500. {
  501. //ManufacturingKanban task = ((CheckBox)sender).Tag as ManufacturingKanban;
  502. //if (CheckedKanbans.Contains(task.ID))
  503. // CheckedKanbans.Remove(task.ID);
  504. //else
  505. // CheckedKanbans.Add(task.ID);
  506. }
  507. private string GetQualityStatus(QualityStatus status)
  508. {
  509. if (status == QualityStatus.Passed)
  510. return "PASSED";
  511. if (status == QualityStatus.Skipped)
  512. return "SKIPPED";
  513. if (status == QualityStatus.PassedWithIssues)
  514. return "ISSUES";
  515. if (status == QualityStatus.Failed)
  516. return "FAILED";
  517. return " ";
  518. }
  519. private void ReloadPackets()
  520. {
  521. var filter = GenerateFilter();
  522. var columns = GenerateColumns();
  523. using var profiler = new Profiler(false);
  524. packets = new Client<ManufacturingPacket>().Query(
  525. filter,
  526. columns,
  527. SortBy.SelectedIndex == 0
  528. ? new SortOrder<ManufacturingPacket>(x => x.SetoutLink.Number)
  529. : new SortOrder<ManufacturingPacket>(x => x.DueDate).ThenBy(x => x.Priority, SortDirection.Descending)
  530. .ThenBy(x => x.SetoutLink.Number));
  531. Logger.Send(LogType.Information, ClientFactory.UserID,
  532. string.Format("Retrieved {0} packets in {1}ms", packets.Rows.Count, profiler.Restart()));
  533. var objects = packets.ToObjects<ManufacturingPacket>();
  534. var groups = objects.GroupBy(x => !x.Completed.IsEmpty() ? CoreUtils.FullGuid : x.StageLink.SectionID);
  535. var results = groups.ToDictionary(x => x.Key, x => x);
  536. Logger.Send(LogType.Information, ClientFactory.UserID, string.Format("Processed Kanbans in {0}ms", profiler.Restart()));
  537. foreach (var column in _columns)
  538. {
  539. column.SetPackets(results.GetValueOrDefault(column.Category) ?? Enumerable.Empty<ManufacturingPacket>());
  540. }
  541. Logger.Send(LogType.Information, ClientFactory.UserID, string.Format("Loaded Columns in {0}ms", profiler.Restart()));
  542. }
  543. private Filter<ManufacturingPacket> GenerateFilter()
  544. {
  545. var filter = new Filter<ManufacturingPacket>(x => x.Archived).IsEqualTo(DateTime.MinValue);
  546. if (!bIncludeCompleted)
  547. filter = filter.And(x => x.Completed).IsEqualTo(DateTime.MinValue);
  548. if (!bIncludeHeld)
  549. // filter = filter.And(x => x.OnHold).IsEqualTo(false);
  550. filter = filter.And(x => x.OnHold).IsEqualTo(false);
  551. switch (filterOrders)
  552. {
  553. case ManufacturingSettings.FilterOrdersOptions.IncludeOrders:
  554. break;
  555. case ManufacturingSettings.FilterOrdersOptions.OrdersOnly:
  556. var orderfilter = new Filter<ManufacturingPacket>(x => x.OrderItem).LinkValid()
  557. .And(x => x.OrderItem.ReceivedDate).IsEqualTo(DateTime.MinValue);
  558. filter = filter.And(orderfilter);
  559. break;
  560. case ManufacturingSettings.FilterOrdersOptions.ExcludeOrders:
  561. orderfilter = new Filter<ManufacturingPacket>(x => x.OrderItem).NotLinkValid()
  562. .Or(x => x.OrderItem.ReceivedDate).IsNotEqualTo(DateTime.MinValue);
  563. filter = filter.And(orderfilter);
  564. break;
  565. }
  566. var bSkipJobCheck = false;
  567. if (ITP.SelectedValue != null && !ITP.SelectedValue.Equals(CoreUtils.FullGuid))
  568. {
  569. filter = filter.And(x => x.ITP.ID).IsEqualTo((Guid)ITP.SelectedValue);
  570. bSkipJobCheck = true;
  571. }
  572. if (!bSkipJobCheck && Job.SelectedValue != null && !Job.SelectedValue.Equals(CoreUtils.FullGuid))
  573. filter = filter.And(x => x.SetoutLink.JobLink.ID).IsEqualTo((Guid)Job.SelectedValue);
  574. var sections = Data.Sections.Where(x => CurrentFactory.Equals(Guid.Empty) || x.Factory.ID.Equals(CurrentFactory)).Select(x => x.ID)
  575. .ToList();
  576. var sctflt = new Filter<ManufacturingPacket>(x => x.StageLink.SectionID).IsEqualTo(Guid.Empty)
  577. .Or(x => x.StageLink.SectionID).InList(sections.ToArray());
  578. /*
  579. var sctflt = new Filter<ManufacturingPacket>(x => x.StageLink).NotLinkValid();
  580. foreach (var section in Data.Sections.Where(x => CurrentFactory.Equals(Guid.Empty) || x.Factory.ID.Equals(CurrentFactory)))
  581. sctflt = sctflt.Or(x => x.StageLink.SectionID).IsEqualTo(section.ID);
  582. */
  583. filter.Ands.Add(sctflt);
  584. if (CurrentFactory != Guid.Empty)
  585. {
  586. var templatefilter = new Filter<ManufacturingPacket>(x => x.ManufacturingTemplateLink.Factory.ID).IsEqualTo(CurrentFactory)
  587. .Or(x => x.StageLink).LinkValid();
  588. filter.Ands.Add(templatefilter);
  589. }
  590. if (!string.IsNullOrWhiteSpace(SearchBox.Text))
  591. filter = filter.TextSearch(
  592. SearchBox.Text,
  593. x => x.SetoutLink.JobLink.JobNumber,
  594. x => x.SetoutLink.JobLink.Name,
  595. x => x.SetoutLink.Number,
  596. x => x.SetoutLink.Description,
  597. //x => x.SetoutLink.Reference,
  598. x => x.SetoutLink.Location,
  599. //x => x.Unit.Code,
  600. //x => x.Unit.Description,
  601. x => x.ITP.Code,
  602. x => x.ITP.Description,
  603. x => x.Title,
  604. x => x.Serial,
  605. x => x.Location,
  606. x => x.WaterMark,
  607. x => x.ManufacturingTemplateLink.Code
  608. );
  609. return filter;
  610. }
  611. private static Columns<ManufacturingPacket> GenerateColumns()
  612. {
  613. var columns = new Columns<ManufacturingPacket>();
  614. columns.Add(x => x.ID);
  615. //columns.Add(x => x.OnHold);
  616. columns.Add(x => x.OnHold);
  617. columns.Add(x => x.Issues);
  618. columns.Add(x => x.Priority);
  619. columns.Add(x => x.Distributed);
  620. columns.Add(x => x.BarcodeQty);
  621. columns.Add(x => x.Quantity);
  622. columns.Add(x => x.Title);
  623. columns.Add(x => x.Serial);
  624. columns.Add(x => x.WaterMark);
  625. columns.Add(x => x.EstimatedDate);
  626. columns.Add(x => x.Created);
  627. columns.Add(x => x.DueDate);
  628. columns.Add(x => x.Location);
  629. columns.Add(x => x.BarcodePrinted);
  630. columns.Add(x => x.BarcodeType);
  631. columns.Add(x => x.Completed);
  632. //columns.Add(x => x.TimeRemaining);
  633. columns.Add(x => x.Group);
  634. columns.Add(x => x.SetoutLink.ID);
  635. columns.Add(x => x.SetoutLink.Number);
  636. columns.Add(x => x.SetoutLink.Description);
  637. columns.Add(x => x.SetoutLink.Location);
  638. columns.Add(x => x.SetoutLink.JobLink.ID);
  639. columns.Add(x => x.SetoutLink.Group.ID);
  640. columns.Add(x => x.SetoutLink.Group.Name);
  641. columns.Add(x => x.SetoutLink.Group.Job.JobNumber);
  642. columns.Add(x => x.SetoutLink.Group.OptimizationDocument.ID);
  643. columns.Add(x => x.OrderItem.ID);
  644. //columns.Add(x => x.OrderItem.ReceivedDate);
  645. //columns.Add(x => x.OrderItem.Consignment.EstimatedWarehouseArrival);
  646. //columns.Add(x => x.OrderItem.PurchaseOrderLink.SupplierLink.Code);
  647. //columns.Add(x => x.OrderItem.PurchaseOrderLink.PONumber);
  648. columns.Add(x => x.ManufacturingTemplateLink.ID);
  649. columns.Add(x => x.ITP.ID);
  650. columns.Add(x => x.StageLink.ID);
  651. columns.Add(x => x.StageLink.SectionID);
  652. columns.Add(x => x.StageLink.Station);
  653. columns.Add(x => x.StageLink.Time);
  654. columns.Add(x => x.StageLink.PercentageComplete);
  655. columns.Add(x => x.StageLink.Deleted);
  656. return columns;
  657. }
  658. private void Factories_SelectionChanged(object sender, SelectionChangedEventArgs e)
  659. {
  660. if (e.AddedItems.Count == 0 || e.AddedItems[0] is not Tuple<string, BitmapImage, Guid> selected)
  661. return;
  662. CurrentFactory = selected.Item3;
  663. if (IsReady)
  664. SaveSettings();
  665. if (IsReady)
  666. Refresh();
  667. }
  668. private void SortBy_SelectionChanged(object sender, SelectionChangedEventArgs e)
  669. {
  670. if (e.AddedItems.Count == 0 || e.AddedItems[0] is not ComboBoxItem selected)
  671. return;
  672. SortByDueDate = selected.Content.Equals("Due Date");
  673. if (IsReady)
  674. SaveSettings();
  675. if (IsReady)
  676. Refresh();
  677. }
  678. private void View_SelectionChanged(object sender, SelectionChangedEventArgs e)
  679. {
  680. if (e.AddedItems.Count == 0 || e.AddedItems[0] is not ComboBoxItem selected)
  681. return;
  682. ViewType = (ManufacturingViewType)View.SelectedIndex;
  683. if (IsReady)
  684. SaveSettings();
  685. if (ViewType == ManufacturingViewType.Job && SelectedJob != CoreUtils.FullGuid)
  686. {
  687. SelectedJob = CoreUtils.FullGuid;
  688. JobChanging = true;
  689. Job.SelectedValue = SelectedJob;
  690. JobChanging = false;
  691. }
  692. if (IsReady)
  693. Refresh();
  694. }
  695. private void SearchBox_KeyUp(object sender, KeyEventArgs e)
  696. {
  697. if (string.IsNullOrWhiteSpace(SearchBox.Text) || e.Key == Key.Return)
  698. Refresh();
  699. }
  700. private void IncludeCompleted_Click(object sender, RoutedEventArgs e)
  701. {
  702. bIncludeCompleted = IncludeCompleted.IsChecked == true;
  703. if (IsReady)
  704. {
  705. SaveSettings();
  706. Refresh();
  707. }
  708. }
  709. private void IncludeHeld_Click(object sender, RoutedEventArgs e)
  710. {
  711. bIncludeHeld = IncludeHeld.IsChecked == true;
  712. if (IsReady)
  713. {
  714. SaveSettings();
  715. Refresh();
  716. }
  717. }
  718. private void FilterOrders_SelectionChanged(object sender, SelectionChangedEventArgs e)
  719. {
  720. if (e.AddedItems.Count == 0 || e.AddedItems[0] is not ComboBoxItem selected)
  721. return;
  722. filterOrders = (ManufacturingSettings.FilterOrdersOptions)FilterOrders.SelectedIndex;
  723. if (IsReady)
  724. {
  725. SaveSettings();
  726. Refresh();
  727. }
  728. }
  729. private void SaveSettings()
  730. {
  731. var user = new ManufacturingSettings
  732. {
  733. FactoryID = CurrentFactory,
  734. SortByDueDate = SortByDueDate,
  735. ViewType = ViewType,
  736. IncludeHeld = bIncludeHeld,
  737. FilterOrders = filterOrders,
  738. IncludeCompleted = bIncludeCompleted
  739. };
  740. new UserConfiguration<ManufacturingSettings>().Save(user);
  741. }
  742. private void Export_Click(object sender, RoutedEventArgs e)
  743. {
  744. IEnumerable<string> columns = string.IsNullOrWhiteSpace(settings.ExportColumns) ? Array.Empty<string>() : settings.ExportColumns.Split(',');
  745. if (!columns.Any())
  746. columns = packets.Columns.Select(x => x.ColumnName);
  747. var form = new DynamicExportForm(typeof(ManufacturingPacket), columns);
  748. if (form.ShowDialog() != true)
  749. return;
  750. settings.ExportColumns = string.Join(",", form.Fields);
  751. new UserConfiguration<ManufacturingSettings>().Save(settings);
  752. var export = new Client<ManufacturingPacket>().Query(
  753. GenerateFilter(),
  754. new Columns<ManufacturingPacket>(form.Fields),
  755. LookupFactory.DefineSort<ManufacturingPacket>()
  756. );
  757. ExcelExporter.DoExport<ManufacturingPacket>(export, string.Format("Manufacturing {0:dd-MMM-yy}", DateTime.Today));
  758. }
  759. }
  760. }