ProblemsDockGrid.cs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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 com.sun.istack.@internal.localization;
  9. using Comal.Classes;
  10. using InABox.Clients;
  11. using InABox.Core;
  12. using InABox.DynamicGrid;
  13. using InABox.Wpf;
  14. using InABox.WPF;
  15. namespace PRSDesktop;
  16. public class ProblemsDockGrid : DynamicDataGrid<Problems>
  17. {
  18. protected override void Init()
  19. {
  20. base.Init();
  21. HiddenColumns.Add(x=>x.Problem.Notes);
  22. HiddenColumns.Add(x=>x.Problem.AssignedTo.Code);
  23. ActionColumns.Add(new DynamicImageColumn(TypeImage)
  24. {
  25. Position = DynamicActionColumnPosition.Start,
  26. GetFilter = () => new StaticColumnFilter<Type?>(GetType, IMAGES.Keys.Select(x => new Tuple<string, Type?>(x.Name, x)).ToArray())
  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", InABox.Wpf.Resources.delete.AsBitmapImage(), MarkResolved,
  34. position: DynamicGridButtonPosition.Right);
  35. }
  36. private Type? GetType(CoreRow row)
  37. {
  38. var typeName = row.Get<Problems, string>(x => x.Type);
  39. return IMAGES.Keys.FirstOrDefault(x => x.Name == 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>(x => x.Code, 150, "Code", "", Alignment.MiddleLeft);
  53. result.Add<Problems>(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 string? TypeText(CoreRow? row)
  77. {
  78. return row?.Get<Problems, string>(x => x.Type) ?? "";
  79. }
  80. private void ProblemMenu(DynamicMenuColumn menu, CoreRow? row)
  81. {
  82. menu.AddItem("Add Note", null, AddNote);
  83. menu.AddItem("Assign To...", null, AssignTo);
  84. menu.AddSeparator();
  85. menu.AddItem("Edit Item", null, EditItem);
  86. menu.AddSeparator();
  87. menu.AddItem("Mark as Resolved", null, MarkResolved);
  88. }
  89. private IProblems<ManagedProblem>? GetItem(CoreRow? row)
  90. {
  91. if (row is null) return null;
  92. var _type = GetType(row);
  93. if (_type == null)
  94. return null;
  95. var _id = row.Get<Problems, Guid>(x => x.ID);
  96. var item = ClientFactory.CreateClient(_type).Query(
  97. Filter.Create(_type, "ID", Operator.IsEqualTo, _id),
  98. Columns.Local(_type),
  99. null
  100. ).Rows.FirstOrDefault()?.ToObject(_type) as IProblems<ManagedProblem>;
  101. return item;
  102. }
  103. private void AddNote(CoreRow[] rows)
  104. {
  105. var _items = rows.Select(GetItem).Where(x => x != null).ToArray();
  106. if (!_items.Any())
  107. return;
  108. var _note = "";
  109. if (TextBoxDialog.Execute("Add Problem Note", ref _note))
  110. {
  111. Dictionary<Type, List<IProblems<ManagedProblem>>> _updates = new();
  112. foreach (var _item in _items)
  113. {
  114. if (_item == null)
  115. continue;
  116. var _notes = _item.Problem.Notes?.ToList() ?? new List<string>();
  117. _notes.Add(_note);
  118. _item.Problem.Notes = _notes.ToArray();
  119. var _type = _item.GetType();
  120. if (!_updates.ContainsKey(_type))
  121. _updates[_type] = new List<IProblems<ManagedProblem>>();
  122. _updates[_type].Add(_item);
  123. }
  124. Progress.ShowModal("Adding Notes", progress =>
  125. {
  126. foreach (var _update in _updates)
  127. {
  128. progress.Report($"Adding note to {_update.Value.Count} {new Inflector.Inflector(new CultureInfo("en")).Pluralize(_update.Key.Name.Split('.').Last()).SplitCamelCase()}");
  129. ClientFactory.CreateClient(_update.Key).Save(_update.Value, "Added Isse note");
  130. }
  131. });
  132. Refresh(false, true);
  133. }
  134. }
  135. private bool AddNote(Button button, CoreRow[] rows)
  136. {
  137. AddNote(rows);
  138. return false;
  139. }
  140. private void AddNote(CoreRow? row)
  141. {
  142. if (row == null)
  143. return;
  144. AddNote([row]);
  145. }
  146. private void MarkResolved(CoreRow?[] rows)
  147. {
  148. var _items = rows.Select(GetItem).Where(x => x != null).ToArray();
  149. if (!_items.Any())
  150. return;
  151. Dictionary<Type, List<IProblems<ManagedProblem>>> _updates = new();
  152. foreach (var _item in _items)
  153. {
  154. if (_item == null)
  155. continue;
  156. _item.Problem.Resolved = DateTime.Now;
  157. var _type = _item.GetType();
  158. if (!_updates.ContainsKey(_type))
  159. _updates[_type] = new List<IProblems<ManagedProblem>>();
  160. _updates[_type].Add(_item);
  161. }
  162. Progress.ShowModal("Resolving items", progress =>
  163. {
  164. foreach (var _update in _updates)
  165. {
  166. progress.Report($"Resolving {_update.Value.Count} {new Inflector.Inflector(new CultureInfo("en")).Pluralize(_update.Key.Name.Split('.').Last()).SplitCamelCase()}");
  167. ClientFactory.CreateClient(_update.Key).Save(_update.Value, "Issue marked as resolved");
  168. }
  169. });
  170. Refresh(false, true);
  171. }
  172. private void MarkResolved(CoreRow? row)
  173. {
  174. if (row == null)
  175. return;
  176. MarkResolved([row]);
  177. }
  178. private bool MarkResolved(Button button, CoreRow[] rows)
  179. {
  180. if (MessageWindow.ShowYesNo("Mark Selected Issues as resolved?","Confirm"))
  181. MarkResolved(rows);
  182. return false;
  183. }
  184. private void AssignTo(CoreRow[] rows)
  185. {
  186. var _items = rows.Select(GetItem).ToArray();
  187. if (!_items.Any())
  188. return;
  189. var _dlg = new MultiSelectDialog<Employee>(LookupFactory.DefineFilter<Employee>(), null, false);
  190. if (_dlg.ShowDialog())
  191. {
  192. Dictionary<Type, List<IProblems<ManagedProblem>>> _updates = new();
  193. foreach (var _item in _items)
  194. {
  195. if (_item == null)
  196. continue;
  197. _item.Problem.AssignedTo.ID = _dlg.IDs().FirstOrDefault();
  198. var _type = _item.GetType();
  199. if (!_updates.ContainsKey(_type))
  200. _updates[_type] = new List<IProblems<ManagedProblem>>();
  201. _updates[_type].Add(_item);
  202. }
  203. Progress.ShowModal("Reassigning items", progress =>
  204. {
  205. foreach (var _update in _updates)
  206. {
  207. progress.Report($"Reassigning {_update.Value.Count} {new Inflector.Inflector(new CultureInfo("en")).Pluralize(_update.Key.Name.Split('.').Last()).SplitCamelCase()}");
  208. ClientFactory.CreateClient(_update.Key).Save(_update.Value, "Reassigning Problem");
  209. }
  210. });
  211. Refresh(false, true);
  212. }
  213. }
  214. private bool AssignTo(Button button, CoreRow[] rows)
  215. {
  216. AssignTo(rows);
  217. return false;
  218. }
  219. private void AssignTo(CoreRow? row)
  220. {
  221. if (row is null)
  222. return;
  223. AssignTo([row]);
  224. }
  225. protected override void DoDoubleClick(object sender, DynamicGridCellClickEventArgs args)
  226. {
  227. base.DoDoubleClick(sender, args);
  228. if (args.Row == null)
  229. return;
  230. EditItem(args.Row);
  231. }
  232. private void EditItem(CoreRow? row)
  233. {
  234. if (row is null) return;
  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 ], null, false))
  243. Refresh(false,true);
  244. }
  245. }