KanbanStore.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System.Text;
  4. using System.Text.RegularExpressions;
  5. using Comal.Classes;
  6. using InABox.Clients;
  7. using InABox.Core;
  8. using InABox.Database;
  9. using System;
  10. namespace Comal.Stores;
  11. public class ServerKanbanSubscriberSet(IEnumerable<Guid> kanbanids, IProvider provider) : BaseKanbanSubscriberSet(kanbanids)
  12. {
  13. protected override void DoSave(IEnumerable<KanbanSubscriber> updates)
  14. => provider.Save(updates);
  15. protected override void DoDelete(KanbanSubscriber[] deletes)
  16. => provider.Delete(deletes,"");
  17. protected override CoreTable DoQuery(Filter<KanbanSubscriber> filter, Columns<KanbanSubscriber> columns)
  18. => provider.Query(filter, columns);
  19. }
  20. internal class KanbanStore : ScheduleActionStore<Kanban>
  21. {
  22. private void CheckNotifications(Kanban entity)
  23. {
  24. if (entity.HasOriginalValue(x => x.Completed) && !entity.Completed.IsEmpty())
  25. {
  26. // Find all notifications linked to this task
  27. var notifications = Provider.Query(
  28. new Filter<Notification>(x => x.EntityType).IsEqualTo(typeof(Kanban).EntityName())
  29. .And(x => x.EntityID).IsEqualTo(entity.ID)
  30. .And(x => x.Closed).IsEqualTo(DateTime.MinValue),
  31. Columns.None<Notification>().Add(x => x.ID)
  32. ).ToArray<Notification>();
  33. foreach (var notification in notifications)
  34. notification.Closed = entity.Completed;
  35. if (notifications.Any())
  36. FindSubStore<Notification>().Save(notifications, "");
  37. }
  38. }
  39. private void NotifyUsers(Kanban entity)
  40. {
  41. var Subject = $"Updated Task: {entity.Title} (Due: {entity.DueDate:dd MMM yy})";
  42. var emps = Provider.Query(
  43. new Filter<KanbanSubscriber>(x => x.Kanban.ID).IsEqualTo(entity.ID),
  44. Columns.None<KanbanSubscriber>().Add(x => x.Employee.ID, x => x.Employee.UserLink.ID));
  45. var senderrow = emps.Rows.FirstOrDefault(r => r.Get<KanbanSubscriber, Guid>(c => c.Employee.UserLink.ID).Equals(UserGuid));
  46. var senderid = senderrow?.Get<KanbanSubscriber, Guid>(c => c.Employee.ID) ?? Guid.Empty;
  47. var notifications = new List<Notification>();
  48. foreach (var row in emps.Rows)
  49. {
  50. var userid = row.Get<KanbanSubscriber, Guid>(c => c.Employee.UserLink.ID);
  51. if (userid != UserGuid)
  52. {
  53. var notification = new Notification();
  54. notification.Employee.ID = row.Get<KanbanSubscriber, Guid>(c => c.Employee.ID);
  55. notification.Sender.ID = senderid;
  56. notification.Title = Subject;
  57. notification.EntityType = typeof(Kanban).EntityName();
  58. notification.EntityID = entity.ID;
  59. notification.Description = BuildDescription(entity);
  60. notifications.Add(notification);
  61. }
  62. }
  63. if (emps.Rows.Count == 0)
  64. {
  65. var userID = Provider.Query(
  66. new Filter<Employee>(x => x.ID).IsEqualTo(entity.EmployeeLink.ID),
  67. Columns.None<Employee>().Add(x => x.UserLink.ID)
  68. ).Rows.FirstOrDefault()?.Get<Employee, Guid>(x => x.UserLink.ID);
  69. if(userID != UserGuid)
  70. {
  71. Notification notification = new Notification();
  72. notification.Employee.ID = entity.EmployeeLink.ID;
  73. notification.Sender.ID = entity.ManagerLink.ID;
  74. notification.Title = Subject;
  75. notification.EntityType = typeof(Kanban).EntityName();
  76. notification.EntityID = entity.ID;
  77. notification.Description = BuildDescription(entity);
  78. notifications.Add(notification);
  79. }
  80. }
  81. if (notifications.Any())
  82. FindSubStore<Notification>().Save(notifications, "");
  83. }
  84. private string BuildDescription(Kanban entity)
  85. {
  86. var notes = string.Join("\r\n", entity.Notes)
  87. .Split(new[] { "===================================\r\n" }, StringSplitOptions.RemoveEmptyEntries);
  88. var summary = notes.LastOrDefault();
  89. if (string.IsNullOrEmpty(summary))
  90. summary = entity.Summary;
  91. if (string.IsNullOrEmpty(summary))
  92. summary = "";
  93. summary = Regex.Replace(summary.Replace("\r", "\n"), @"( |\r?\n|\r|\n)\1+", "$1");
  94. var sb = new StringBuilder();
  95. if (entity.EmployeeLink.HasOriginalValue(x => x.ID))
  96. sb.AppendLine("The above task has been assigned to you. Please check the relevant details, and action as required.");
  97. else
  98. sb.AppendLine("The above task has been changed. Please check the relevant details, and action as required.");
  99. if (entity.HasOriginalValue(x => x.Status))
  100. {
  101. sb.AppendLine();
  102. sb.AppendLine(string.Format("- The task has progressed from {0} to {1}.", entity.GetOriginalValue(x => x.Status),
  103. entity.Status));
  104. }
  105. if (entity.HasOriginalValue(x => x.DueDate) && entity.GetOriginalValue(x => x.DueDate) != DateTime.MinValue)
  106. {
  107. sb.AppendLine();
  108. sb.AppendLine(string.Format("- The due date for the task has been changed from {0} to {1}.",
  109. entity.OriginalValueList["DueDate"],
  110. entity.DueDate));
  111. }
  112. if (entity.HasOriginalValue(x => x.Notes) && entity.Notes.Count() > 1)
  113. {
  114. sb.AppendLine("- The notes for the task have been updated as follows:");
  115. foreach (var line in summary.Split('\n'))
  116. sb.AppendLine(" " + line);
  117. }
  118. return sb.ToString();
  119. }
  120. private void CheckNotificationRequired(Kanban entity)
  121. {
  122. if (entity.EmployeeLink.HasOriginalValue(x => x.ID) || entity.HasOriginalValue(x => x.Notes) ||
  123. entity.HasOriginalValue(x => x.Status) ||
  124. entity.HasOriginalValue(x => x.Summary) || entity.HasOriginalValue(x => x.DueDate))
  125. {
  126. NotifyUsers(entity);
  127. }
  128. else if (entity.ID != Guid.Empty && entity.HasOriginalValue(x => x.ID))
  129. {
  130. if (entity.GetOriginalValue<Kanban, Guid>("ID") == Guid.Empty)
  131. {
  132. NotifyUsers(entity);
  133. }
  134. }
  135. }
  136. protected override void BeforeSave(Kanban entity)
  137. {
  138. base.BeforeSave(entity);
  139. if (entity.Completed.IsEmpty())
  140. entity.Closed = DateTime.MinValue;
  141. }
  142. private void CheckKanbanTypeForms(Kanban kanban)
  143. {
  144. if(!kanban.Type.HasOriginalValue(x => x.ID))
  145. {
  146. return;
  147. }
  148. var kanbanForms = Provider.Query(
  149. new Filter<KanbanForm>(x => x.Parent.ID).IsEqualTo(kanban.ID)).Rows.Select(x => x.ToObject<KanbanForm>()).ToArray();
  150. var toDelete = kanbanForms.Where(x => string.IsNullOrWhiteSpace(x.FormData)).ToArray();
  151. Provider.Delete(toDelete, UserID);
  152. var kanbanTypeForms = Provider.Query(
  153. new Filter<KanbanTypeForm>(x => x.Type.ID).IsEqualTo(kanban.Type.ID)
  154. .And(x => x.Form.AppliesTo).IsEqualTo(nameof(Kanban)));
  155. var newForms = new List<KanbanForm>();
  156. foreach(var row in kanbanTypeForms.Rows)
  157. {
  158. var formID = row.Get<KanbanTypeForm, Guid>(x => x.Form.ID);
  159. if (!(kanbanForms.Any(x => x.Form.ID == formID) && toDelete.All(x => x.Form.ID != formID)))
  160. {
  161. var kanbanForm = new KanbanForm();
  162. kanbanForm.Form.ID = formID;
  163. kanbanForm.Parent.ID = kanban.ID;
  164. newForms.Add(kanbanForm);
  165. }
  166. }
  167. Provider.Save(newForms);
  168. }
  169. protected override void AfterSave(Kanban entity)
  170. {
  171. base.AfterSave(entity);
  172. CheckNotifications(entity);
  173. CheckNotificationRequired(entity);
  174. CheckKanbanTypeForms(entity);
  175. CheckSubscribers(entity);
  176. }
  177. private void CheckSubscribers(Kanban entity)
  178. {
  179. var changedEmployee = entity.HasOriginalValue(x => x.EmployeeLink.ID);
  180. var changedManager = entity.HasOriginalValue(x => x.ManagerLink.ID);
  181. if (changedEmployee || changedManager)
  182. {
  183. var set = new ServerKanbanSubscriberSet([entity.ID], Provider);
  184. if (changedEmployee)
  185. set.EnsureAssignee(entity.ID, entity.EmployeeLink.ID);
  186. if (changedManager)
  187. set.EnsureManager(entity.ID, entity.ManagerLink.ID);
  188. set.Save();
  189. }
  190. }
  191. }