ManufacturingAllocationPanel.xaml.cs 37 KB

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