using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Comal.Classes; using InABox.Core; using System; namespace Comal.Stores { public class FormSubscription { public Guid EmployeeID { get; set; } public Guid FormID { get; set; } } public static class FormSubscriptionCache { static FormSubscriptionCache() { Subscriptions = null; } public static FormSubscription[] Subscriptions { get; set; } } public abstract class EntityFormStore : BaseStore where TEntity : EntityForm, new() where TParent : Entity, new() where TParentLink : BaseObject, IEntityLink, new() { private void CheckFormSubscriptionCache() { if (FormSubscriptionCache.Subscriptions == null) { Logger.Send(LogType.Information, UserID, "Refreshing Form Subscription Cache"); var subs = Provider.Query( null, Columns.None().Add(x => x.Employee.ID, x => x.Form.ID) ); FormSubscriptionCache.Subscriptions = subs.Rows.Select(r => new FormSubscription { EmployeeID = r.Get(c => c.Employee.ID), FormID = r.Get(c => c.Form.ID) } ).ToArray(); } } private void CheckFormSubscriptions(TEntity entity) { if (entity is IDigitalFormInstance instance && entity.HasOriginalValue(x=>x.FormCompleted) && entity.GetOriginalValue(x=>x.FormCompleted) == DateTime.MinValue ) { var updates = new List(); CheckFormSubscriptionCache(); var formid = entity.Form.ID; //(Guid)CoreUtils.GetPropertyValue(entity, "Form.ID"); var formname = entity.Form.Description; //(string)CoreUtils.GetPropertyValue(entity, "Form.Description"); var userid = entity.FormCompletedBy.ID; //CoreUtils.GetPropertyValue(entity, "FormCompletedBy.ID"); if (userid == Guid.Empty) userid = UserGuid; var emprow = userid != Guid.Empty ? Provider.Query( new Filter(x => x.UserLink.ID).IsEqualTo(userid), Columns.None().Add(x => x.ID, x => x.Name) ).Rows.FirstOrDefault() : null; var empid = emprow != null ? emprow.Get(x => x.ID) : Guid.Empty; var empname = emprow != null ? emprow.Get(x => x.Name) : UserID; var subscriptions = FormSubscriptionCache.Subscriptions.Where(x => x.FormID == formid).ToArray(); foreach (var subscription in subscriptions) { var notification = new Notification(); notification.Employee.ID = subscription.EmployeeID; notification.Sender.ID = empid; notification.Title = "Form Completed: " + formname; notification.Description = string.Format("{0} has completed a {1} digital form.", empname, formname); notification.EntityType = entity.GetType().EntityName(); notification.EntityID = entity.ID; updates.Add(notification); } if (updates.Any()) FindSubStore().Save(updates, ""); } } protected override void AfterSave(TEntity entity) { base.AfterSave(entity); CheckFormSubscriptions(entity); CheckParentStatus(entity); } private void CheckParentStatus(TEntity entity) { if (entity.HasOriginalValue(x=>x.FormCompleted) || entity.HasOriginalValue(x=>x.FormCancelled)) { bool isFinal = false; TParent? parent = null; Task[] tasks = new Task[] { Task.Run(() => { isFinal = Provider.Query( new Filter(x => x.ID).IsEqualTo(entity.Form.ID), Columns.None().Add(x => x.Final) ).Rows.FirstOrDefault()?.Get(x => x.Final) ?? false; }), Task.Run(() => { parent = Provider.Query( new Filter(x=>x.ID).IsEqualTo(entity.ParentID()), LookupFactory.RequiredColumns() ).Rows .FirstOrDefault()? .ToObject(); }) }; Task.WaitAll(tasks); if (isFinal && (parent != null)) { UpdateParentStatus(entity, parent); if (parent.IsChanged()) FindSubStore().Save(parent, $"{typeof(TParent).EntityName().Split('.').Last()} status updated by {entity.Form.Description}"); } } } protected virtual void UpdateParentStatus(IDigitalFormInstance form, TParent parent) { } } }