ProblemsDockGrid.cs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Windows.Controls;
  6. using System.Windows.Media.Imaging;
  7. using com.healthmarketscience.jackcess.query;
  8. using Comal.Classes;
  9. using InABox.Clients;
  10. using InABox.Core;
  11. using InABox.DynamicGrid;
  12. using InABox.Wpf;
  13. using InABox.WPF;
  14. namespace PRSDesktop;
  15. public class ProblemsDockGrid : DynamicDataGrid<Problems>
  16. {
  17. protected override void Init()
  18. {
  19. base.Init();
  20. HiddenColumns.Add(x=>x.Problem.Notes);
  21. HiddenColumns.Add(x=>x.Problem.AssignedTo.Code);
  22. ActionColumns.Add(new DynamicImageColumn(TypeImage)
  23. {
  24. Position = DynamicActionColumnPosition.Start,
  25. Filters = IMAGES.Keys.Select(x=>x.Name.Split('.').Last()).ToArray(),
  26. FilterRecord = TypeFilter
  27. });
  28. ActionColumns.Add(new DynamicTextColumn(GetLastNote) { Position = DynamicActionColumnPosition.End, Width = 0, HeaderText = "Issues" });
  29. ActionColumns.Add(new DynamicTextColumn(GetAssignedTo) { Position = DynamicActionColumnPosition.End, Width = 100, HeaderText="Assigned To", Alignment = Alignment.MiddleCenter});
  30. ActionColumns.Add(new DynamicMenuColumn(ProblemMenu) { Position = DynamicActionColumnPosition.End });
  31. AddButton("Add Note", PRSDesktop.Resources.notification.AsBitmapImage(), AddNote);
  32. AddButton("Assign To", PRSDesktop.Resources.employee.AsBitmapImage(), AssignTo);
  33. AddButton("Mark Resolved", PRSDesktop.Resources.delete.AsBitmapImage(), MarkResolved,
  34. position: DynamicGridButtonPosition.Right);
  35. }
  36. private bool TypeFilter(CoreRow row, string[] filter)
  37. {
  38. string typename = row.Get<Problems, string>(x => x.Type);
  39. return filter.Contains(typename);
  40. }
  41. private object? GetAssignedTo(CoreRow? row) => row?.Get<Problems, string>(x => x.Problem.AssignedTo.Code);
  42. private object? GetLastNote(CoreRow? row) => row?.Get<Problems, string[]>(x => x.Problem.Notes).LastOrDefault();
  43. protected override void DoReconfigure(DynamicGridOptions options)
  44. {
  45. base.DoReconfigure(options);
  46. options.FilterRows = true;
  47. options.MultiSelect = true;
  48. }
  49. protected override DynamicGridColumns LoadColumns()
  50. {
  51. var result = new DynamicGridColumns();
  52. result.Add<Problems, string>(x => x.Code, 150, "Code", "", Alignment.MiddleLeft);
  53. result.Add<Problems, string>(x => x.Description, 0, "Description", "", Alignment.MiddleLeft);
  54. return result;
  55. }
  56. private static readonly Dictionary<Type, BitmapImage?> IMAGES = new()
  57. {
  58. { typeof(Bill), PRSDesktop.Resources.bill.AsBitmapImage() },
  59. { typeof(Activity), PRSDesktop.Resources.assignments.AsBitmapImage() },
  60. { typeof(ProductStyle), PRSDesktop.Resources.palette.AsBitmapImage() },
  61. { typeof(Product), PRSDesktop.Resources.product.AsBitmapImage() },
  62. { typeof(CostSheet), PRSDesktop.Resources.costsheet.AsBitmapImage() },
  63. { typeof(Kit), PRSDesktop.Resources.kit.AsBitmapImage() },
  64. { typeof(JobBillOfMaterialsItem), PRSDesktop.Resources.box_sml.AsBitmapImage() },
  65. { typeof(JobRequisitionItem), PRSDesktop.Resources.requisition.AsBitmapImage() },
  66. { typeof(ManufacturingPacket), PRSDesktop.Resources.factory.AsBitmapImage() },
  67. };
  68. private BitmapImage? TypeImage(CoreRow? row)
  69. {
  70. var _type = row?.Get<Problems, string>(x => x.Type) ?? "";
  71. var _key = IMAGES.Keys.FirstOrDefault(x => string.Equals(x.Name.Split('.').Last(), _type));
  72. return _key != null
  73. ? IMAGES[_key]
  74. : null;
  75. }
  76. private void ProblemMenu(DynamicMenuColumn menu, CoreRow? row)
  77. {
  78. menu.AddItem("Add Note", null, AddNote);
  79. menu.AddItem("Assign To...", null, AssignTo);
  80. menu.AddSeparator();
  81. menu.AddItem("Edit Item", null, EitItem);
  82. menu.AddSeparator();
  83. menu.AddItem("Mark as Resolved", null, MarkResolved);
  84. }
  85. private Type? GetType(CoreRow? row)
  86. {
  87. var _name = row?.Get<Problems, string>(x => x.Type) ?? "";
  88. var _type = IMAGES.Keys.FirstOrDefault(x => string.Equals(x.Name.Split('.').Last(), _name));
  89. return _type;
  90. }
  91. private IProblems<ManagedProblem>? GetItem(CoreRow? row)
  92. {
  93. var _type = GetType(row);
  94. if (_type == null)
  95. return null;
  96. var _id = row.Get<Problems, Guid>(x => x.ID);
  97. var item = ClientFactory.CreateClient(_type).Query(
  98. Filter.Create(_type, "ID", Operator.IsEqualTo, _id),
  99. Columns.Local(_type),
  100. null
  101. ).Rows.FirstOrDefault()?.ToObject(_type) as IProblems<ManagedProblem>;
  102. return item;
  103. }
  104. private void AddNote(CoreRow[] rows)
  105. {
  106. var _items = rows.Select(GetItem).Where(x => x != null).ToArray();
  107. if (!_items.Any())
  108. return;
  109. var _note = "";
  110. if (TextBoxDialog.Execute("Add Problem Note", ref _note))
  111. {
  112. Dictionary<Type, List<IProblems<ManagedProblem>>> _updates = new();
  113. foreach (var _item in _items)
  114. {
  115. if (_item == null)
  116. continue;
  117. var _notes = _item.Problem.Notes?.ToList() ?? new List<string>();
  118. _notes.Add(_note);
  119. _item.Problem.Notes = _notes.ToArray();
  120. var _type = _item.GetType();
  121. if (!_updates.ContainsKey(_type))
  122. _updates[_type] = new List<IProblems<ManagedProblem>>();
  123. _updates[_type].Add(_item);
  124. }
  125. Progress.ShowModal("Adding Notes", progress =>
  126. {
  127. foreach (var _update in _updates)
  128. {
  129. progress.Report($"Adding note to {_update.Value.Count} {new Inflector.Inflector(new CultureInfo("en")).Pluralize(_update.Key.Name.Split('.').Last()).SplitCamelCase()}");
  130. ClientFactory.CreateClient(_update.Key).Save(_update.Value, "Added Isse note");
  131. }
  132. });
  133. Refresh(false, true);
  134. }
  135. }
  136. private bool AddNote(Button button, CoreRow[] rows)
  137. {
  138. AddNote(rows);
  139. return false;
  140. }
  141. private void AddNote(CoreRow? row)
  142. {
  143. if (row == null)
  144. return;
  145. AddNote([row]);
  146. }
  147. private void MarkResolved(CoreRow?[] rows)
  148. {
  149. var _items = rows.Select(GetItem).Where(x => x != null).ToArray();
  150. if (!_items.Any())
  151. return;
  152. Dictionary<Type, List<IProblems<ManagedProblem>>> _updates = new();
  153. foreach (var _item in _items)
  154. {
  155. if (_item == null)
  156. continue;
  157. _item.Problem.Resolved = DateTime.Now;
  158. var _type = _item.GetType();
  159. if (!_updates.ContainsKey(_type))
  160. _updates[_type] = new List<IProblems<ManagedProblem>>();
  161. _updates[_type].Add(_item);
  162. }
  163. Progress.ShowModal("Resolving items", progress =>
  164. {
  165. foreach (var _update in _updates)
  166. {
  167. progress.Report($"Resolving {_update.Value.Count} {new Inflector.Inflector(new CultureInfo("en")).Pluralize(_update.Key.Name.Split('.').Last()).SplitCamelCase()}");
  168. ClientFactory.CreateClient(_update.Key).Save(_update.Value, "Issue marked as resolved");
  169. }
  170. });
  171. Refresh(false, true);
  172. }
  173. private void MarkResolved(CoreRow? row)
  174. {
  175. if (row == null)
  176. return;
  177. MarkResolved([row]);
  178. }
  179. private bool MarkResolved(Button button, CoreRow[] rows)
  180. {
  181. if (MessageWindow.ShowYesNo("Mark Selected Issues as resolved?","Confirm"))
  182. MarkResolved(rows);
  183. return false;
  184. }
  185. private void AssignTo(CoreRow[] rows)
  186. {
  187. var _items = rows.Select(GetItem).ToArray();
  188. if (!_items.Any())
  189. return;
  190. var _dlg = new MultiSelectDialog<Employee>(LookupFactory.DefineFilter<Employee>(), null, false);
  191. if (_dlg.ShowDialog())
  192. {
  193. Dictionary<Type, List<IProblems<ManagedProblem>>> _updates = new();
  194. foreach (var _item in _items)
  195. {
  196. if (_item == null)
  197. continue;
  198. _item.Problem.AssignedTo.ID = _dlg.IDs().FirstOrDefault();
  199. var _type = _item.GetType();
  200. if (!_updates.ContainsKey(_type))
  201. _updates[_type] = new List<IProblems<ManagedProblem>>();
  202. _updates[_type].Add(_item);
  203. }
  204. Progress.ShowModal("Reassigning items", progress =>
  205. {
  206. foreach (var _update in _updates)
  207. {
  208. progress.Report($"Reassigning {_update.Value.Count} {new Inflector.Inflector(new CultureInfo("en")).Pluralize(_update.Key.Name.Split('.').Last()).SplitCamelCase()}");
  209. ClientFactory.CreateClient(_update.Key).Save(_update.Value, "Reassigning Problem");
  210. }
  211. });
  212. Refresh(false, true);
  213. }
  214. }
  215. private bool AssignTo(Button button, CoreRow[] rows)
  216. {
  217. AssignTo(rows);
  218. return false;
  219. }
  220. private void AssignTo(CoreRow? row)
  221. {
  222. if (row != null)
  223. return;
  224. AssignTo([ row ]);
  225. }
  226. protected override void DoDoubleClick(object sender, DynamicGridCellClickEventArgs args)
  227. {
  228. base.DoDoubleClick(sender, args);
  229. if (args.Row == null)
  230. return;
  231. EitItem(args.Row);
  232. }
  233. private void EitItem(CoreRow? row)
  234. {
  235. var _type = GetType(row);
  236. if (_type == null)
  237. return;
  238. var _item = GetItem(row);
  239. if (_item == null)
  240. return;
  241. var _grid = DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), _type);
  242. if (_grid.EditItems([ _item ]))
  243. Refresh(false,true);
  244. }
  245. }