From 1e189ee74f94a67cc931e52020d2e72956dcc965 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Tue, 22 Dec 2020 21:02:07 +0000 Subject: [PATCH] --- server/AyaNova/biz/NotifyEventHelper.cs | 279 ++++++++++++++++-------- server/AyaNova/biz/ReviewBiz.cs | 98 +++++---- 2 files changed, 233 insertions(+), 144 deletions(-) diff --git a/server/AyaNova/biz/NotifyEventHelper.cs b/server/AyaNova/biz/NotifyEventHelper.cs index bcf9b052..73346de6 100644 --- a/server/AyaNova/biz/NotifyEventHelper.cs +++ b/server/AyaNova/biz/NotifyEventHelper.cs @@ -119,28 +119,6 @@ namespace AyaNova.Biz }//eom - private static async Task EnsureDefaultInAppUserNotificationSubscriptionExists(long userId, AyContext ct) - { - var defaultsub = await ct.NotifySubscription.FirstOrDefaultAsync(z => z.EventType == NotifyEventType.GeneralNotification && z.UserId == userId && z.DeliveryMethod == NotifyDeliveryMethod.App); - if (defaultsub == null) - { - //NOTE: agevalue and advanced notice settings here will ensure that direct in app notifications with a future delivery date ("deadman" switch deliveries) set in their - //notifyevent.eventdate will deliver on that date and not immediately to support all the things that are direct built in notifications for future dates - //such as for an overdue Review which doesn't have or need it's own notifyeventtype and subscription independently - defaultsub = new NotifySubscription() - { - UserId = userId, - EventType = NotifyEventType.GeneralNotification, - DeliveryMethod = NotifyDeliveryMethod.App, - AgeValue = new TimeSpan(0, 0, 1), - AdvanceNotice = new TimeSpan(0, 0, 1) - }; - await ct.NotifySubscription.AddAsync(defaultsub); - await ct.SaveChangesAsync(); - } - - return defaultsub; - } @@ -299,56 +277,38 @@ namespace AyaNova.Biz //----------------------------------------------- //ObjectAge // - { - var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.ObjectAge && z.AyaType == newObject.AyaType).ToListAsync(); - foreach (var sub in subs) - { - if (TagsMatch(newObject.Tags, sub.Tags)) - { - //Note: age is set by advance notice which is consulted by CoreJobNotify in it's run so the deliver date is not required here only the reference EventDate to check for deliver - //ObjectAge is determined by subscription AgeValue in combo with the EventDate NotifyEvent parameter which together determines at what age from notifyevent.EventDate it's considered for the event to have officially occured - //However delivery is determined by sub.advancenotice so all three values play a part - // - NotifyEvent n = new NotifyEvent() - { - EventType = NotifyEventType.ObjectAge, - UserId = sub.UserId, - AyaType = newObject.AyaType, - ObjectId = newObject.Id, - NotifySubscriptionId = sub.Id, - Name = newObject.Name - }; - await ct.NotifyEvent.AddAsync(n); - log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); - SaveContext = true; - } - } - } + // { + // var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.ObjectAge && z.AyaType == newObject.AyaType).ToListAsync(); + // foreach (var sub in subs) + // { + // if (TagsMatch(newObject.Tags, sub.Tags)) + // { + // //Note: age is set by advance notice which is consulted by CoreJobNotify in it's run so the deliver date is not required here only the reference EventDate to check for deliver + // //ObjectAge is determined by subscription AgeValue in combo with the EventDate NotifyEvent parameter which together determines at what age from notifyevent.EventDate it's considered for the event to have officially occured + // //However delivery is determined by sub.advancenotice so all three values play a part + // // + // NotifyEvent n = new NotifyEvent() + // { + // EventType = NotifyEventType.ObjectAge, + // UserId = sub.UserId, + // AyaType = newObject.AyaType, + // ObjectId = newObject.Id, + // NotifySubscriptionId = sub.Id, + // Name = newObject.Name + // }; + // await ct.NotifyEvent.AddAsync(n); + // log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + // SaveContext = true; + // } + // } + // } //------------------------------------------ //ObjectCreated // // [USER for any type, CUSTOMER for workorder only] / if customer then CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398 - { - var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.ObjectCreated && z.AyaType == newObject.AyaType).ToListAsync(); - foreach (var sub in subs) - { - if (TagsMatch(newObject.Tags, sub.Tags)) - { - NotifyEvent n = new NotifyEvent() - { - EventType = NotifyEventType.ObjectCreated, - UserId = sub.UserId, - AyaType = newObject.AyaType, - ObjectId = newObject.Id, - NotifySubscriptionId = sub.Id, - Name = newObject.Name - }; - await ct.NotifyEvent.AddAsync(n); - log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); - SaveContext = true; - } - } - } + // { + // await ProcessStandardObjectCreatedEvents(newObject, ct); + // } #endregion created processing break; case AyaEvent.Modified: @@ -567,35 +527,7 @@ namespace AyaNova.Biz //------------------------------ // Delete any NotifyEvent records for this exact object - // It's gone and shouldn't have any events left for it - await ClearPriorEventsForObject(ct, newObject.AyaType, newObject.Id); - - - //------------------------------------------ - //ObjectDeleted notification - // - { - var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.ObjectDeleted && z.AyaType == newObject.AyaType).ToListAsync(); - foreach (var sub in subs) - { - if (TagsMatch(newObject.Tags, sub.Tags)) - { - //TODO: On deliver should point to history event log record or take from there and insert into delivery message? - NotifyEvent n = new NotifyEvent() - { - EventType = NotifyEventType.ObjectDeleted, - UserId = sub.UserId, - AyaType = newObject.AyaType, - ObjectId = newObject.Id, - NotifySubscriptionId = sub.Id, - Name = newObject.Name - }; - await ct.NotifyEvent.AddAsync(n); - log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); - SaveContext = true; - } - } - } + await ProcessStandardObjectDeletedEvents(newObject, ct); #endregion deleted processing break; @@ -625,6 +557,159 @@ namespace AyaNova.Biz }//eom + + + + + + /////////////////////////////////////////// + // ENSURE USER HAS IN APP NOTIFICATION + // + // + public static async Task EnsureDefaultInAppUserNotificationSubscriptionExists(long userId, AyContext ct) + { + var defaultsub = await ct.NotifySubscription.FirstOrDefaultAsync(z => z.EventType == NotifyEventType.GeneralNotification && z.UserId == userId && z.DeliveryMethod == NotifyDeliveryMethod.App); + if (defaultsub == null) + { + //NOTE: agevalue and advanced notice settings here will ensure that direct in app notifications with a future delivery date ("deadman" switch deliveries) set in their + //notifyevent.eventdate will deliver on that date and not immediately to support all the things that are direct built in notifications for future dates + //such as for an overdue Review which doesn't have or need it's own notifyeventtype and subscription independently + defaultsub = new NotifySubscription() + { + UserId = userId, + EventType = NotifyEventType.GeneralNotification, + DeliveryMethod = NotifyDeliveryMethod.App, + AgeValue = new TimeSpan(0, 0, 1), + AdvanceNotice = new TimeSpan(0, 0, 1) + }; + await ct.NotifySubscription.AddAsync(defaultsub); + await ct.SaveChangesAsync(); + } + return defaultsub; + } + + + + +///////////////////////////////////////// + // PROCESS STANDARD EVENTS + // + // + public static async Task ProcessStandardObjectEvents(AyaEvent ayaEvent, ICoreBizObjectModel newObject, AyContext ct) + { + switch(ayaEvent){ + case AyaEvent.Created: + await ProcessStandardObjectCreatedEvents(newObject,ct); + break; + case AyaEvent.Deleted: + await ProcessStandardObjectDeletedEvents(newObject,ct); + break; + case AyaEvent.Modified: + await ProcessStandardObjectModifiedEvents(newObject,ct); + break; + } + } + + ///////////////////////////////////////// + // PROCESS STANDARD CREATE NOTIFICATION + // + // + public static async Task ProcessStandardObjectCreatedEvents(ICoreBizObjectModel newObject, AyContext ct) + { + //CREATED SUBSCRIPTIONS + { + var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.ObjectCreated && z.AyaType == newObject.AyaType).ToListAsync(); + foreach (var sub in subs) + { + if (TagsMatch(newObject.Tags, sub.Tags)) + { + NotifyEvent n = new NotifyEvent() + { + EventType = NotifyEventType.ObjectCreated, + UserId = sub.UserId, + AyaType = newObject.AyaType, + ObjectId = newObject.Id, + NotifySubscriptionId = sub.Id, + Name = newObject.Name + }; + await ct.NotifyEvent.AddAsync(n); + log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + await ct.SaveChangesAsync(); + } + } + } + + + //AGE SUBSCRIPTIONS + { + var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.ObjectAge && z.AyaType == newObject.AyaType).ToListAsync(); + foreach (var sub in subs) + { + if (TagsMatch(newObject.Tags, sub.Tags)) + { + //Note: age is set by advance notice which is consulted by CoreJobNotify in it's run so the deliver date is not required here only the reference EventDate to check for deliver + //ObjectAge is determined by subscription AgeValue in combo with the EventDate NotifyEvent parameter which together determines at what age from notifyevent.EventDate it's considered for the event to have officially occured + //However delivery is determined by sub.advancenotice so all three values play a part + // + NotifyEvent n = new NotifyEvent() + { + EventType = NotifyEventType.ObjectAge, + UserId = sub.UserId, + AyaType = newObject.AyaType, + ObjectId = newObject.Id, + NotifySubscriptionId = sub.Id, + Name = newObject.Name + }; + await ct.NotifyEvent.AddAsync(n); + log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + await ct.SaveChangesAsync(); + } + } + } + + + } + + + ///////////////////////////////////////// + // PROCESS STANDARD DELETE NOTIFICATION + // + // + public static async Task ProcessStandardObjectDeletedEvents(ICoreBizObjectModel bizObject, AyContext ct) + { + // It's gone and shouldn't have any events left for it + await ClearPriorEventsForObject(ct, bizObject.AyaType, bizObject.Id); + + + //------------------------------------------ + //ObjectDeleted notification + // + { + var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.ObjectDeleted && z.AyaType == bizObject.AyaType).ToListAsync(); + foreach (var sub in subs) + { + if (TagsMatch(bizObject.Tags, sub.Tags)) + { + //TODO: On deliver should point to history event log record or take from there and insert into delivery message? + NotifyEvent n = new NotifyEvent() + { + EventType = NotifyEventType.ObjectDeleted, + UserId = sub.UserId, + AyaType = bizObject.AyaType, + ObjectId = bizObject.Id, + NotifySubscriptionId = sub.Id, + Name = bizObject.Name + }; + await ct.NotifyEvent.AddAsync(n); + log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + await ct.SaveChangesAsync(); + } + } + } + } + + + ////////////////////////////////// // CLEAN OUT OLD EVENTS // diff --git a/server/AyaNova/biz/ReviewBiz.cs b/server/AyaNova/biz/ReviewBiz.cs index 9c0c43a9..9631baf7 100644 --- a/server/AyaNova/biz/ReviewBiz.cs +++ b/server/AyaNova/biz/ReviewBiz.cs @@ -465,7 +465,7 @@ namespace AyaNova.Biz //////////////////////////////////////////////////////////////////////////////////////////////// // NOTIFICATION PROCESSING // - public async Task HandlePotentialNotificationEvent(AyaEvent ayaEvent, Review proposedObj, Review currentObj) + public async Task HandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj) { ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); if (ServerBootConfig.SEEDING) return; @@ -473,62 +473,66 @@ namespace AyaNova.Biz bool isNew = currentObj == null; - if (ayaEvent == AyaEvent.Deleted) - { - return; - } + //STANDARD EVENTS FOR ALL OBJECTS + await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); + //SPECIFIC EVENTS FOR THIS OBJECT + + //CREATED / MODIFIED if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) { - //Remove prior - await NotifyEventHelper.ClearPriorEventsForObject(ct, newObject.AyaType, newObject.Id, NotifyEventType.GeneralNotification);//assumes only general event for this object type is overdue here - - //set a deadman automatic internal notification if goes past due - var r = (Review)newObject; - - //it not completed yet and not overdue already (which could indicate an import or something) - if (r.CompletedDate == null && r.DueDate > DateTime.UtcNow) + //OVERDUE pseudo event { - var userNotifySub = await EnsureDefaultInAppUserNotificationSubscriptionExists(r.UserId, ct); - NotifySubscription supervisorNotifySub = null; - if (r.UserId != r.AssignedByUserId) - { - supervisorNotifySub = await EnsureDefaultInAppUserNotificationSubscriptionExists(r.AssignedByUserId, ct); - } + //Remove prior + await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, proposedObj.Id, NotifyEventType.GeneralNotification);//assumes only general event for this object type is overdue here - { - NotifyEvent n = new NotifyEvent() - { - EventType = NotifyEventType.GeneralNotification, - UserId = r.UserId, - ObjectId = newObject.Id, - AyaType = AyaType.Review, - NotifySubscriptionId = userNotifySub.Id, - Name = "LT:ReviewOverDue - " + newObject.Name, - EventDate = r.DueDate - }; - await ct.NotifyEvent.AddAsync(n); - log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); - } + //set a deadman automatic internal notification if goes past due + var r = (Review)proposedObj; - if (supervisorNotifySub != null) + //it not completed yet and not overdue already (which could indicate an import or something) + if (r.CompletedDate == null && r.DueDate > DateTime.UtcNow) { - NotifyEvent n = new NotifyEvent() + var userNotifySub = await NotifyEventHelper.EnsureDefaultInAppUserNotificationSubscriptionExists(r.UserId, ct); + NotifySubscription supervisorNotifySub = null; + if (r.UserId != r.AssignedByUserId) { - EventType = NotifyEventType.GeneralNotification, - UserId = r.AssignedByUserId, - ObjectId = newObject.Id, - AyaType = AyaType.Review, - NotifySubscriptionId = supervisorNotifySub.Id, - Name = "LT:ReviewOverDue - " + newObject.Name, - EventDate = r.DueDate - }; - await ct.NotifyEvent.AddAsync(n); - log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + supervisorNotifySub = await NotifyEventHelper.EnsureDefaultInAppUserNotificationSubscriptionExists(r.AssignedByUserId, ct); + } + + { + NotifyEvent n = new NotifyEvent() + { + EventType = NotifyEventType.GeneralNotification, + UserId = r.UserId, + ObjectId = proposedObj.Id, + AyaType = AyaType.Review, + NotifySubscriptionId = userNotifySub.Id, + Name = "LT:ReviewOverDue - " + proposedObj.Name, + EventDate = r.DueDate + }; + await ct.NotifyEvent.AddAsync(n); + log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + } + + if (supervisorNotifySub != null) + { + NotifyEvent n = new NotifyEvent() + { + EventType = NotifyEventType.GeneralNotification, + UserId = r.AssignedByUserId, + ObjectId = proposedObj.Id, + AyaType = AyaType.Review, + NotifySubscriptionId = supervisorNotifySub.Id, + Name = "LT:ReviewOverDue - " + proposedObj.Name, + EventDate = r.DueDate + }; + await ct.NotifyEvent.AddAsync(n); + log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + } } - } - } + }//overdue event + }//custom events for created / modified }