using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using Comal.Classes; using InABox.Core; namespace Comal.Stores { internal class KanbanStore : ScheduleActionStore { private void CheckNotifications(Kanban entity) { if (entity.HasOriginalValue(x => x.Completed) && !entity.Completed.IsEmpty()) { // Find all notifications linked to this task var notifications = Provider.Query( new Filter(x => x.EntityType).IsEqualTo(typeof(Kanban).EntityName()).And(x => x.EntityID).IsEqualTo(entity.ID) .And(x => x.Closed).IsEqualTo(DateTime.MinValue), new Columns(x => x.ID) ).Rows.Select(x => x.ToObject()); foreach (var notification in notifications) notification.Closed = entity.Completed; if (notifications.Any()) FindSubStore().Save(notifications, ""); } } private void NotifyUsers(Kanban entity) { var Subject = string.Format("Updated Task: {0} (Due: {1:dd MMM yy})", entity.Title, entity.DueDate); var emps = Provider.Query( new Filter(x => x.Kanban.ID).IsEqualTo(entity.ID), new Columns(x => x.Employee.ID, x => x.Employee.UserLink.ID)); var senderrow = emps.Rows.FirstOrDefault(r => r.Get(c => c.Employee.UserLink.ID).Equals(UserGuid)); var senderid = senderrow != null ? senderrow.Get(c => c.Employee.ID) : Guid.Empty; var notifications = new List(); foreach (var row in emps.Rows) { var userid = row.Get(c => c.Employee.UserLink.ID); if (userid != UserGuid) { var notification = new Notification(); notification.Employee.ID = row.Get(c => c.Employee.ID); notification.Sender.ID = senderid; notification.Title = Subject; notification.EntityType = typeof(Kanban).EntityName(); notification.EntityID = entity.ID; notification.Description = BuildDescription(entity); notifications.Add(notification); } } if (emps.Rows.Count == 0) { var userID = Provider.Query( new Filter(x => x.ID).IsEqualTo(entity.EmployeeLink.ID), new Columns(x => x.UserLink.ID) ).Rows.FirstOrDefault()?.Get(x => x.UserLink.ID); if(userID != UserGuid) { Notification notification = new Notification(); notification.Employee.ID = entity.EmployeeLink.ID; notification.Sender.ID = entity.ManagerLink.ID; notification.Title = Subject; notification.EntityType = typeof(Kanban).EntityName(); notification.EntityID = entity.ID; notification.Description = BuildDescription(entity); notifications.Add(notification); } } if (notifications.Any()) FindSubStore().Save(notifications, ""); } private string BuildDescription(Kanban entity) { var notes = entity.Notes != null ? string.Join("\r\n", entity.Notes) .Split(new[] { "===================================\r\n" }, StringSplitOptions.RemoveEmptyEntries) : new string[] { }; var summary = notes.LastOrDefault(); if (string.IsNullOrEmpty(summary)) summary = entity.Summary; if (string.IsNullOrEmpty(summary)) summary = ""; summary = Regex.Replace(summary.Replace("\r", "\n"), @"( |\r?\n|\r|\n)\1+", "$1"); var sb = new StringBuilder(); if (entity.EmployeeLink.HasOriginalValue(x => x.ID)) sb.AppendLine("The above task has been assigned to you. Please check the relevant details, and action as required."); else sb.AppendLine("The above task has been changed. Please check the relevant details, and action as required."); if (entity.HasOriginalValue(x => x.Category) && !string.IsNullOrEmpty(entity.GetOriginalValue(x => x.Category))) { sb.AppendLine(); sb.AppendLine(string.Format("- The task has progressed from {0} to {1}.", entity.GetOriginalValue(x => x.Category), entity.Category)); } if (entity.HasOriginalValue(x => x.DueDate) && entity.GetOriginalValue(x => x.DueDate) != DateTime.MinValue) { sb.AppendLine(); sb.AppendLine(string.Format("- The due date for the task has been changed from {0} to {1}.", entity.OriginalValues["DueDate"], entity.DueDate)); } if (entity.HasOriginalValue(x => x.Notes) && entity.Notes.Count() > 1) { sb.AppendLine("- The notes for the task have been updated as follows:"); foreach (var line in summary.Split('\n')) sb.AppendLine(" " + line); } return sb.ToString(); } private void CheckNotificationRequired(Kanban entity) { if (entity.EmployeeLink.HasOriginalValue(x => x.ID) || entity.HasOriginalValue(x => x.Notes) || entity.HasOriginalValue(x => x.Category) || entity.HasOriginalValue(x => x.Summary) || entity.HasOriginalValue(x => x.DueDate)) { NotifyUsers(entity); } else if (entity.ID != Guid.Empty && entity.HasOriginalValue(x => x.ID)) { if (entity.GetOriginalValue("ID") == Guid.Empty) { NotifyUsers(entity); } } } protected override void BeforeSave(Kanban entity) { base.BeforeSave(entity); if (entity.Completed.IsEmpty()) entity.Closed = DateTime.MinValue; } private void CheckKanbanTypeForms(Kanban kanban) { if(!kanban.Type.HasOriginalValue(x => x.ID)) { return; } var kanbanForms = Provider.Query( new Filter(x => x.Parent.ID).IsEqualTo(kanban.ID)).Rows.Select(x => x.ToObject()); var toDelete = kanbanForms.Where(x => string.IsNullOrWhiteSpace(x.FormData)); Provider.Delete(toDelete, UserID); var kanbanTypeForms = Provider.Query( new Filter(x => x.Type.ID).IsEqualTo(kanban.Type.ID) .And(x => x.Form.AppliesTo).IsEqualTo(nameof(Kanban))); var newForms = new List(); foreach(var row in kanbanTypeForms.Rows) { var formID = row.Get(x => x.Form.ID); if (!(kanbanForms.Any(x => x.Form.ID == formID) && !toDelete.Any(x => x.Form.ID == formID))) { var kanbanForm = new KanbanForm(); kanbanForm.Form.ID = formID; kanbanForm.Parent.ID = kanban.ID; newForms.Add(kanbanForm); } } Provider.Save(newForms); } protected override void AfterSave(Kanban entity) { base.AfterSave(entity); CheckNotifications(entity); CheckNotificationRequired(entity); CheckKanbanTypeForms(entity); } } }