diff --git a/server/AyaNova/Controllers/EnumListController.cs b/server/AyaNova/Controllers/EnumListController.cs index 8e13681c..cb0aa561 100644 --- a/server/AyaNova/Controllers/EnumListController.cs +++ b/server/AyaNova/Controllers/EnumListController.cs @@ -466,6 +466,7 @@ namespace AyaNova.Api.Controllers TranslationKeysToFetch.Add("NotifyEventWorkorderCreatedForCustomer"); TranslationKeysToFetch.Add("NotifyEventPMGenerationFailed"); TranslationKeysToFetch.Add("NotifyEventPMInsufficientInventory"); + TranslationKeysToFetch.Add("NotifyEventReviewImminent"); var LT = await TranslationBiz.GetSubsetStaticAsync(TranslationKeysToFetch, translationId); @@ -482,6 +483,7 @@ namespace AyaNova.Api.Controllers ReturnList.Add(new NameIdItem() { Name = LT["NotifyEventObjectAge"], Id = (long)NotifyEventType.ObjectAge }); ReturnList.Add(new NameIdItem() { Name = LT["NotifyEventPMInsufficientInventory"], Id = (long)NotifyEventType.PMInsufficientInventory }); ReturnList.Add(new NameIdItem() { Name = LT["NotifyEventReminderImminent"], Id = (long)NotifyEventType.ReminderImminent }); + ReturnList.Add(new NameIdItem() { Name = LT["NotifyEventReviewImminent"], Id = (long)NotifyEventType.ReviewImminent }); ReturnList.Add(new NameIdItem() { Name = LT["NotifyEventScheduledOnWorkorder"], Id = (long)NotifyEventType.ScheduledOnWorkorder }); ReturnList.Add(new NameIdItem() { Name = LT["NotifyEventScheduledOnWorkorderImminent"], Id = (long)NotifyEventType.ScheduledOnWorkorderImminent }); ReturnList.Add(new NameIdItem() { Name = LT["NotifyEventWorkorderCompletedStatusOverdue"], Id = (long)NotifyEventType.WorkorderCompletedStatusOverdue }); diff --git a/server/AyaNova/biz/NotifyEventType.cs b/server/AyaNova/biz/NotifyEventType.cs index bf0bca8e..509253a3 100644 --- a/server/AyaNova/biz/NotifyEventType.cs +++ b/server/AyaNova/biz/NotifyEventType.cs @@ -43,7 +43,8 @@ namespace AyaNova.Biz WorkorderCompleted = 30, //*Service work order is set to any status that is flagged as a "Completed" type of status. Customer & User (Note this is for users that don't want or can't pick status change to completed type) WorkorderCreatedForCustomer = 31, //*Service work order is created for Customer, only applies to that customer user notify sub for that customer, customer id is in conditional ID value for subscription PMGenerationFailed = 32, //indicates there was a failure during PM generation with error - SendUserCredentials = 33 // Internal System use only: When user generates new credentials and sends them this is the notification type for that see UserBiz GenerateCredsAndEmailUser + SendUserCredentials = 33, // Internal System use only: When user generates new credentials and sends them this is the notification type for that see UserBiz GenerateCredsAndEmailUser + ReviewImminent = 34,//*Review object, Advance notice setting tag conditional //POTENTIAL OTHER NOTIFICATIONS: //WorkOrderItemLoan unit is overdue from estimate diff --git a/server/AyaNova/biz/ReminderBiz.cs b/server/AyaNova/biz/ReminderBiz.cs index 4221ea89..144df28b 100644 --- a/server/AyaNova/biz/ReminderBiz.cs +++ b/server/AyaNova/biz/ReminderBiz.cs @@ -501,7 +501,7 @@ namespace AyaNova.Biz } } - }//warranty expiry event + }//Reminder imminent event }//end of process notifications } diff --git a/server/AyaNova/biz/ReviewBiz.cs b/server/AyaNova/biz/ReviewBiz.cs index 93a028d7..29080f8f 100644 --- a/server/AyaNova/biz/ReviewBiz.cs +++ b/server/AyaNova/biz/ReviewBiz.cs @@ -527,76 +527,126 @@ namespace AyaNova.Biz bool isNew = currentObj == null; + Review o = (Review)proposedObj; + //STANDARD EVENTS FOR ALL OBJECTS await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); //SPECIFIC EVENTS FOR THIS OBJECT + #region OLD - //CREATED / MODIFIED + //OLD general notification code removed in favor of specific event for review imminent + // //CREATED / MODIFIED + // if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) + // { + // //OVERDUE pseudo event + // { + // //Remove prior + // await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, proposedObj.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)proposedObj; + + // //it not completed yet and not overdue already (which could indicate an import or something) + // if (r.CompletedDate == null && r.ReviewDate > DateTime.UtcNow) + // { + // //Notify user + // await NotifyEventHelper.EnsureDefaultInAppUserNotificationSubscriptionExists(r.UserId, ct); + // { + // var gensubs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.GeneralNotification && z.UserId == r.UserId).ToListAsync(); + // foreach (var sub in gensubs) + // { + // var eventNameTranslated = await TranslationBiz.GetTranslationForUserStaticAsync("ReviewOverDue", r.UserId); + // NotifyEvent n = new NotifyEvent() + // { + // EventType = NotifyEventType.GeneralNotification, + // UserId = r.UserId, + // ObjectId = proposedObj.Id, + // AyaType = AyaType.Review, + // NotifySubscriptionId = sub.Id, + // Name = $"{eventNameTranslated} - {proposedObj.Name}", + // EventDate = r.ReviewDate + // }; + // await ct.NotifyEvent.AddAsync(n); + // log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + // } + // if (gensubs.Count > 0) + // await ct.SaveChangesAsync(); + // } + + // //Notify supervisor + // if (r.UserId != r.AssignedByUserId) + // { + // await NotifyEventHelper.EnsureDefaultInAppUserNotificationSubscriptionExists(r.AssignedByUserId, ct); + // var gensubs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.GeneralNotification && z.UserId == r.AssignedByUserId).ToListAsync(); + // foreach (var sub in gensubs) + // { + // var eventNameTranslated = await TranslationBiz.GetTranslationForUserStaticAsync("ReviewOverDue", r.AssignedByUserId); + // NotifyEvent n = new NotifyEvent() + // { + // EventType = NotifyEventType.GeneralNotification, + // UserId = r.AssignedByUserId, + // ObjectId = proposedObj.Id, + // AyaType = AyaType.Review, + // NotifySubscriptionId = sub.Id, + // Name = $"{eventNameTranslated} - {proposedObj.Name}", + // EventDate = r.ReviewDate + // }; + // await ct.NotifyEvent.AddAsync(n); + // log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + // } + // if (gensubs.Count > 0) + // await ct.SaveChangesAsync(); + // } + // } + // }//overdue event + // }//custom events for created / modified + #endregion old + + //## DELETED EVENTS + + //any event added below needs to be removed, so + //just blanket remove any event for this object of eventtype that would be added below here + //do it regardless any time there's an update and then + //let this code below handle the refreshing addition that could have changes + await NotifyEventHelper.ClearPriorEventsForObject(ct, AyaType.Review, o.Id, NotifyEventType.ReviewImminent); + + //## CREATED / MODIFIED EVENTS if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) { - //OVERDUE pseudo event + //# REVIEW IMMINENT { - //Remove prior - await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, proposedObj.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)proposedObj; - - //it not completed yet and not overdue already (which could indicate an import or something) - if (r.CompletedDate == null && r.ReviewDate > DateTime.UtcNow) + //notify users (time delayed) + var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.ReviewImminent).ToListAsync(); + foreach (var sub in subs) { - //Notify user - await NotifyEventHelper.EnsureDefaultInAppUserNotificationSubscriptionExists(r.UserId, ct); - { - var gensubs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.GeneralNotification && z.UserId == r.UserId).ToListAsync(); - foreach (var sub in gensubs) - { - var eventNameTranslated = await TranslationBiz.GetTranslationForUserStaticAsync("ReviewOverDue", r.UserId); - NotifyEvent n = new NotifyEvent() - { - EventType = NotifyEventType.GeneralNotification, - UserId = r.UserId, - ObjectId = proposedObj.Id, - AyaType = AyaType.Review, - NotifySubscriptionId = sub.Id, - Name = $"{eventNameTranslated} - {proposedObj.Name}", - EventDate = r.ReviewDate - }; - await ct.NotifyEvent.AddAsync(n); - log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); - } - if (gensubs.Count > 0) - await ct.SaveChangesAsync(); - } + //not for inactive users + if (!await UserBiz.UserIsActive(sub.UserId)) continue; - //Notify supervisor - if (r.UserId != r.AssignedByUserId) + //Tag match? (will be true if no sub tags so always safe to call this) + if (NotifyEventHelper.ObjectHasAllSubscriptionTags(o.Tags, sub.Tags)) { - await NotifyEventHelper.EnsureDefaultInAppUserNotificationSubscriptionExists(r.AssignedByUserId, ct); - var gensubs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.GeneralNotification && z.UserId == r.AssignedByUserId).ToListAsync(); - foreach (var sub in gensubs) + + NotifyEvent n = new NotifyEvent() { - var eventNameTranslated = await TranslationBiz.GetTranslationForUserStaticAsync("ReviewOverDue", r.AssignedByUserId); - NotifyEvent n = new NotifyEvent() - { - EventType = NotifyEventType.GeneralNotification, - UserId = r.AssignedByUserId, - ObjectId = proposedObj.Id, - AyaType = AyaType.Review, - NotifySubscriptionId = sub.Id, - Name = $"{eventNameTranslated} - {proposedObj.Name}", - EventDate = r.ReviewDate - }; - await ct.NotifyEvent.AddAsync(n); - log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); - } - if (gensubs.Count > 0) - await ct.SaveChangesAsync(); + EventType = NotifyEventType.ReviewImminent, + UserId = sub.UserId, + AyaType = o.AyaType, + ObjectId = o.Id, + NotifySubscriptionId = sub.Id, + Name = o.Name, + EventDate = o.ReviewDate + }; + await ct.NotifyEvent.AddAsync(n); + log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + await ct.SaveChangesAsync(); } } - }//overdue event - }//custom events for created / modified + + }//review imminent + + }//end of process notifications + }//end of process notifications diff --git a/server/AyaNova/resource/de.json b/server/AyaNova/resource/de.json index cfbe7411..9b9b9b3e 100644 --- a/server/AyaNova/resource/de.json +++ b/server/AyaNova/resource/de.json @@ -2031,7 +2031,7 @@ "NotifyEventQuoteStatusChange": "Angebotsstatus geändert", "NotifyEventQuoteStatusAge": "Angebotsstatus für den Zeitraum unverändert", "NotifyEventServiceBankDepleted": "Service Bank erschöpft", - "NotifyEventReminderImminent": "Erinnerung unmittelbar bevorsteht", + "NotifyEventReminderImminent": "Erinnerung - unmittelbar bevorstehend", "NotifyEventScheduledOnWorkorder": "Geplant auf Arbeitsauftrag", "NotifyEventScheduledOnWorkorderImminent": "Arbeitsauftragsplan steht kurz bevor", "NotifyEventWorkorderCompletedStatusOverdue": "Arbeitsauftrag nicht rechtzeitig fertig", @@ -2059,6 +2059,7 @@ "NotifyEventPMStopGeneratingDateReached": "Stoppdatum für vorbeugende Wartung erreicht", "NotifyEventPMGenerationFailed": "Vorbeugende Wartung Generatorausfall", "NotifyEventPMInsufficientInventory": "Vorbeugende Wartung unzureichender Lagerbestand", + "NotifyEventReviewImminent": "Überprüfung - unmittelbar bevorstehend", "Duration": "Dauer", "Notifications": "Benachrichtigungen", "NotifyMailSecurityNone": "Keiner", diff --git a/server/AyaNova/resource/en.json b/server/AyaNova/resource/en.json index 77bbb56f..0d00f556 100644 --- a/server/AyaNova/resource/en.json +++ b/server/AyaNova/resource/en.json @@ -2031,7 +2031,7 @@ "NotifyEventQuoteStatusChange": "Quote status changed", "NotifyEventQuoteStatusAge": "Quote status age", "NotifyEventServiceBankDepleted": "Service bank empty", - "NotifyEventReminderImminent": "Reminder imminent", + "NotifyEventReminderImminent": "Reminder - imminent", "NotifyEventScheduledOnWorkorder": "Scheduled on work order", "NotifyEventScheduledOnWorkorderImminent": "Work order scheduled service imminent", "NotifyEventWorkorderCompletedStatusOverdue": "Work order not completed on time", @@ -2059,6 +2059,7 @@ "NotifyEventPMStopGeneratingDateReached": "Preventive maintenance stop date", "NotifyEventPMGenerationFailed": "Preventive maintenance generation failure", "NotifyEventPMInsufficientInventory": "Preventive maintenance insufficient inventory", + "NotifyEventReviewImminent": "Review - imminent", "Duration": "Duration", "Notifications": "Notifications", "NotifyMailSecurityNone": "None", diff --git a/server/AyaNova/resource/es.json b/server/AyaNova/resource/es.json index 0143b0e9..8eae8e2b 100644 --- a/server/AyaNova/resource/es.json +++ b/server/AyaNova/resource/es.json @@ -2059,6 +2059,7 @@ "NotifyEventPMStopGeneratingDateReached": "Se alcanzó la fecha de 'detención' del mantenimiento preventivo", "NotifyEventPMGenerationFailed": "Fallo de generación de mantenimiento preventivo", "NotifyEventPMInsufficientInventory": "Inventario insuficiente de mantenimiento preventivo", + "NotifyEventReviewImminent": "Revisión - inminente", "Duration": "Duración", "Notifications": "Notificaciones", "NotifyMailSecurityNone": "Ninguna", diff --git a/server/AyaNova/resource/fr.json b/server/AyaNova/resource/fr.json index 59ca5eb4..87dd5504 100644 --- a/server/AyaNova/resource/fr.json +++ b/server/AyaNova/resource/fr.json @@ -2031,7 +2031,7 @@ "NotifyEventQuoteStatusChange": "Statut du devis modifié", "NotifyEventQuoteStatusAge": "Statut du devis inchangé pour la période de temps", "NotifyEventServiceBankDepleted": "Banque de services épuisée", - "NotifyEventReminderImminent": "Rappel imminent", + "NotifyEventReminderImminent": "Rappel - imminent", "NotifyEventScheduledOnWorkorder": "Planifié sur ordre de travail", "NotifyEventScheduledOnWorkorderImminent": "Service planifié d'un ordre de travail imminent", "NotifyEventWorkorderCompletedStatusOverdue": "Ordre de travail non terminé à temps", @@ -2059,6 +2059,7 @@ "NotifyEventPMStopGeneratingDateReached": "Date d'arrêt de la maintenance préventive atteinte", "NotifyEventPMGenerationFailed": "Défaillance du système de maintenance préventive", "NotifyEventPMInsufficientInventory": "Maintenance préventive inventaire insuffisant", + "NotifyEventReviewImminent": "Révision - imminente", "Duration": "Durée", "Notifications": "Notifications", "NotifyMailSecurityNone": "Aucun",