NotificationUtils.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using Comal.Classes;
  7. using InABox.Clients;
  8. using InABox.Core;
  9. using InABox.DynamicGrid;
  10. using InABox.WPF;
  11. namespace PRSDesktop
  12. {
  13. public static class NotificationUtils
  14. {
  15. private static Entity LoadEntity(Type type, Guid id, params string[] columnnames)
  16. {
  17. var filter = Activator.CreateInstance(typeof(Filter<>).MakeGenericType(type), "ID", Operator.IsEqualTo, id);
  18. IColumns columns = null;
  19. if (columnnames.Any())
  20. {
  21. columns = Activator.CreateInstance(typeof(Columns<>).MakeGenericType(type)) as IColumns;
  22. foreach (var columnname in columnnames)
  23. columns.Add(columnname);
  24. }
  25. var table = ClientFactory.CreateClient(type).Query(filter, columns);
  26. var result = table.Rows.FirstOrDefault()?.ToObject(type) as Entity;
  27. return result;
  28. }
  29. private static IDynamicGrid FindDataGrid(Type type)
  30. {
  31. var gridtypes = CoreUtils.TypeList(
  32. AppDomain.CurrentDomain.GetAssemblies(),
  33. myType =>
  34. myType.IsClass
  35. && !myType.IsAbstract
  36. && !myType.IsGenericType
  37. && myType.BaseType != null
  38. && myType.BaseType.Name == typeof(DynamicDataGrid<>).Name
  39. && myType.ContainsInheritedGenericType(type)
  40. ).ToArray();
  41. var gridtype = gridtypes.Any() ? gridtypes.First() : typeof(DynamicDataGrid<>).MakeGenericType(type);
  42. var grid = Activator.CreateInstance(gridtype) as IDynamicGrid;
  43. return grid;
  44. }
  45. private static bool PerformAction(Guid[] ids, Func<Notification, bool> action)
  46. {
  47. if (!ids.Any())
  48. //if (Notifications.SelectedRows?.FirstOrDefault() == null)
  49. {
  50. MessageBox.Show("Please select a message first!");
  51. return false;
  52. }
  53. var updates = new List<Notification>();
  54. Notification[] notifications = { };
  55. var columns = new Columns<Notification>().Default(ColumnType.IncludeForeignKeys);
  56. columns.Add(x => x.EntityID);
  57. columns.Add(x => x.EntityType);
  58. columns.Add(x => x.Closed);
  59. columns.Add(x => x.Sender.Name);
  60. columns.Add(x => x.Description);
  61. using (new WaitCursor())
  62. {
  63. notifications = new Client<Notification>().Query(
  64. new Filter<Notification>(x => x.ID).InList(ids),
  65. columns
  66. ).Rows.Select(x => x.ToObject<Notification>()).ToArray();
  67. }
  68. foreach (var notification in notifications)
  69. if (action.Invoke(notification))
  70. updates.Add(notification);
  71. if (updates.Any())
  72. {
  73. using (new WaitCursor())
  74. {
  75. new Client<Notification>().Save(updates, "", (o, e) => { });
  76. }
  77. return true;
  78. }
  79. return false;
  80. }
  81. public static bool IsDigitalForm(string name)
  82. {
  83. if (string.IsNullOrWhiteSpace(name))
  84. return false;
  85. var type = CoreUtils.GetEntity(name);
  86. var result = type.GetInterfaces().Contains(typeof(IDigitalFormInstance));
  87. return result;
  88. }
  89. public static Type GetEntityType(string name)
  90. {
  91. if (string.IsNullOrWhiteSpace(name))
  92. return null;
  93. if (!IsDigitalForm(name))
  94. return CoreUtils.GetEntity(name);
  95. var form = CoreUtils.GetEntity(name);
  96. var parent = CoreUtils.GetProperty(form, "Parent");
  97. var type = parent.PropertyType.GetInheritedGenericTypeArguments().FirstOrDefault();
  98. return type;
  99. }
  100. public static bool MakeVisible(FrameworkElement element, float left, float right, params bool[] visibleconditions)
  101. {
  102. var visible = true;
  103. foreach (var condition in visibleconditions)
  104. visible = visible && condition;
  105. element.Visibility = visible ? Visibility.Visible : Visibility.Collapsed;
  106. element.Margin = new Thickness(left, element.Margin.Top, right, element.Margin.Bottom);
  107. return visible;
  108. }
  109. public static bool ViewEntity(Guid[] ids)
  110. {
  111. return PerformAction(ids, notification =>
  112. {
  113. var type = GetEntityType(notification.EntityType);
  114. var id = notification.EntityID;
  115. if (IsDigitalForm(notification.EntityType))
  116. {
  117. var form =
  118. LoadEntity(CoreUtils.GetEntity(notification.EntityType), notification.EntityID, "ID", "Parent.ID") as IDigitalFormInstance;
  119. id = form.ParentID();
  120. }
  121. var entity = LoadEntity(type, id);
  122. var grid = FindDataGrid(type);
  123. return grid.EditItems(new object[] { entity });
  124. });
  125. }
  126. public static bool ViewForm(Guid[] ids)
  127. {
  128. return PerformAction(ids, notification =>
  129. {
  130. var type = CoreUtils.GetEntity(notification.EntityType);
  131. var form = LoadEntity(type, notification.EntityID);
  132. if(form is IDigitalFormInstance formInstance)
  133. {
  134. if(DynamicFormEditWindow.EditDigitalForm(formInstance, out var dataModel)){
  135. dataModel.Update(null);
  136. return true;
  137. }
  138. }
  139. return false;
  140. });
  141. }
  142. public static bool ReplyOrForward(Guid[] ids, string prefix, bool selectrecipient, bool sentfolder)
  143. {
  144. return PerformAction(ids, notification =>
  145. {
  146. var sb = new StringBuilder(string.Format("\n\nAt {0:HH:mmtt} on {0:dd MMM yy}, {1} wrote:\n", notification.Created,
  147. notification.Sender.Name));
  148. var desc = string.IsNullOrWhiteSpace(notification.Description) ? "" : CoreUtils.StripHTML(notification.Description);
  149. foreach (var line in desc.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).Where(x => !string.IsNullOrWhiteSpace(x)))
  150. sb.AppendFormat("> {0}\n", line.Trim());
  151. var form = new NotificationForm
  152. {
  153. Subject = string.Format("{0} {1}", prefix, notification.Title),
  154. Recipient = selectrecipient ? sentfolder ? notification.Employee.ID : notification.Sender.ID : Guid.Empty,
  155. JobID = notification.Job.ID,
  156. Description = sb.ToString()
  157. };
  158. if (form.ShowDialog() == true)
  159. {
  160. notification.Description = string.Format("{0}\nReplied to Message", notification.Description);
  161. if (MessageBox.Show("Do you want to dismiss this message?", "Task Created", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
  162. notification.Closed = DateTime.Now;
  163. return true;
  164. }
  165. return false;
  166. });
  167. }
  168. public static bool CreateTask(Guid[] ids, Guid employeeid)
  169. {
  170. return PerformAction(ids, notification =>
  171. {
  172. var task = new Kanban
  173. {
  174. Title = notification.Title,
  175. Notes = new[] { notification.Description },
  176. Category = "Open"
  177. };
  178. task.JobLink.ID = notification.Job.ID;
  179. task.EmployeeLink.ID = employeeid;
  180. task.ManagerLink.ID = notification.Sender.ID;
  181. var kg = new KanbanGrid();
  182. if (kg.EditItems(new[] { task }))
  183. {
  184. using (new WaitCursor())
  185. {
  186. task = new Client<Kanban>().Load(new Filter<Kanban>(x => x.ID).IsEqualTo(task.ID)).FirstOrDefault();
  187. }
  188. notification.Description = string.Format("{0}\nCreated Task for {1}", notification.Description, task.EmployeeLink.Name);
  189. //notification.Kanban.ID = task.ID;
  190. if (MessageBox.Show("Do you want to dismiss this message?", "Task Created", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
  191. notification.Closed = DateTime.Now;
  192. return true;
  193. }
  194. return false;
  195. });
  196. }
  197. public static bool CreateRequi(Guid[] ids, Guid employeeid)
  198. {
  199. return PerformAction(ids, notification =>
  200. {
  201. var requi = new Requisition
  202. {
  203. Title = notification.Title,
  204. Notes = new[] { notification.Description }
  205. };
  206. requi.JobLink.ID = notification.Job.ID;
  207. requi.Employee.ID = employeeid;
  208. requi.RequestedBy.ID = notification.Sender.ID;
  209. var grid = new DynamicDataGrid<Requisition>();
  210. if (grid.EditItems(new[] { requi }))
  211. {
  212. notification.Description = string.Format("{0}\nCreated Requi# {1}", notification.Description, requi.Number);
  213. //notification.Requisition.ID = requi.ID;
  214. if (MessageBox.Show("Do you want to dismiss this message?", "Requisition Created", MessageBoxButton.YesNo) ==
  215. MessageBoxResult.Yes)
  216. notification.Closed = DateTime.Now;
  217. return true;
  218. }
  219. return false;
  220. });
  221. }
  222. public static bool CreateDelivery(Guid[] ids)
  223. {
  224. return PerformAction(ids, notification =>
  225. {
  226. var delivery = new Delivery
  227. {
  228. Notes = notification.Description,
  229. Due = DateTime.Today.AddDays(1)
  230. };
  231. delivery.Employee.ID = notification.Sender.ID;
  232. delivery.Job.ID = notification.Job.ID;
  233. var grid = new DynamicDataGrid<Delivery>();
  234. if (grid.EditItems(new[] { delivery }))
  235. {
  236. notification.Description = string.Format("{0}\nCreated Delivery# {1}", notification.Description, delivery.Number);
  237. //notification.Delivery.ID = delivery.ID;
  238. if (MessageBox.Show("Do you want to dismiss this message?", "Delivery Created", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
  239. notification.Closed = DateTime.Now;
  240. return true;
  241. }
  242. return false;
  243. });
  244. }
  245. public static bool AttachToJob(Guid[] ids)
  246. {
  247. return PerformAction(ids, notification =>
  248. {
  249. var jobs = new MultiSelectDialog<Job>(
  250. null,
  251. new Columns<Job>(x => x.ID), //new System.Linq.Expressions.Expression<Func<Job, object>>[] { x=>x.ID },
  252. false
  253. );
  254. if (jobs.ShowDialog() != true)
  255. return false;
  256. notification.Job.ID = jobs.IDs().First();
  257. return true;
  258. });
  259. }
  260. public static bool ViewJob(Guid[] ids)
  261. {
  262. return PerformAction(ids, notification =>
  263. {
  264. var job = new Client<Job>().Load(new Filter<Job>(x => x.ID).IsEqualTo(notification.Job.ID)).FirstOrDefault();
  265. if (job != null)
  266. FindDataGrid(typeof(Job)).EditItems(new[] { job });
  267. return false;
  268. });
  269. }
  270. public static bool CreateSetout(Guid[] ids)
  271. {
  272. return PerformAction(ids, notification =>
  273. {
  274. var templates = new MultiSelectDialog<ManufacturingTemplate>(
  275. null,
  276. new Columns<ManufacturingTemplate>(x =>
  277. x.ID), //new System.Linq.Expressions.Expression<Func<ManufacturingTemplate, object>>[] { x=>x.ID },
  278. false
  279. );
  280. if (templates.ShowDialog() != true)
  281. return false;
  282. var template = templates.Items().FirstOrDefault();
  283. Setout setout = null;
  284. ManufacturingPacket packet = null;
  285. var pstages = new List<ManufacturingPacketStage>();
  286. using (new WaitCursor())
  287. {
  288. var setoutnumber = string.Format("{0}-{1:yyMMdd}-", notification.Job.JobNumber, DateTime.Today);
  289. var setouts = new Client<Setout>().Query(
  290. new Filter<Setout>(x => x.JobLink.ID).IsEqualTo(notification.Job.ID).And(x => x.Number).BeginsWith(setoutnumber),
  291. new Columns<Setout>(x => x.Number),
  292. new SortOrder<Setout>(x => x.Number)
  293. ).Rows;
  294. var i = 1;
  295. while (setouts.Any(r => r.Get<Setout, string>(c => c.Number).Equals(string.Format("{0}{1:D3}", setoutnumber, i))))
  296. i++;
  297. setout = new Setout
  298. {
  299. Description = notification.Description,
  300. Reference = notification.Title,
  301. Number = string.Format("{0}{1:D2}", setoutnumber, i)
  302. };
  303. setout.JobLink.ID = notification.Job.ID;
  304. new Client<Setout>().Save(setout, "Created from Notification");
  305. packet = new ManufacturingPacket();
  306. packet.SetoutLink.ID = setout.ID;
  307. //packet.JobLink.ID = notification.Job.ID;
  308. packet.Serial = string.Format("{0}-001", setout.Number);
  309. packet.Group = template.Factory.Name;
  310. packet.ManufacturingTemplateLink.ID = template.ID;
  311. packet.ManufacturingTemplateLink.Code = template.Code;
  312. packet.Title = notification.Title;
  313. packet.Quantity = 1;
  314. new Client<ManufacturingPacket>().Save(packet, "Created from Notification");
  315. var tstages = new Client<ManufacturingTemplateStage>().Load(
  316. new Filter<ManufacturingTemplateStage>(x => x.Template.ID).IsEqualTo(packet.ManufacturingTemplateLink.ID),
  317. new SortOrder<ManufacturingTemplateStage>(x => x.Sequence)
  318. );
  319. foreach (var tstage in tstages)
  320. {
  321. var pstage = new ManufacturingPacketStage
  322. {
  323. Time = tstage.Time,
  324. Sequence = tstage.Sequence,
  325. SequenceType = tstage.SequenceType,
  326. Started = DateTime.MinValue,
  327. PercentageComplete = 0.0F,
  328. Completed = DateTime.MinValue,
  329. QualityChecks = tstage.QualityChecks,
  330. QualityStatus = QualityStatus.NotChecked,
  331. QualityNotes = ""
  332. };
  333. var section = new Client<ManufacturingSection>()
  334. .Load(new Filter<ManufacturingSection>(x => x.ID).IsEqualTo(tstage.Section.ID))
  335. .FirstOrDefault();
  336. if (section != null)
  337. {
  338. pstage.ManufacturingSectionLink.ID = tstage.Section.ID;
  339. pstage.ManufacturingSectionLink.Name = tstage.Section.Name;
  340. }
  341. pstages.Add(pstage);
  342. }
  343. new Client<ManufacturingPacketStage>().Save(pstages, "Created from Notification");
  344. }
  345. var grid = new DynamicDataGrid<Setout>();
  346. if (grid.EditItems(new[] { setout }))
  347. {
  348. notification.Description = string.Format("{0}\nCreated Setout# {1}", notification.Description, setout.Number);
  349. //notification.Setout.ID = setout.ID;
  350. if (MessageBox.Show("Do you want to dismiss this message?", "Setout Created", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
  351. notification.Closed = DateTime.Now;
  352. return true;
  353. }
  354. using (new WaitCursor())
  355. {
  356. // Cascade on PAcket / PacketStage should** take care of the child records
  357. // Be good to keep an eye on that!
  358. new Client<Setout>().Delete(setout, "");
  359. }
  360. return false;
  361. });
  362. }
  363. public static bool Archive(Guid[] ids)
  364. {
  365. return PerformAction(ids, notification =>
  366. {
  367. notification.Closed = DateTime.Now;
  368. return true;
  369. });
  370. }
  371. public static bool Reopen(Guid[] ids)
  372. {
  373. return PerformAction(ids, notification =>
  374. {
  375. notification.Closed = DateTime.MinValue;
  376. return true;
  377. });
  378. }
  379. }
  380. }