NotificationUtils.cs 17 KB

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