ManufacturingAllocationPanel.xaml.cs 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Input;
  9. using System.Windows.Media;
  10. using System.Windows.Media.Imaging;
  11. using Comal.Classes;
  12. using InABox.Clients;
  13. using InABox.Configuration;
  14. using InABox.Core;
  15. using InABox.WPF;
  16. using InABox.Wpf;
  17. using System.ComponentModel;
  18. namespace PRSDesktop
  19. {
  20. /// <summary>
  21. /// Interaction logic for ManufacturingAllocationPanel.xaml
  22. /// </summary>
  23. public partial class ManufacturingAllocationPanel : UserControl, IPanel<ManufacturingPacket>
  24. {
  25. private Guid _section = Guid.Empty;
  26. private CoreTable _sections;
  27. private readonly BitmapImage barcode = PRSDesktop.Resources.barcode.AsBitmapImage();
  28. private readonly List<Tuple<Border, Label, ListBox, ColumnDefinition, int, CheckBox, Label>> columns = new();
  29. private ListBox current;
  30. private readonly BitmapImage disabled = PRSDesktop.Resources.disabled.AsBitmapImage();
  31. private readonly BitmapImage grouped = PRSDesktop.Resources.grouped.AsBitmapImage();
  32. private readonly string NEARLYDUE_COLOR = "Orange";
  33. private readonly string NOTYETDUE_COLOR = "PaleGreen";
  34. private readonly string ORDER_COLOR = "Gray";
  35. private readonly string OVERDUE_COLOR = "Salmon";
  36. private CoreTable Packets;
  37. private readonly string PRIORITY_COLOR = "Red";
  38. private readonly string QA_COLOR = "Silver";
  39. private string SELECTED_COLOR = "Yellow";
  40. private readonly string SHARED_COLOR = "Lime";
  41. private CoreTable Stages;
  42. public ManufacturingAllocationPanel()
  43. {
  44. InitializeComponent();
  45. Kanbans = new ObservableCollection<ManufacturingKanban>();
  46. PendingCheck.Tag = Pending;
  47. }
  48. public ObservableCollection<ManufacturingKanban> Kanbans { get; set; }
  49. public bool IsReady { get; set; }
  50. public void CreateToolbarButtons(IPanelHost host)
  51. {
  52. ManufacturingSetupActions.Standard(host);
  53. }
  54. public string SectionName => "Factory Allocation";
  55. public DataModel DataModel(Selection selection)
  56. {
  57. var ids = Packets != null ? Packets.Rows.Select(r => r.Get<ManufacturingPacket, Guid>(x => x.ID)).ToArray() : new Guid[] { };
  58. return new ManufacturingPacketDataModel(new Filter<ManufacturingPacket>(x => x.ID).InList(ids));
  59. }
  60. public void Refresh()
  61. {
  62. if (_section == Guid.Empty)
  63. {
  64. var sections = (Dictionary<Guid, string>)Sections.ItemsSource;
  65. _section = sections.Any() ? sections.First().Key : Guid.Empty;
  66. Sections.SelectedValue = _section;
  67. }
  68. ReloadPackets(true);
  69. }
  70. public Dictionary<string, object[]> Selected()
  71. {
  72. var result = new Dictionary<string, object[]>();
  73. return result;
  74. }
  75. public void Setup()
  76. {
  77. var settings = new UserConfiguration<ManufacturingAllocationSettings>().Load();
  78. var sections = new Dictionary<Guid, string>();
  79. ReloadSections();
  80. foreach (var row in _sections.Rows)
  81. sections[row.Get<ManufacturingSection, Guid>(x => x.ID)] = string.Format("{0}: {1}",
  82. row.Get<ManufacturingSection, string>(x => x.Factory.Name), row.Get<ManufacturingSection, string>(x => x.Name));
  83. _section = sections.ContainsKey(settings.Section) ? settings.Section : sections.Any() ? sections.First().Key : Guid.Empty;
  84. Sections.ItemsSource = sections;
  85. Sections.SelectedValue = _section;
  86. }
  87. public void Shutdown(CancelEventArgs? cancel)
  88. {
  89. }
  90. public event DataModelUpdateEvent? OnUpdateDataModel;
  91. public void Heartbeat(TimeSpan time)
  92. {
  93. // Nothing to do here
  94. }
  95. private BitmapImage GetBarCode(CoreRow packet)
  96. {
  97. if (!packet.Get<ManufacturingPacket, DateTime>(c => c.BarcodePrinted).IsEmpty())
  98. return packet.Get<ManufacturingPacket, BarcodeType>(c => c.BarcodeType) == BarcodeType.Grouped ? grouped : barcode;
  99. if (packet.Get<ManufacturingPacket, BarcodeType>(c => c.BarcodeType) == BarcodeType.None)
  100. return disabled;
  101. return null;
  102. }
  103. private string GetColor(DateTime duedate, DateTime estdate)
  104. {
  105. var color = NOTYETDUE_COLOR;
  106. if (duedate < estdate)
  107. color = OVERDUE_COLOR;
  108. else if (duedate < estdate.AddDays(7))
  109. color = NEARLYDUE_COLOR;
  110. return color;
  111. }
  112. private void CreateKanban(CoreRow row, bool IsChecked)
  113. {
  114. try
  115. {
  116. var packetid = row.Get<ManufacturingPacket, Guid>(x => x.ID);
  117. var priority = row.Get<ManufacturingPacket, bool>(c => c.Priority);
  118. var qty = row.Get<ManufacturingPacket, int>(c => c.Quantity);
  119. var barqty = row.Get<ManufacturingPacket, int>(c => c.BarcodeQty);
  120. var duedate = row.Get<ManufacturingPacket, DateTime>(c => c.DueDate);
  121. var estdate = row.Get<ManufacturingPacket, DateTime>(c => c.EstimatedDate);
  122. var sectionid = row.Get<ManufacturingPacket, Guid>(c => c.StageLink.SectionID);
  123. var pktsection = row.Get<ManufacturingPacket, string>(c => c.StageLink.Section);
  124. var stage = Stages.Rows.FirstOrDefault(r => r.Get<ManufacturingPacketStage, Guid>(c => c.Parent.ID).Equals(packetid));
  125. if (stage == null)
  126. return;
  127. var section = (Guid)Sections.SelectedValue;
  128. var station = stage.Get<ManufacturingPacketStage, int>(c => c.Station);
  129. var quality = stage.Get<ManufacturingPacketStage, QualityStatus>(c => c.QualityStatus);
  130. var percentage = stage.Get<ManufacturingPacketStage, double>(c => c.PercentageComplete);
  131. var Pending = station == 0;
  132. var model = new ManufacturingKanban();
  133. model.ID = row.Get<ManufacturingPacket, Guid>(c => c.ID).ToString();
  134. model.Title = string.Format("{0}: {1}{2}",
  135. row.Get<ManufacturingPacket, string>(c => c.Serial),
  136. qty != barqty ? string.Format("{0} x ", qty) : "",
  137. row.Get<ManufacturingPacket, string>(c => c.Title)
  138. );
  139. model.Quantity = barqty;
  140. model.JobName = string.Format("{0}: {1}",
  141. row.Get<ManufacturingPacket, string>(c => c.SetoutLink.Number),
  142. row.Get<ManufacturingPacket, string>(c => c.SetoutLink.JobLink.Name)
  143. );
  144. model.DueDate = duedate;
  145. var location = row.Get<ManufacturingPacket, string>(c => c.Location);
  146. var descrip = new List<string>
  147. {
  148. //row.Get<ManufacturingPacket,String>(c=>c.Level.Code),
  149. //row.Get<ManufacturingPacket,String>(c=>c.Zone.Code),
  150. string.IsNullOrEmpty(location) ? row.Get<ManufacturingPacket, string>(c => c.SetoutLink.Location) : location
  151. };
  152. model.Description = string.Join(" / ", descrip.Where(x => !string.IsNullOrWhiteSpace(x))).Trim();
  153. model.TemplateID = row.Get<ManufacturingPacket, Guid>(c => c.ManufacturingTemplateLink.ID);
  154. model.Image = GetBarCode(row);
  155. //model.IsSelected = packet.ID.ToString() == CurrentKanbanID;
  156. model.Tags = priority ? new[] { "PRIORITY" } : new string[] { };
  157. model.Category = section.ToString(); // packet.StageLink.SectionID.ToString();
  158. model.ColorKey =
  159. Entity.IsEntityLinkValid<ManufacturingPacket, PurchaseOrderItemLink>(x => x.OrderItem, row) &&
  160. row.Get<ManufacturingPacket, DateTime>(c => c.OrderItem.ReceivedDate).IsEmpty() ? ORDER_COLOR :
  161. priority ? PRIORITY_COLOR :
  162. !Pending ? GetColor(duedate.IsEmpty() ? DateTime.Today : duedate, estdate.IsEmpty() ? DateTime.Today : estdate) : QA_COLOR;
  163. model.SelectedColor = model.ColorKey; // packet.ID.ToString() == CurrentKanbanID ? SELECTED_COLOR : model.ColorKey;
  164. model.SharedColor = station.Equals(-1) ? SHARED_COLOR : model.ColorKey;
  165. model.Checked = IsChecked;
  166. model.SetoutID = row.Get<ManufacturingPacket, Guid>(c => c.SetoutLink.ID);
  167. model.Assignee = station.ToString();
  168. var ratio = 1.0F / (station == -1 ? (double)columns.Count : 1.0F);
  169. var percentleft = (100.0F - stage.Get<ManufacturingPacketStage, double>(c => c.PercentageComplete)) / 100.0F;
  170. model.Status = string.Format("({0:F2} hours)",
  171. qty * stage.Get<ManufacturingPacketStage, TimeSpan>(c => c.Time).TotalHours * ratio *
  172. percentleft); //packet.StageLink.ID.Equals(Guid.Empty) ? " " : Pending ? "PENDING" /*GetQualityStatus(quality)*/ : String.Format("{0:F0}%", percentage);
  173. model.Flags = row.Get<ManufacturingPacket, bool>(c => c.Distributed)
  174. ? !sectionid.Equals(section) ? string.IsNullOrEmpty(pktsection) ? "" : pktsection.ToUpper().Trim() : "DISTRIB"
  175. : "";
  176. model.GroupID = row.Get<ManufacturingPacket, Guid>(c => c.SetoutLink.Group.ID);
  177. var groupname = row.Get<ManufacturingPacket, string>(c => c.SetoutLink.Group.Name);
  178. model.GroupName = !string.IsNullOrWhiteSpace(groupname) ?
  179. row.Get<ManufacturingPacket, string>(c => c.SetoutLink.Group.Job.JobNumber) + ": " + groupname
  180. : "";
  181. Kanbans.Add(model);
  182. }
  183. catch (Exception e)
  184. {
  185. Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
  186. }
  187. }
  188. private TimeSpan CalcTime(IEnumerable<ManufacturingKanban> kanbans)
  189. {
  190. double hours = 0.0F;
  191. var ids = kanbans.Select(x => Guid.Parse(x.ID));
  192. foreach (var id in ids)
  193. {
  194. var packet = Packets.Rows.FirstOrDefault(r => r.Get<ManufacturingPacket, Guid>(c => c.ID).Equals(id));
  195. var stage = Stages.Rows.FirstOrDefault(r => r.Get<ManufacturingPacketStage, Guid>(c => c.Parent.ID).Equals(id));
  196. var ratio = 1.0F / (stage.Get<ManufacturingPacketStage, int>(c => c.Station) == -1 ? (double)columns.Count : 1.0F);
  197. var percentleft = (100.0F - stage.Get<ManufacturingPacketStage, double>(c => c.PercentageComplete)) / 100.0F;
  198. hours += packet.Get<ManufacturingPacket, int>(c => c.Quantity) *
  199. stage.Get<ManufacturingPacketStage, TimeSpan>(c => c.Time).TotalHours *
  200. ratio * percentleft;
  201. }
  202. return TimeSpan.FromHours(hours);
  203. }
  204. private void ReloadPackets(bool reloaddata)
  205. {
  206. using (new WaitCursor())
  207. {
  208. var checks = Kanbans.Where(x => x.Checked).Select(x => x.ID).ToArray();
  209. Kanbans.Clear();
  210. if (reloaddata && Sections.SelectedValue != null)
  211. {
  212. var sectionid = (Guid)Sections.SelectedValue; // CurrentSection != null ? CurrentSection.ID : CoreUtils.FullGuid;
  213. Stages = new Client<ManufacturingPacketStage>().Query(
  214. new Filter<ManufacturingPacketStage>(x => x.ManufacturingSectionLink.ID).IsEqualTo(sectionid).And(x => x.Completed)
  215. .IsEqualTo(DateTime.MinValue),
  216. Columns.None<ManufacturingPacketStage>().Add(
  217. x => x.ID,
  218. x => x.Parent.ID,
  219. x => x.ManufacturingSectionLink.ID,
  220. x => x.Station,
  221. x => x.QualityStatus,
  222. x => x.PercentageComplete,
  223. x => x.Time,
  224. x => x.Started
  225. )
  226. );
  227. //Stages = stagetable.Rows.Select(x => x.ToObject<ManufacturingPacketStage>()).ToArray();
  228. var filter = new Filter<ManufacturingPacket>(x => x.Completed).IsEqualTo(DateTime.MinValue)
  229. .And(x => x.Archived).IsEqualTo(DateTime.MinValue)
  230. .And(x => x.OnHold).IsEqualTo(false);
  231. var sectfilter = new Filter<ManufacturingPacket>(x => x.StageLink.SectionID).IsEqualTo(sectionid).Or(x => x.Distributed)
  232. .IsEqualTo(true);
  233. filter.Ands.Add(sectfilter);
  234. var columns = Columns.None<ManufacturingPacket>();
  235. var iprops = DatabaseSchema.Properties(typeof(ManufacturingPacket)).Where(x =>
  236. !x.Name.Equals("CustomAttributes") && !x.Name.Equals("Stages") && !x.Name.Equals("Time") && !x.Name.Equals("ActualTime") &&
  237. !x.Name.Equals("TimeRemaining"));
  238. foreach (var iprop in iprops)
  239. columns.Add(iprop.Name);
  240. Packets = new Client<ManufacturingPacket>().Query(
  241. filter,
  242. columns,
  243. //new Columns<ManufacturingPacket>(
  244. // x => x.ID,
  245. // x => x.Serial,
  246. // x => x.Title,
  247. // x => x.Quantity,
  248. // x => x.SetoutLink.Number,
  249. // x => x.SetoutLink.JobLink.JobNumber,
  250. // x => x.SetoutLink.JobLink.Name,
  251. // x => x.DueDate,
  252. // x => x.SetoutLink.Location,
  253. // x => x.SetoutLink.Reference,
  254. // x => x.Priority,
  255. // x => x.OrderItem.ID,
  256. // x => x.EstimatedDate,
  257. // x => x.Distributed,
  258. // x => x.StageLink.SectionID,
  259. // x => x.StageLink.Section,
  260. // x => x.BarcodePrinted,
  261. // x => x.BarcodeType
  262. // ),
  263. new SortOrder<ManufacturingPacket>(x => x.Priority, SortDirection.Descending).ThenBy(x => x.SetoutLink.Number)
  264. );
  265. //Packets = table.Rows.Select(x => x.ToObject<ManufacturingPacket>()).ToArray();
  266. }
  267. if (Packets != null)
  268. foreach (var row in Packets.Rows)
  269. CreateKanban(row, false);
  270. Pending.ItemsSource = null;
  271. var pendings = Kanbans.Where(x => x.Assignee.Equals("0")).OrderBy(x => x.Tags.Contains("PRIORITY") ? 0 : 1).ThenBy(x => x.DueDate);
  272. Pending.ItemsSource = pendings;
  273. Task.Run(() =>
  274. {
  275. var time = CalcTime(pendings).TotalHours;
  276. Dispatcher.Invoke(() => { Hours.Content = string.Format("{0:F2} hrs", time); });
  277. });
  278. foreach (var column in columns)
  279. {
  280. column.Item3.ItemsSource = null;
  281. var items = Kanbans.Where(x => x.Assignee.Equals("-1") || x.Assignee.Equals(column.Item5.ToString()))
  282. .OrderBy(x => x.Tags.Contains("PRIORITY") ? 0 : 1).ThenBy(x => x.DueDate);
  283. column.Item3.ItemsSource = items;
  284. column.Item6.IsChecked = false;
  285. Task.Run(() =>
  286. {
  287. var time = CalcTime(items).TotalHours;
  288. Dispatcher.Invoke(() => { column.Item7.Content = string.Format("{0:F2} hrs", time); });
  289. });
  290. }
  291. }
  292. }
  293. private void ReloadSections()
  294. {
  295. _sections = new Client<ManufacturingSection>().Query(
  296. new Filter<ManufacturingSection>(x => x.Hidden).IsEqualTo(false),
  297. Columns.None<ManufacturingSection>().Add(
  298. x => x.ID,
  299. x => x.Factory.Name,
  300. x => x.Name,
  301. x => x.Stations
  302. ),
  303. new SortOrder<ManufacturingSection>(x => x.Factory.Sequence).ThenBy(x => x.Sequence)
  304. );
  305. }
  306. protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
  307. {
  308. base.OnRenderSizeChanged(sizeInfo);
  309. var width = sizeInfo.NewSize.Width;
  310. SetWidths(width);
  311. }
  312. private void SetWidths(double width)
  313. {
  314. double stations = Stations.ColumnDefinitions.Count;
  315. var desiredwidth = (width - 5.0F) / (stations + 1.0F);
  316. if (desiredwidth < 300.0F)
  317. desiredwidth = 300.0F;
  318. //Sections.Width = desiredwidth;
  319. Pending.Width = desiredwidth;
  320. Stations.Width = stations * desiredwidth;
  321. }
  322. private void Sections_SelectionChanged(object sender, SelectionChangedEventArgs e)
  323. {
  324. if (e.AddedItems.Count == 0)
  325. return;
  326. var pair = (KeyValuePair<Guid, string>)e.AddedItems[0];
  327. var sectionid = pair.Key;
  328. ReloadColumns(sectionid);
  329. if (IsReady)
  330. new UserConfiguration<ManufacturingAllocationSettings>().Save(new ManufacturingAllocationSettings { Section = pair.Key });
  331. }
  332. private void ReloadColumns(Guid sectionid)
  333. {
  334. // Delete all existing lists and Grid Rows
  335. foreach (var column in columns)
  336. {
  337. Stations.Children.Remove(column.Item1);
  338. Stations.Children.Remove(column.Item3);
  339. Stations.ColumnDefinitions.Remove(column.Item4);
  340. }
  341. columns.Clear();
  342. var history = new Client<ManufacturingHistory>().Query(
  343. new Filter<ManufacturingHistory>(x => x.Section.ID).IsEqualTo(sectionid).And(x => x.Date)
  344. .IsGreaterThanOrEqualTo(DateTime.Today.AddDays(-7)),
  345. Columns.None<ManufacturingHistory>().Add(
  346. x => x.Station,
  347. x => x.Employee.Name
  348. ),
  349. new SortOrder<ManufacturingHistory>(x => x.Station).ThenBy(x => x.LastUpdate)
  350. );
  351. var section = _sections.Rows.First(r => r.Get<ManufacturingSection, Guid>(x => x.ID).Equals(sectionid));
  352. var stations = section.Get<ManufacturingSection, int>(x => x.Stations);
  353. for (var iStation = 0; iStation < stations; iStation++)
  354. {
  355. var row = history.Rows.LastOrDefault(r => r.Get<ManufacturingHistory, int>(c => c.Station).Equals(iStation + 1));
  356. var empname = row != null ? row.Get<ManufacturingHistory, string>(x => x.Employee.Name) : string.Format("Station {0}", iStation + 1);
  357. var Column = new ColumnDefinition { Width = new GridLength(1.0F, GridUnitType.Star) };
  358. Stations.ColumnDefinitions.Add(Column);
  359. // Create a Border
  360. var Border = new Border();
  361. Border.BorderBrush = new SolidColorBrush(Colors.Gray);
  362. Border.BorderThickness = new Thickness(0);
  363. Border.CornerRadius = new CornerRadius(5, 5, 0, 0);
  364. Border.Margin = new Thickness(0, 0, 2, 2);
  365. Border.SetValue(Grid.RowProperty, 0);
  366. Border.SetValue(Grid.ColumnProperty, iStation);
  367. Border.Height = 30.0F;
  368. Stations.Children.Add(Border);
  369. var grid = new Grid();
  370. grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0F, GridUnitType.Auto) });
  371. grid.ColumnDefinitions.Add(new ColumnDefinition
  372. {
  373. Width = new GridLength(iStation == stations - 1 && Security.IsAllowed<CanViewFactorySettings>() ? 30.0F : 0.0F,
  374. GridUnitType.Pixel)
  375. });
  376. grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0F, GridUnitType.Star) });
  377. grid.ColumnDefinitions.Add(new ColumnDefinition
  378. {
  379. Width = new GridLength(iStation == stations - 1 && Security.IsAllowed<CanViewFactorySettings>() ? 30.0F : 0.0F,
  380. GridUnitType.Pixel)
  381. });
  382. grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0F, GridUnitType.Auto) });
  383. Border.Child = grid;
  384. var checkborder = new Border();
  385. checkborder.BorderBrush = new SolidColorBrush(Colors.Gray);
  386. checkborder.BorderThickness = new Thickness(0.75);
  387. checkborder.CornerRadius = new CornerRadius(5, 0, 0, 0);
  388. checkborder.Margin = new Thickness(0, 0, 2, 0);
  389. checkborder.SetValue(Grid.RowProperty, 0);
  390. checkborder.SetValue(Grid.ColumnProperty, 0);
  391. grid.Children.Add(checkborder);
  392. var check = new CheckBox();
  393. check.Margin = new Thickness(14, 0, 17, 0);
  394. check.SetValue(Grid.ColumnProperty, 0);
  395. check.Checked += List_Checked;
  396. check.Unchecked += List_Checked;
  397. check.VerticalAlignment = VerticalAlignment.Center;
  398. checkborder.Child = check;
  399. var remove = new Button();
  400. remove.Margin = new Thickness(0, 0, 2, 0);
  401. remove.SetValue(Grid.RowProperty, 0);
  402. remove.SetValue(Grid.ColumnProperty, 1);
  403. remove.Content = "-";
  404. remove.Click += Remove_Click;
  405. grid.Children.Add(remove);
  406. var labelborder = new Border();
  407. labelborder.BorderBrush = new SolidColorBrush(Colors.Gray);
  408. labelborder.BorderThickness = new Thickness(0.75);
  409. labelborder.CornerRadius = new CornerRadius(0, 0, 0, 0);
  410. labelborder.Margin = new Thickness(0, 0, 2, 0);
  411. labelborder.SetValue(Grid.RowProperty, 0);
  412. labelborder.SetValue(Grid.ColumnProperty, 2);
  413. grid.Children.Add(labelborder);
  414. var Label = new Label();
  415. Label.SetValue(Grid.ColumnProperty, 1);
  416. Label.Content = empname;
  417. Label.HorizontalContentAlignment = HorizontalAlignment.Center;
  418. Label.VerticalContentAlignment = VerticalAlignment.Center;
  419. labelborder.Child = Label;
  420. var add = new Button();
  421. add.Margin = new Thickness(0, 0, 2, 0);
  422. add.SetValue(Grid.RowProperty, 0);
  423. add.SetValue(Grid.ColumnProperty, 3);
  424. add.Content = "+";
  425. add.Click += Add_Click;
  426. grid.Children.Add(add);
  427. var hoursborder = new Border();
  428. hoursborder.BorderBrush = new SolidColorBrush(Colors.Gray);
  429. hoursborder.BorderThickness = new Thickness(0.75);
  430. hoursborder.CornerRadius = new CornerRadius(0, 5, 0, 0);
  431. hoursborder.Margin = new Thickness(0, 0, 0, 0);
  432. hoursborder.SetValue(Grid.RowProperty, 0);
  433. hoursborder.SetValue(Grid.ColumnProperty, 4);
  434. grid.Children.Add(hoursborder);
  435. var hours = new Label();
  436. hours.SetValue(Grid.ColumnProperty, 2);
  437. hours.Content = string.Format("({0} hours)", 0.0F);
  438. hours.HorizontalContentAlignment = HorizontalAlignment.Center;
  439. hours.VerticalContentAlignment = VerticalAlignment.Center;
  440. hoursborder.Child = hours;
  441. var Items = new ListBox();
  442. Items.Margin = new Thickness(0, 0, 2, 2);
  443. Items.SetValue(Grid.RowProperty, 1);
  444. Items.SetValue(Grid.ColumnProperty, iStation);
  445. Items.ItemTemplate = (DataTemplate)Resources["Packet"];
  446. Items.HorizontalContentAlignment = HorizontalAlignment.Stretch;
  447. Items.SetValue(ScrollViewer.HorizontalScrollBarVisibilityProperty, ScrollBarVisibility.Disabled);
  448. Items.SetValue(VirtualizingPanel.IsVirtualizingProperty, true);
  449. Items.SetValue(VirtualizingPanel.VirtualizationModeProperty, VirtualizationMode.Recycling);
  450. Items.PreviewMouseRightButtonDown += Items_PreviewMouseRightButtonDown;
  451. Items.PreviewMouseDown += Items_PreviewMouseDown;
  452. Items.SelectionChanged += Items_SelectionChanged;
  453. Stations.Children.Add(Items);
  454. check.Tag = Items;
  455. remove.Tag = Items;
  456. var column = new Tuple<Border, Label, ListBox, ColumnDefinition, int, CheckBox, Label>(Border, Label, Items, Column, iStation + 1,
  457. check,
  458. hours);
  459. columns.Add(column);
  460. }
  461. SetWidths(ActualWidth);
  462. ReloadPackets(true);
  463. }
  464. private void Items_SelectionChanged(object sender, SelectionChangedEventArgs e)
  465. {
  466. if (e.AddedItems.Count > 0)
  467. current = sender as ListBox;
  468. }
  469. private void Items_PreviewMouseDown(object sender, MouseButtonEventArgs e)
  470. {
  471. current = sender as ListBox;
  472. }
  473. private void Items_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
  474. {
  475. current = sender as ListBox;
  476. }
  477. private void Add_Click(object sender, RoutedEventArgs e)
  478. {
  479. var sectionid = (Guid)Sections.SelectedValue;
  480. var section = new Client<ManufacturingSection>().Load(new Filter<ManufacturingSection>(x => x.ID).IsEqualTo(sectionid)).FirstOrDefault();
  481. if (section != null)
  482. {
  483. section.Stations += 1;
  484. new Client<ManufacturingSection>().Save(section, "Added Station");
  485. ReloadSections();
  486. ReloadColumns(section.ID);
  487. }
  488. }
  489. private void Remove_Click(object sender, RoutedEventArgs e)
  490. {
  491. var sectionid = (Guid)Sections.SelectedValue;
  492. var section = new Client<ManufacturingSection>().Load(new Filter<ManufacturingSection>(x => x.ID).IsEqualTo(sectionid)).FirstOrDefault();
  493. if (section != null)
  494. {
  495. if (section.Stations < 2)
  496. {
  497. MessageBox.Show("There must be at least one station available in each section!");
  498. return;
  499. }
  500. var button = sender as Button;
  501. var listbox = button.Tag as ListBox;
  502. var kanbans = listbox.ItemsSource as IEnumerable<ManufacturingKanban>;
  503. if (kanbans.Any(x => !x.Assignee.Equals("-1")))
  504. {
  505. MessageBox.Show("Please clear out all packets before removing this station!");
  506. return;
  507. }
  508. section.Stations -= 1;
  509. new Client<ManufacturingSection>().Save(section, "Removed Station");
  510. ReloadSections();
  511. ReloadColumns(section.ID);
  512. }
  513. }
  514. private void CardSelected(object sender, MouseButtonEventArgs e)
  515. {
  516. }
  517. private void CardPreviewMouseWheel(object sender, MouseWheelEventArgs e)
  518. {
  519. }
  520. private void CardChecked(object sender, RoutedEventArgs e)
  521. {
  522. }
  523. private void PacketMenu_Opened(object sender, RoutedEventArgs e)
  524. {
  525. var menu = sender as ContextMenu;
  526. var kanban = menu.Tag as ManufacturingKanban;
  527. var assign = menu.Items[0] as MenuItem;
  528. var revert = menu.Items[1] as MenuItem;
  529. var separator = menu.Items[2] as Separator;
  530. var distribute = menu.Items[3] as MenuItem;
  531. var undistribute = menu.Items[4] as MenuItem;
  532. var separator2 = menu.Items[5] as Separator;
  533. var share = menu.Items[6] as MenuItem;
  534. var unshare = menu.Items[7] as MenuItem;
  535. assign.Visibility = kanban.Assignee.Equals("-1") ? Visibility.Collapsed : Visibility.Visible;
  536. revert.Visibility = kanban.Assignee.Equals("0") ? Visibility.Collapsed : Visibility.Visible;
  537. distribute.Visibility = Security.IsAllowed<CanDistributePackets>() ? Visibility.Visible : Visibility.Collapsed;
  538. undistribute.Visibility = distribute.Visibility;
  539. separator2.Visibility = distribute.Visibility;
  540. share.Visibility = kanban.Assignee.Equals("-1") ? Visibility.Collapsed : Visibility.Visible;
  541. unshare.Visibility = kanban.Assignee.Equals("-1") ? Visibility.Visible : Visibility.Collapsed;
  542. assign.Items.Clear();
  543. foreach (var column in columns)
  544. {
  545. var item = new MenuItem { Header = column.Item2.Content, Tag = column.Item5 };
  546. item.Click += SetStation_Click;
  547. assign.Items.Add(item);
  548. }
  549. }
  550. private IEnumerable<ManufacturingKanban> CheckedKanbans(ListBox listbox)
  551. {
  552. var kanbans = listbox.ItemsSource as IEnumerable<ManufacturingKanban>;
  553. var result = kanbans.Where(x => x.Checked);
  554. if (!result.Any())
  555. result = new[] { listbox.SelectedValue as ManufacturingKanban };
  556. return result;
  557. }
  558. private IEnumerable<ManufacturingPacket> CheckedPackets(ListBox listbox)
  559. {
  560. var kanbans = CheckedKanbans(listbox).Select(x => Guid.Parse(x.ID));
  561. var packets = Packets.Rows.Where(r => kanbans.Contains(r.Get<ManufacturingPacket, Guid>(c => c.ID)));
  562. return packets.Select(x => x.ToObject<ManufacturingPacket>());
  563. }
  564. private IEnumerable<ManufacturingPacketStage> CheckedStages(ListBox listbox)
  565. {
  566. var kanbans = CheckedKanbans(listbox).Select(x => Guid.Parse(x.ID));
  567. var selstages = Stages.Rows.Where(r =>
  568. kanbans.Contains(r.Get<ManufacturingPacketStage, Guid>(c => c.Parent.ID)) &&
  569. r.Get<ManufacturingPacketStage, Guid>(c => c.ManufacturingSectionLink.ID).Equals(_section));
  570. return selstages.Select(x => x.ToObject<ManufacturingPacketStage>());
  571. }
  572. private Tuple<Border, Label, ListBox, ColumnDefinition, int, CheckBox, Label> GetColumn(object sender)
  573. {
  574. var menu = sender as MenuItem;
  575. Logger.Send(LogType.Information, ClientFactory.UserID, string.Format("GetColumn: Menu is {0}", menu != null ? menu.Header : "null"));
  576. var context = menu.Parent as ContextMenu;
  577. Logger.Send(LogType.Information, ClientFactory.UserID, string.Format("GetColumn: Context is {0}", context != null ? "ok" : "null"));
  578. var border = context.PlacementTarget as Border;
  579. Logger.Send(LogType.Information, ClientFactory.UserID, string.Format("GetColumn: Border is {0}", border != null ? "ok" : "null"));
  580. var kanban = menu.Tag as ManufacturingKanban;
  581. Logger.Send(LogType.Information, ClientFactory.UserID,
  582. string.Format("GetColumn: kanban is {0}", kanban != null ? kanban.Description : "null"));
  583. var column = columns.FirstOrDefault(x => x.Item3 == current);
  584. Logger.Send(LogType.Information, ClientFactory.UserID, string.Format("GetColumn: column is {0}", column != null ? "ok" : "null"));
  585. return column;
  586. }
  587. private void SetStation_Click(object sender, RoutedEventArgs e)
  588. {
  589. var menu = sender as MenuItem;
  590. var station = (int)menu.Tag;
  591. Logger.Send(LogType.Information, ClientFactory.UserID, string.Format("Allocating: Station is {0}", station));
  592. var column = GetColumn(menu.Parent);
  593. var list = column == null ? Pending : column.Item3;
  594. //Logger.Send(LogType.Information, ClientFactory.UserID, String.Format("Allocating: Column is {0}", column.Item2.Content));
  595. var stages = CheckedStages(list).ToArray();
  596. Logger.Send(LogType.Information, ClientFactory.UserID, string.Format("Allocating: Packet Count is {0}", stages.Length));
  597. Logger.Send(LogType.Information, ClientFactory.UserID,
  598. string.Format("Allocating: {0}", string.Join(", ", stages.Select(x => x.Parent.Serial))));
  599. foreach (var stage in stages)
  600. {
  601. stage.Station = station;
  602. if (stage.Started.Equals(DateTime.MinValue))
  603. stage.Started = DateTime.Now;
  604. }
  605. using (new WaitCursor())
  606. {
  607. Logger.Send(LogType.Information, ClientFactory.UserID,
  608. string.Format("Allocating: Updating {0} items", stages.Where(x => x.IsChanged()).ToArray().Length));
  609. new Client<ManufacturingPacketStage>().Save(stages, string.Format("Assigned to Station {0}", station));
  610. }
  611. Refresh();
  612. }
  613. private void Revert_Click(object sender, RoutedEventArgs e)
  614. {
  615. var column = GetColumn(sender);
  616. var stages = CheckedStages(column != null ? column.Item3 : Pending).ToArray();
  617. var bDeleteStarted = false;
  618. foreach (var stage in stages)
  619. {
  620. if (stage.PercentageComplete > 0.0F)
  621. bDeleteStarted = true;
  622. stage.Station = 0;
  623. stage.Started = DateTime.MinValue;
  624. }
  625. if (bDeleteStarted)
  626. bDeleteStarted =
  627. MessageBox.Show("Some items have already been started.\n\nRemove these packets anyway?", "Confirm", MessageBoxButton.YesNo) ==
  628. MessageBoxResult.Yes;
  629. using (new WaitCursor())
  630. {
  631. var updates = stages.Where(x => bDeleteStarted ? true : x.PercentageComplete == 0.0F).ToArray();
  632. new Client<ManufacturingPacketStage>().Save(updates, "Reverted to Pending Status");
  633. }
  634. Refresh();
  635. }
  636. private void Distribute_Click(object sender, RoutedEventArgs e)
  637. {
  638. var column = GetColumn(sender);
  639. var packets = CheckedPackets(column != null ? column.Item3 : Pending).ToArray();
  640. foreach (var packet in packets)
  641. packet.Distributed = true;
  642. using (new WaitCursor())
  643. {
  644. new Client<ManufacturingPacket>().Save(packets, "Set Distributed Flag");
  645. }
  646. Refresh();
  647. }
  648. private void ClearDistributed_Click(object sender, RoutedEventArgs e)
  649. {
  650. var column = GetColumn(sender);
  651. var packets = CheckedPackets(column != null ? column.Item3 : Pending).ToArray();
  652. foreach (var packet in packets)
  653. packet.Distributed = false;
  654. using (new WaitCursor())
  655. {
  656. new Client<ManufacturingPacket>().Save(packets, "Cleared Distributed Flag");
  657. }
  658. Refresh();
  659. }
  660. private void SetShared_Click(object sender, RoutedEventArgs e)
  661. {
  662. var column = GetColumn(sender);
  663. var stages = CheckedStages(column != null ? column.Item3 : Pending);
  664. foreach (var stage in stages)
  665. {
  666. stage.Station = -1;
  667. if (stage.Started.Equals(DateTime.MinValue))
  668. stage.Started = DateTime.Now;
  669. }
  670. using (new WaitCursor())
  671. {
  672. new Client<ManufacturingPacketStage>().Save(stages, "Cleared Shared Flag");
  673. }
  674. Refresh();
  675. }
  676. private void ClearShared_Click(object sender, RoutedEventArgs e)
  677. {
  678. var column = GetColumn(sender);
  679. var stages = CheckedStages(column != null ? column.Item3 : Pending);
  680. foreach (var stage in stages)
  681. stage.Station = column.Item5;
  682. using (new WaitCursor())
  683. {
  684. new Client<ManufacturingPacketStage>().Save(stages, "Cleared Shared Flag");
  685. }
  686. Refresh();
  687. }
  688. private void List_Checked(object sender, RoutedEventArgs e)
  689. {
  690. var check = sender as CheckBox;
  691. var list = check.Tag as ListBox;
  692. var kanbans = list.ItemsSource as IEnumerable<ManufacturingKanban>;
  693. foreach (var kanban in kanbans)
  694. kanban.Checked = check.IsChecked == true;
  695. list.ItemsSource = null;
  696. list.ItemsSource = kanbans;
  697. }
  698. }
  699. }