This commit is contained in:
@@ -18,549 +18,6 @@ namespace AyaNova.Biz
|
||||
{
|
||||
private static ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger("NotifyEventProcessor");
|
||||
|
||||
//Add operations message
|
||||
internal static async Task AddOpsProblemEvent(string message, Exception ex = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(message) && ex == null)
|
||||
return;
|
||||
|
||||
//Log as a backup in case there is no one to notify and also for the record and support
|
||||
if (ex != null)
|
||||
{
|
||||
//actually, if there is an exception it's already logged anyway so don't re-log it here, just makes dupes
|
||||
// log.LogError(ex, $"Ops problem notification: \"{message}\"");
|
||||
message += $"\nException error: {ExceptionUtil.ExtractAllExceptionMessages(ex)}";
|
||||
}
|
||||
else
|
||||
log.LogWarning($"Ops problem notification: \"{message}\"");
|
||||
|
||||
await AddGeneralNotifyEvent(NotifyEventType.ServerOperationsProblem, message, "OPS");
|
||||
}
|
||||
|
||||
|
||||
//This handles general notification events not requiring a decision or tied to an object that are basically just a immediate message to the user
|
||||
//e.g. ops problems, GeneralNotification, NotifyHealthCheck etc
|
||||
//optional user id to send directly to them
|
||||
internal static async Task AddGeneralNotifyEvent(NotifyEventType eventType, string message, string name, Exception except = null, long userId = 0)
|
||||
{
|
||||
log.LogDebug($"AddGeneralNotifyEvent processing: [type:{eventType}, userId:{userId}, message:{message}]");
|
||||
#if (DEBUG)
|
||||
switch (eventType)
|
||||
{
|
||||
case NotifyEventType.BackupStatus:
|
||||
case NotifyEventType.GeneralNotification:
|
||||
case NotifyEventType.NotifyHealthCheck://created by job processor itself
|
||||
case NotifyEventType.ServerOperationsProblem:
|
||||
break;
|
||||
default://this will likely be a development error, not a production error so no need to log etc
|
||||
throw (new System.NotSupportedException($"NotifyEventProcessor:AddGeneralNotifyEvent - Type of event {eventType} is unexpected and not supported"));
|
||||
}
|
||||
|
||||
if (eventType != NotifyEventType.GeneralNotification && userId != 0)
|
||||
{
|
||||
throw (new System.NotSupportedException($"NotifyEventProcessor:AddGeneralNotifyEvent - event {eventType} was specified with user id {userId} which is unexpected and not supported"));
|
||||
}
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
using (AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext)
|
||||
{
|
||||
|
||||
//General notification goes to a specific user only
|
||||
//no need to consult subscriptions
|
||||
if (eventType == NotifyEventType.GeneralNotification)
|
||||
{
|
||||
if (userId == 0)
|
||||
{
|
||||
//this will likely be a development error, not a production error so no need to log etc
|
||||
throw new System.ArgumentException("NotifyEventProcessor:AddGeneralNotifyEvent: GeneralNotification requires a user id but none was specified");
|
||||
}
|
||||
|
||||
var UserName = await ct.User.AsNoTracking().Where(z => z.Id == userId).Select(z => z.Name).FirstOrDefaultAsync();
|
||||
|
||||
//if they don't have a regular inapp subscription create one now
|
||||
NotifySubscription defaultsub = await EnsureDefaultInAppUserNotificationSubscriptionExists(userId, ct);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
name = UserName;
|
||||
}
|
||||
|
||||
NotifyEvent n = new NotifyEvent() { EventType = eventType, UserId = userId, Message = message, NotifySubscriptionId = defaultsub.Id, Name = name };
|
||||
await ct.NotifyEvent.AddAsync(n);
|
||||
await ct.SaveChangesAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//check subscriptions for event and send accordingly to each user
|
||||
var subs = await ct.NotifySubscription.Where(z => z.EventType == eventType).ToListAsync();
|
||||
|
||||
//append exception message if not null
|
||||
if (except != null)
|
||||
message += $"\nException error: {ExceptionUtil.ExtractAllExceptionMessages(except)}";
|
||||
|
||||
foreach (var sub in subs)
|
||||
{
|
||||
//note flag ~SERVER~ means to client to substitute "Server" translation key text instead
|
||||
NotifyEvent n = new NotifyEvent() { EventType = eventType, UserId = sub.UserId, Message = message, NotifySubscriptionId = sub.Id, Name = "~SERVER~" };
|
||||
await ct.NotifyEvent.AddAsync(n);
|
||||
}
|
||||
if (subs.Count > 0)
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError(ex, $"Error adding general notify event [type:{eventType}, userId:{userId}, message:{message}]");
|
||||
}
|
||||
|
||||
}//eom
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//This is told about an event and then determines if there are any subscriptions related to that event and proceses them accordingly
|
||||
//todo: this should take some kind of general event type like the AyaEvent types (i.e. which CRUD operation is in effect if relevant)
|
||||
//and also a biz object before and after or just before if not a change and also a AyaType
|
||||
|
||||
//then *this* code will go through and look for subscriptions related to that event
|
||||
//this way the biz object code can be "dumb" about notifications in general and just let this code handle it as needed
|
||||
//will iterate the subscriptions and see if any apply here
|
||||
internal static async Task HandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel newObject, ICoreBizObjectModel originalObject = null)
|
||||
{
|
||||
if (ServerBootConfig.SEEDING) return;
|
||||
log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{newObject.AyaType}, AyaEvent:{ayaEvent}]");
|
||||
//set to true if any changes are made to the context (NotifyEvent added)
|
||||
bool SaveContext = false;
|
||||
try
|
||||
{
|
||||
using (AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext)
|
||||
{
|
||||
//short circuit if there are no subscriptions which would be typical of a v8 migrate scenario or fresh import or just not using notification
|
||||
if (!await ct.NotifySubscription.AnyAsync())
|
||||
return;
|
||||
|
||||
//switch through AyaEvent then individual Ayatypes as required for event types
|
||||
switch (ayaEvent)
|
||||
{
|
||||
case AyaEvent.Created:
|
||||
#region Created processing
|
||||
//------------------------------
|
||||
// AyaType Specific created related subscriptions
|
||||
// Note: these are for specific things only in this block
|
||||
// generally being created notifications are further down below
|
||||
switch (newObject.AyaType)
|
||||
{
|
||||
|
||||
case AyaType.Review:
|
||||
{
|
||||
//set a deadman automatic internal notification if goes past due
|
||||
var r = (Review)newObject;
|
||||
|
||||
//if not completed yet and not overdue already (which could indicate an import or something)
|
||||
if (r.CompletedDate == null && r.DueDate > DateTime.UtcNow)
|
||||
{
|
||||
var userNotifySub = await EnsureDefaultInAppUserNotificationSubscriptionExists(r.UserId, ct);
|
||||
NotifySubscription supervisorNotifySub = null;
|
||||
if (r.UserId != r.AssignedByUserId)
|
||||
{
|
||||
supervisorNotifySub = await EnsureDefaultInAppUserNotificationSubscriptionExists(r.AssignedByUserId, ct);
|
||||
}
|
||||
|
||||
{
|
||||
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()}]");
|
||||
}
|
||||
|
||||
if (supervisorNotifySub != null)
|
||||
{
|
||||
NotifyEvent n = new NotifyEvent()
|
||||
{
|
||||
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()}]");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
//AyaTypes with their own special notification related events
|
||||
case AyaType.WorkOrder:
|
||||
{
|
||||
//WorkorderStatusChange
|
||||
{
|
||||
throw new System.NotImplementedException("Awaiting workorder object completion");
|
||||
var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.WorkorderStatusChange).ToListAsync();
|
||||
foreach (var sub in subs)
|
||||
{
|
||||
if (TagsMatch(newObject.Tags, sub.Tags))
|
||||
{
|
||||
|
||||
NotifyEvent n = new NotifyEvent()
|
||||
{
|
||||
EventType = NotifyEventType.ObjectAge,
|
||||
UserId = sub.UserId,
|
||||
ObjectId = newObject.Id,
|
||||
NotifySubscriptionId = sub.Id,
|
||||
//TODO: IdValue=((WorkOrder)newObject).WorkorderStatusId
|
||||
Name = newObject.Name
|
||||
};
|
||||
await ct.NotifyEvent.AddAsync(n);
|
||||
log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]");
|
||||
|
||||
//Note: in same event but for MODIFY below if need to delete old notifyevent here
|
||||
// var deleteEventList = await ct.NotifyEvent.Where(z => z.ObjectId == ev.ObjectId && z.AyaType == ev.AyaType).ToListAsync();
|
||||
// ct.NotifyEvent.RemoveRange(deleteEventList);
|
||||
|
||||
|
||||
SaveContext = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//ScheduledOnWorkorder https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
//ScheduledOnWorkorderImminent https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
//WorkorderFinishStatusOverdue
|
||||
//WorkorderFinished [USER, CUSTOMER], if customer then also CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
//OutsideServiceOverdue
|
||||
//OutsideServiceReceived https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
//PartRequestReceived https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
//CustomerServiceImminent ALSO CopyOfCustomerNotification
|
||||
//WorkorderCreatedForCustomer (conditional ID sb customer id) ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
|
||||
//PartRequested https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
//WorkorderTotalExceedsThreshold
|
||||
//WorkorderStatusAge
|
||||
}
|
||||
break;
|
||||
case AyaType.Quote:
|
||||
//QuoteStatusChange [USER, CUSTOMER] / ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
//QuoteStatusAge
|
||||
break;
|
||||
case AyaType.Contract:
|
||||
//ContractExpiring [CUSTOMER/USER] / ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
|
||||
break;
|
||||
case AyaType.Reminder:
|
||||
//ReminderImminent
|
||||
break;
|
||||
case AyaType.Unit:
|
||||
//UnitWarrantyExpiry
|
||||
break;
|
||||
case AyaType.UnitMeterReading:
|
||||
//UnitMeterReadingMultipleExceeded
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
//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;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//------------------------------------------
|
||||
//ObjectCreated
|
||||
//
|
||||
// [USER for any type, CUSTOMER for workorder only] / if customer then CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
// {
|
||||
// await ProcessStandardObjectCreatedEvents(newObject, ct);
|
||||
// }
|
||||
#endregion created processing
|
||||
break;
|
||||
case AyaEvent.Modified:
|
||||
#region Modified processing
|
||||
//######## NOTE: be sure to remove any that are being replaced potentially
|
||||
//------------------------------
|
||||
// AyaType Specific modified related subscriptions
|
||||
//
|
||||
switch (newObject.AyaType)
|
||||
{
|
||||
case AyaType.Review:
|
||||
{
|
||||
// //Remove prior
|
||||
// await 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)
|
||||
// {
|
||||
// var userNotifySub = await EnsureDefaultInAppUserNotificationSubscriptionExists(r.UserId, ct);
|
||||
// NotifySubscription supervisorNotifySub = null;
|
||||
// if (r.UserId != r.AssignedByUserId)
|
||||
// {
|
||||
// supervisorNotifySub = await EnsureDefaultInAppUserNotificationSubscriptionExists(r.AssignedByUserId, ct);
|
||||
// }
|
||||
|
||||
// {
|
||||
// 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()}]");
|
||||
// }
|
||||
|
||||
// if (supervisorNotifySub != null)
|
||||
// {
|
||||
// NotifyEvent n = new NotifyEvent()
|
||||
// {
|
||||
// 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()}]");
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
//AyaTypes with their own special notification related events
|
||||
case AyaType.WorkOrder:
|
||||
{
|
||||
//WorkorderStatusChange [USER, CUSTOMER BOTH] / CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
//
|
||||
{
|
||||
throw new System.NotImplementedException("Awaiting workorder object completion");
|
||||
// if (((WorkOrder)newObject).WorkorderStatusId != ((WorkOrder)dbObject).WorkorderStatusId)
|
||||
// {
|
||||
// var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.WorkorderStatusChange).ToListAsync();
|
||||
// foreach (var sub in subs)
|
||||
// {
|
||||
// if (TagsMatch(newObject.Tags, sub.Tags))
|
||||
// {
|
||||
|
||||
// NotifyEvent n = new NotifyEvent()
|
||||
// {
|
||||
// EventType = NotifyEventType.ObjectAge,
|
||||
// UserId = sub.UserId,
|
||||
// ObjectId = newObject.Id,
|
||||
// NotifySubscriptionId = sub.Id,
|
||||
// //TODO: IdValue=((WorkOrder)newObject).WorkorderStatusId
|
||||
// EventDate = DateTime.UtcNow,
|
||||
//Name=newObject.Name
|
||||
//,
|
||||
// Name=newObject.Name
|
||||
// };
|
||||
// await ct.NotifyEvent.AddAsync(n);
|
||||
// log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]");
|
||||
|
||||
// //Note: in same event but for MODIFY below if need to delete old notifyevent here
|
||||
// // var deleteEventList = await ct.NotifyEvent.Where(z => z.ObjectId == ev.ObjectId && z.AyaType == ev.AyaType).ToListAsync();
|
||||
// // ct.NotifyEvent.RemoveRange(deleteEventList);
|
||||
|
||||
|
||||
// SaveContext = true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
//ScheduledOnWorkorder (DELETE OLD, USER / DATE COULD CHANGE)
|
||||
//https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
//ScheduledOnWorkorderImminent (DELTE OLD)
|
||||
//https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
//WorkorderFinishStatusOverdue (DELETE OLD)
|
||||
//WorkorderFinished [USER, CUSTOMER] ALSO CopyOfCustomerNotification applies here https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
//OutsideServiceOverdue (ALSO DELETE OLD)
|
||||
//OutsideServiceReceived
|
||||
//PartRequestReceived
|
||||
//CustomerServiceImminent (ALSO DELETE OLD) / ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
//PartRequested
|
||||
//https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
//WorkorderTotalExceedsThreshold
|
||||
//WorkorderStatusAge (ALSO DELETE OLD)
|
||||
//https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/1137
|
||||
//WorkorderFinishedFollowUp (uses AGE after finished status) [USER]
|
||||
|
||||
}
|
||||
break;
|
||||
case AyaType.Quote:
|
||||
//QuoteStatusChange [USER, CUSTOMER] ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
//QuoteStatusAge (DELETE OLD)
|
||||
break;
|
||||
case AyaType.Contract:
|
||||
//ContractExpiring (DELETE OLD)
|
||||
break;
|
||||
case AyaType.Reminder:
|
||||
//ReminderImminent (DELETE OLD)
|
||||
break;
|
||||
case AyaType.Unit:
|
||||
//UnitWarrantyExpiry (DELETE OLD)
|
||||
break;
|
||||
case AyaType.UnitMeterReading:
|
||||
//UnitMeterReadingMultipleExceeded
|
||||
//case 1254
|
||||
// This is as a threshold multiple value, i.e. if it's passing a multiple of 50,000 then notify, or notify every 10,000 or something.
|
||||
// In saving code it just checks to see if it has crossed the multiple threshold, i.e. calculate the old multiple, calculate the new multiple if over then send notification immediate.
|
||||
break;
|
||||
case AyaType.CustomerServiceRequest:
|
||||
//CSRAccepted (DELETE OLD might have changed from one to the other) [CUSTOMER] ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
//CSRRejected (DELETE OLD might have changed from one to the other) [CUSTOMER] ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
|
||||
break;
|
||||
case AyaType.ServiceBank:
|
||||
//ServiceBankDepleted https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/472
|
||||
break;
|
||||
|
||||
case AyaType.User:
|
||||
//This one's a little different, if user has had roles changed, then pre-existing subs may not be allowed anymore
|
||||
//Remove any notification subscriptions user doesn't have rights to:
|
||||
if (((User)originalObject).Roles != ((User)newObject).Roles)
|
||||
{
|
||||
var DeleteList = new List<long>();
|
||||
var NewRoles = ((User)newObject).Roles;
|
||||
//iterate subs and remove any user shouldn't have
|
||||
var userSubs = await ct.NotifySubscription.Where(z => z.UserId == newObject.Id).ToListAsync();
|
||||
foreach (var sub in userSubs)
|
||||
{
|
||||
if (sub.AyaType != AyaType.NoType)
|
||||
{
|
||||
//check if user has rights to it or not still
|
||||
//must have read rights to be valid
|
||||
if (!AyaNova.Api.ControllerHelpers.Authorized.HasAnyRole(NewRoles, sub.AyaType))
|
||||
{
|
||||
//no rights whatsoever, so delete it
|
||||
DeleteList.Add(sub.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DeleteList.Count > 0)
|
||||
{
|
||||
var NSB = NotifySubscriptionBiz.GetBiz(ct);
|
||||
foreach (var l in DeleteList)
|
||||
{
|
||||
await NSB.DeleteAsync(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------
|
||||
//ObjectModified
|
||||
//
|
||||
{
|
||||
var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.ObjectModified && z.AyaType == newObject.AyaType).ToListAsync();
|
||||
foreach (var sub in subs)
|
||||
{
|
||||
if (TagsMatch(newObject.Tags, sub.Tags))
|
||||
{
|
||||
NotifyEvent n = new NotifyEvent()
|
||||
{
|
||||
EventType = NotifyEventType.ObjectModified,
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion modified processing
|
||||
break;
|
||||
case AyaEvent.Deleted:
|
||||
#region Deleted processing
|
||||
|
||||
//------------------------------
|
||||
// Delete any NotifyEvent records for this exact object
|
||||
await ProcessStandardObjectDeletedEvents(newObject, ct);
|
||||
#endregion deleted processing
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
#if (DEBUG)
|
||||
throw (new System.NotSupportedException($"NotifyEventProcessor:HandlePotentialNotificationEvent - AyaEvent {ayaEvent} was specified which is unexpected and not supported"));
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (SaveContext)
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError(ex, $"Error processing event");
|
||||
}
|
||||
finally
|
||||
{
|
||||
log.LogDebug($"Notify event processing completed");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}//eom
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
// ENSURE USER HAS IN APP NOTIFICATION
|
||||
@@ -589,15 +46,14 @@ namespace AyaNova.Biz
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// PROCESS STANDARD EVENTS
|
||||
//
|
||||
//
|
||||
public static async Task ProcessStandardObjectEvents(AyaEvent ayaEvent, ICoreBizObjectModel newObject, AyContext ct)
|
||||
{
|
||||
switch(ayaEvent){
|
||||
switch (ayaEvent)
|
||||
{
|
||||
case AyaEvent.Created:
|
||||
await ProcessStandardObjectCreatedEvents(newObject, ct);
|
||||
break;
|
||||
@@ -671,6 +127,36 @@ namespace AyaNova.Biz
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// PROCESS STANDARD CREATE NOTIFICATION
|
||||
//
|
||||
//
|
||||
public static async Task ProcessStandardObjectModifiedEvents(ICoreBizObjectModel newObject, AyContext ct)
|
||||
{
|
||||
{
|
||||
var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.ObjectModified && z.AyaType == newObject.AyaType).ToListAsync();
|
||||
foreach (var sub in subs)
|
||||
{
|
||||
if (TagsMatch(newObject.Tags, sub.Tags))
|
||||
{
|
||||
NotifyEvent n = new NotifyEvent()
|
||||
{
|
||||
EventType = NotifyEventType.ObjectModified,
|
||||
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()}]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// PROCESS STANDARD DELETE NOTIFICATION
|
||||
//
|
||||
@@ -749,6 +235,397 @@ namespace AyaNova.Biz
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// CREATE OPS PROBLEM EVENT
|
||||
//
|
||||
//
|
||||
internal static async Task AddOpsProblemEvent(string message, Exception ex = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(message) && ex == null)
|
||||
return;
|
||||
|
||||
//Log as a backup in case there is no one to notify and also for the record and support
|
||||
if (ex != null)
|
||||
{
|
||||
//actually, if there is an exception it's already logged anyway so don't re-log it here, just makes dupes
|
||||
// log.LogError(ex, $"Ops problem notification: \"{message}\"");
|
||||
message += $"\nException error: {ExceptionUtil.ExtractAllExceptionMessages(ex)}";
|
||||
}
|
||||
else
|
||||
log.LogWarning($"Ops problem notification: \"{message}\"");
|
||||
|
||||
await AddGeneralNotifyEvent(NotifyEventType.ServerOperationsProblem, message, "OPS");
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// CREATE GENERAL NOTIFY EVENT
|
||||
//
|
||||
//
|
||||
|
||||
internal static async Task AddGeneralNotifyEvent(NotifyEventType eventType, string message, string name, Exception except = null, long userId = 0)
|
||||
{
|
||||
//This handles general notification events not requiring a decision or tied to an object that are basically just a immediate message to the user
|
||||
//e.g. ops problems, GeneralNotification, NotifyHealthCheck etc
|
||||
//optional user id to send directly to them
|
||||
log.LogDebug($"AddGeneralNotifyEvent processing: [type:{eventType}, userId:{userId}, message:{message}]");
|
||||
#if (DEBUG)
|
||||
switch (eventType)
|
||||
{
|
||||
case NotifyEventType.BackupStatus:
|
||||
case NotifyEventType.GeneralNotification:
|
||||
case NotifyEventType.NotifyHealthCheck://created by job processor itself
|
||||
case NotifyEventType.ServerOperationsProblem:
|
||||
break;
|
||||
default://this will likely be a development error, not a production error so no need to log etc
|
||||
throw (new System.NotSupportedException($"NotifyEventProcessor:AddGeneralNotifyEvent - Type of event {eventType} is unexpected and not supported"));
|
||||
}
|
||||
|
||||
if (eventType != NotifyEventType.GeneralNotification && userId != 0)
|
||||
{
|
||||
throw (new System.NotSupportedException($"NotifyEventProcessor:AddGeneralNotifyEvent - event {eventType} was specified with user id {userId} which is unexpected and not supported"));
|
||||
}
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
using (AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext)
|
||||
{
|
||||
|
||||
//General notification goes to a specific user only
|
||||
//no need to consult subscriptions
|
||||
if (eventType == NotifyEventType.GeneralNotification)
|
||||
{
|
||||
if (userId == 0)
|
||||
{
|
||||
//this will likely be a development error, not a production error so no need to log etc
|
||||
throw new System.ArgumentException("NotifyEventProcessor:AddGeneralNotifyEvent: GeneralNotification requires a user id but none was specified");
|
||||
}
|
||||
|
||||
var UserName = await ct.User.AsNoTracking().Where(z => z.Id == userId).Select(z => z.Name).FirstOrDefaultAsync();
|
||||
|
||||
//if they don't have a regular inapp subscription create one now
|
||||
NotifySubscription defaultsub = await EnsureDefaultInAppUserNotificationSubscriptionExists(userId, ct);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
name = UserName;
|
||||
}
|
||||
|
||||
NotifyEvent n = new NotifyEvent() { EventType = eventType, UserId = userId, Message = message, NotifySubscriptionId = defaultsub.Id, Name = name };
|
||||
await ct.NotifyEvent.AddAsync(n);
|
||||
await ct.SaveChangesAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//check subscriptions for event and send accordingly to each user
|
||||
var subs = await ct.NotifySubscription.Where(z => z.EventType == eventType).ToListAsync();
|
||||
|
||||
//append exception message if not null
|
||||
if (except != null)
|
||||
message += $"\nException error: {ExceptionUtil.ExtractAllExceptionMessages(except)}";
|
||||
|
||||
foreach (var sub in subs)
|
||||
{
|
||||
//note flag ~SERVER~ means to client to substitute "Server" translation key text instead
|
||||
NotifyEvent n = new NotifyEvent() { EventType = eventType, UserId = sub.UserId, Message = message, NotifySubscriptionId = sub.Id, Name = "~SERVER~" };
|
||||
await ct.NotifyEvent.AddAsync(n);
|
||||
}
|
||||
if (subs.Count > 0)
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError(ex, $"Error adding general notify event [type:{eventType}, userId:{userId}, message:{message}]");
|
||||
}
|
||||
|
||||
}//eom
|
||||
|
||||
|
||||
|
||||
}//eoc
|
||||
|
||||
}//eons
|
||||
|
||||
//###DEPRECATED: MOVED EVENT PROCESSING INTO BIZ OBJECTS BUT
|
||||
// //SPLIT INTO STANDARD EVENT PROCESSING METHODS BELOW
|
||||
// //AND ANYTHING TYPE SPECIFIC IS IN BIZ OBJECT ITSELF
|
||||
// //KEEPING THIS AS IT HAS SOME IMPLEMENTATION NOTES IN IT
|
||||
// //This is told about an event and then determines if there are any subscriptions related to that event and proceses them accordingly
|
||||
// //todo: this should take some kind of general event type like the AyaEvent types (i.e. which CRUD operation is in effect if relevant)
|
||||
// //and also a biz object before and after or just before if not a change and also a AyaType
|
||||
|
||||
// //then *this* code will go through and look for subscriptions related to that event
|
||||
// //this way the biz object code can be "dumb" about notifications in general and just let this code handle it as needed
|
||||
// //will iterate the subscriptions and see if any apply here
|
||||
// internal static async Task HandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel newObject, ICoreBizObjectModel originalObject = null)
|
||||
// {
|
||||
// if (ServerBootConfig.SEEDING) return;
|
||||
// log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{newObject.AyaType}, AyaEvent:{ayaEvent}]");
|
||||
// //set to true if any changes are made to the context (NotifyEvent added)
|
||||
// bool SaveContext = false;
|
||||
// try
|
||||
// {
|
||||
// using (AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext)
|
||||
// {
|
||||
// //short circuit if there are no subscriptions which would be typical of a v8 migrate scenario or fresh import or just not using notification
|
||||
// if (!await ct.NotifySubscription.AnyAsync())
|
||||
// return;
|
||||
|
||||
// //switch through AyaEvent then individual Ayatypes as required for event types
|
||||
// switch (ayaEvent)
|
||||
// {
|
||||
// case AyaEvent.Created:
|
||||
// #region Created processing
|
||||
// //------------------------------
|
||||
// // AyaType Specific created related subscriptions
|
||||
// // Note: these are for specific things only in this block
|
||||
// // generally being created notifications are further down below
|
||||
// switch (newObject.AyaType)
|
||||
// {
|
||||
|
||||
|
||||
// //AyaTypes with their own special notification related events
|
||||
// case AyaType.WorkOrder:
|
||||
// {
|
||||
// //WorkorderStatusChange
|
||||
// {
|
||||
// throw new System.NotImplementedException("Awaiting workorder object completion");
|
||||
// var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.WorkorderStatusChange).ToListAsync();
|
||||
// foreach (var sub in subs)
|
||||
// {
|
||||
// if (TagsMatch(newObject.Tags, sub.Tags))
|
||||
// {
|
||||
|
||||
// NotifyEvent n = new NotifyEvent()
|
||||
// {
|
||||
// EventType = NotifyEventType.ObjectAge,
|
||||
// UserId = sub.UserId,
|
||||
// ObjectId = newObject.Id,
|
||||
// NotifySubscriptionId = sub.Id,
|
||||
// //TODO: IdValue=((WorkOrder)newObject).WorkorderStatusId
|
||||
// Name = newObject.Name
|
||||
// };
|
||||
// await ct.NotifyEvent.AddAsync(n);
|
||||
// log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]");
|
||||
|
||||
// //Note: in same event but for MODIFY below if need to delete old notifyevent here
|
||||
// // var deleteEventList = await ct.NotifyEvent.Where(z => z.ObjectId == ev.ObjectId && z.AyaType == ev.AyaType).ToListAsync();
|
||||
// // ct.NotifyEvent.RemoveRange(deleteEventList);
|
||||
|
||||
|
||||
// SaveContext = true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// //ScheduledOnWorkorder https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
// //ScheduledOnWorkorderImminent https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
// //WorkorderFinishStatusOverdue
|
||||
// //WorkorderFinished [USER, CUSTOMER], if customer then also CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
// //OutsideServiceOverdue
|
||||
// //OutsideServiceReceived https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
// //PartRequestReceived https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
// //CustomerServiceImminent ALSO CopyOfCustomerNotification
|
||||
// //WorkorderCreatedForCustomer (conditional ID sb customer id) ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
|
||||
// //PartRequested https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
// //WorkorderTotalExceedsThreshold
|
||||
// //WorkorderStatusAge
|
||||
// }
|
||||
// break;
|
||||
// case AyaType.Quote:
|
||||
// //QuoteStatusChange [USER, CUSTOMER] / ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
// //QuoteStatusAge
|
||||
// break;
|
||||
// case AyaType.Contract:
|
||||
// //ContractExpiring [CUSTOMER/USER] / ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
|
||||
// break;
|
||||
// case AyaType.Reminder:
|
||||
// //ReminderImminent
|
||||
// break;
|
||||
// case AyaType.Unit:
|
||||
// //UnitWarrantyExpiry
|
||||
// break;
|
||||
// case AyaType.UnitMeterReading:
|
||||
// //UnitMeterReadingMultipleExceeded
|
||||
// break;
|
||||
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// //------------------------------------------
|
||||
// //ObjectCreated
|
||||
// //
|
||||
// // [USER for any type, CUSTOMER for workorder only] / if customer then CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
// // {
|
||||
|
||||
// // }
|
||||
// #endregion created processing
|
||||
// break;
|
||||
// case AyaEvent.Modified:
|
||||
// #region Modified processing
|
||||
// //######## NOTE: be sure to remove any that are being replaced potentially
|
||||
// //------------------------------
|
||||
// // AyaType Specific modified related subscriptions
|
||||
// //
|
||||
// switch (newObject.AyaType)
|
||||
// {
|
||||
|
||||
|
||||
// //AyaTypes with their own special notification related events
|
||||
// case AyaType.WorkOrder:
|
||||
// {
|
||||
// //WorkorderStatusChange [USER, CUSTOMER BOTH] / CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
// //
|
||||
// {
|
||||
// throw new System.NotImplementedException("Awaiting workorder object completion");
|
||||
// // if (((WorkOrder)newObject).WorkorderStatusId != ((WorkOrder)dbObject).WorkorderStatusId)
|
||||
// // {
|
||||
// // var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.WorkorderStatusChange).ToListAsync();
|
||||
// // foreach (var sub in subs)
|
||||
// // {
|
||||
// // if (TagsMatch(newObject.Tags, sub.Tags))
|
||||
// // {
|
||||
|
||||
// // NotifyEvent n = new NotifyEvent()
|
||||
// // {
|
||||
// // EventType = NotifyEventType.ObjectAge,
|
||||
// // UserId = sub.UserId,
|
||||
// // ObjectId = newObject.Id,
|
||||
// // NotifySubscriptionId = sub.Id,
|
||||
// // //TODO: IdValue=((WorkOrder)newObject).WorkorderStatusId
|
||||
// // EventDate = DateTime.UtcNow,
|
||||
// //Name=newObject.Name
|
||||
// //,
|
||||
// // Name=newObject.Name
|
||||
// // };
|
||||
// // await ct.NotifyEvent.AddAsync(n);
|
||||
// // log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]");
|
||||
|
||||
// // //Note: in same event but for MODIFY below if need to delete old notifyevent here
|
||||
// // // var deleteEventList = await ct.NotifyEvent.Where(z => z.ObjectId == ev.ObjectId && z.AyaType == ev.AyaType).ToListAsync();
|
||||
// // // ct.NotifyEvent.RemoveRange(deleteEventList);
|
||||
|
||||
|
||||
// // SaveContext = true;
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// }
|
||||
// //ScheduledOnWorkorder (DELETE OLD, USER / DATE COULD CHANGE)
|
||||
// //https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
// //ScheduledOnWorkorderImminent (DELTE OLD)
|
||||
// //https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
// //WorkorderFinishStatusOverdue (DELETE OLD)
|
||||
// //WorkorderFinished [USER, CUSTOMER] ALSO CopyOfCustomerNotification applies here https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
// //OutsideServiceOverdue (ALSO DELETE OLD)
|
||||
// //OutsideServiceReceived
|
||||
// //PartRequestReceived
|
||||
// //CustomerServiceImminent (ALSO DELETE OLD) / ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
// //PartRequested
|
||||
// //https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/892
|
||||
// //WorkorderTotalExceedsThreshold
|
||||
// //WorkorderStatusAge (ALSO DELETE OLD)
|
||||
// //https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/1137
|
||||
// //WorkorderFinishedFollowUp (uses AGE after finished status) [USER]
|
||||
|
||||
// }
|
||||
// break;
|
||||
// case AyaType.Quote:
|
||||
// //QuoteStatusChange [USER, CUSTOMER] ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
// //QuoteStatusAge (DELETE OLD)
|
||||
// break;
|
||||
// case AyaType.Contract:
|
||||
// //ContractExpiring (DELETE OLD)
|
||||
// break;
|
||||
// case AyaType.Reminder:
|
||||
// //ReminderImminent (DELETE OLD)
|
||||
// break;
|
||||
// case AyaType.Unit:
|
||||
// //UnitWarrantyExpiry (DELETE OLD)
|
||||
// break;
|
||||
// case AyaType.UnitMeterReading:
|
||||
// //UnitMeterReadingMultipleExceeded
|
||||
// //case 1254
|
||||
// // This is as a threshold multiple value, i.e. if it's passing a multiple of 50,000 then notify, or notify every 10,000 or something.
|
||||
// // In saving code it just checks to see if it has crossed the multiple threshold, i.e. calculate the old multiple, calculate the new multiple if over then send notification immediate.
|
||||
// break;
|
||||
// case AyaType.CustomerServiceRequest:
|
||||
// //CSRAccepted (DELETE OLD might have changed from one to the other) [CUSTOMER] ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
// //CSRRejected (DELETE OLD might have changed from one to the other) [CUSTOMER] ALSO CopyOfCustomerNotification https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3398
|
||||
|
||||
// break;
|
||||
// case AyaType.ServiceBank:
|
||||
// //ServiceBankDepleted https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/472
|
||||
// break;
|
||||
|
||||
|
||||
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// //------------------------------------------
|
||||
// //ObjectModified
|
||||
// //
|
||||
// // {
|
||||
// // var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.ObjectModified && z.AyaType == newObject.AyaType).ToListAsync();
|
||||
// // foreach (var sub in subs)
|
||||
// // {
|
||||
// // if (TagsMatch(newObject.Tags, sub.Tags))
|
||||
// // {
|
||||
// // NotifyEvent n = new NotifyEvent()
|
||||
// // {
|
||||
// // EventType = NotifyEventType.ObjectModified,
|
||||
// // 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;
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// #endregion modified processing
|
||||
// break;
|
||||
// case AyaEvent.Deleted:
|
||||
// #region Deleted processing
|
||||
|
||||
// //------------------------------
|
||||
// // Delete any NotifyEvent records for this exact object
|
||||
// await ProcessStandardObjectDeletedEvents(newObject, ct);
|
||||
// #endregion deleted processing
|
||||
// break;
|
||||
|
||||
|
||||
// default:
|
||||
// #if (DEBUG)
|
||||
// throw (new System.NotSupportedException($"NotifyEventProcessor:HandlePotentialNotificationEvent - AyaEvent {ayaEvent} was specified which is unexpected and not supported"));
|
||||
// #else
|
||||
// break;
|
||||
// #endif
|
||||
// }
|
||||
// if (SaveContext)
|
||||
// await ct.SaveChangesAsync();
|
||||
// }
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// log.LogError(ex, $"Error processing event");
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// log.LogDebug($"Notify event processing completed");
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// }//eom
|
||||
@@ -898,6 +898,41 @@ namespace AyaNova.Biz
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
case AyaType.User:
|
||||
//USER MODIFIED SPECIAL
|
||||
//This one's a little different, if user has had roles changed, then pre-existing subs may not be allowed anymore
|
||||
//Remove any notification subscriptions user doesn't have rights to:
|
||||
if (((User)originalObject).Roles != ((User)newObject).Roles)
|
||||
{
|
||||
var DeleteList = new List<long>();
|
||||
var NewRoles = ((User)newObject).Roles;
|
||||
//iterate subs and remove any user shouldn't have
|
||||
var userSubs = await ct.NotifySubscription.Where(z => z.UserId == newObject.Id).ToListAsync();
|
||||
foreach (var sub in userSubs)
|
||||
{
|
||||
if (sub.AyaType != AyaType.NoType)
|
||||
{
|
||||
//check if user has rights to it or not still
|
||||
//must have read rights to be valid
|
||||
if (!AyaNova.Api.ControllerHelpers.Authorized.HasAnyRole(NewRoles, sub.AyaType))
|
||||
{
|
||||
//no rights whatsoever, so delete it
|
||||
DeleteList.Add(sub.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DeleteList.Count > 0)
|
||||
{
|
||||
var NSB = NotifySubscriptionBiz.GetBiz(ct);
|
||||
foreach (var l in DeleteList)
|
||||
{
|
||||
await NSB.DeleteAsync(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
}//eoc
|
||||
|
||||
Reference in New Issue
Block a user