diff --git a/server/AyaNova/biz/WorkOrderBiz.cs b/server/AyaNova/biz/WorkOrderBiz.cs index 0c63f4a5..7ef7c24d 100644 --- a/server/AyaNova/biz/WorkOrderBiz.cs +++ b/server/AyaNova/biz/WorkOrderBiz.cs @@ -1091,10 +1091,10 @@ namespace AyaNova.Biz { EventType = NotifyEventType.CustomerServiceImminent, UserId = sub.UserId, - AyaType = AyaType.NoType, - ObjectId =0, + AyaType = proposedObj.AyaType, + ObjectId = proposedObj.Id, NotifySubscriptionId = sub.Id, - Name = oProposed.Serial.ToString(),//NO: this needs to be a customer notification string + Name = oProposed.Serial.ToString(), EventDate = (DateTime)oProposed.ServiceDate }; await ct.NotifyEvent.AddAsync(n); @@ -1106,15 +1106,15 @@ namespace AyaNova.Biz }//CustomerServiceImminent if (ayaEvent == AyaEvent.Modified) - {// CustomerServiceImminent modified in some way, could be tags, could be date either of which is relevant to this notification block + {// CustomerServiceImminent - //differences requiring re-processing of notification?? - if (oProposed.CompleteByDate != oCurrent.CompleteByDate || !SameTags) + //differences requiring re-processing of notification + if (oProposed.ServiceDate != oCurrent.ServiceDate) { await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, proposedObj.Id, NotifyEventType.CustomerServiceImminent); //new has date? - if (oProposed.CompleteByDate != null) + if (oProposed.ServiceDate != null) { var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.CustomerServiceImminent).ToListAsync(); @@ -1132,7 +1132,7 @@ namespace AyaNova.Biz ObjectId = proposedObj.Id, NotifySubscriptionId = sub.Id, Name = oProposed.Serial.ToString(), - EventDate = (DateTime)oProposed.CompleteByDate + EventDate = (DateTime)oProposed.ServiceDate }; await ct.NotifyEvent.AddAsync(n); log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); diff --git a/server/AyaNova/generator/CoreJobNotify.cs b/server/AyaNova/generator/CoreJobNotify.cs index 7e5eaba4..b501c446 100644 --- a/server/AyaNova/generator/CoreJobNotify.cs +++ b/server/AyaNova/generator/CoreJobNotify.cs @@ -98,7 +98,7 @@ namespace AyaNova.Biz if (Subscription.DeliveryMethod == NotifyDeliveryMethod.App) await DeliverInApp(notifyevent, Subscription.AgeValue, ct); else if (Subscription.DeliveryMethod == NotifyDeliveryMethod.SMTP) - await DeliverSMTP(notifyevent, Subscription.AgeValue, Subscription.DeliveryAddress, ct); + await DeliverSMTP(notifyevent, Subscription.AgeValue, Subscription.AdvanceNotice, Subscription.DeliveryAddress, ct); } } } @@ -128,7 +128,7 @@ namespace AyaNova.Biz - private static async Task DeliverSMTP(NotifyEvent ne, TimeSpan ageValue, string deliveryAddress, AyContext ct) + private static async Task DeliverSMTP(NotifyEvent ne, TimeSpan ageValue, TimeSpan advanceNotice, string deliveryAddress, AyContext ct) { try { @@ -143,23 +143,26 @@ namespace AyaNova.Biz List TranslationKeysToFetch = new List(); TranslationKeysToFetch.Add(ne.AyaType.ToString()); TranslationKeysToFetch.Add("NotifySubscription"); + TranslationKeysToFetch.Add("NotifySubscriptionLinkText"); if (ne.Name == "~SERVER~") TranslationKeysToFetch.Add("Server"); var EventTypeTranslationKey = "NotifyEvent" + ne.EventType.ToString(); TranslationKeysToFetch.Add(EventTypeTranslationKey); - if (ageValue != TimeSpan.Zero) + if (ageValue != TimeSpan.Zero || ne.EventType == NotifyEventType.CustomerServiceImminent) { TranslationKeysToFetch.Add("TimeSpanDays"); TranslationKeysToFetch.Add("TimeSpanHours"); TranslationKeysToFetch.Add("TimeSpanMinutes"); TranslationKeysToFetch.Add("TimeSpanSeconds"); } + if (ne.EventType == NotifyEventType.CustomerServiceImminent) + TranslationKeysToFetch.Add("NotifyEventCustomerServiceImminentMessage"); //get translations var transid = await ct.UserOptions.AsNoTracking().Where(x => x.UserId == ne.UserId).Select(x => x.TranslationId).FirstOrDefaultAsync(); var LT = await TranslationBiz.GetSubsetStaticAsync(TranslationKeysToFetch, transid); - var NotifySubscriptionTheWord = LT["NotifySubscription"]; + var NotifySubscriptionLinkText = LT["NotifySubscriptionLinkText"]; var name = ne.Name; if (name == "~SERVER~") name = LT["Server"]; @@ -172,17 +175,6 @@ namespace AyaNova.Biz //subscription name translation var SubscriptionTypeName = LT[EventTypeTranslationKey]; - string subject = ""; - //Special notification handling - switch (ne.EventType) - { - case NotifyEventType.CustomerServiceImminent: - subject = SubscriptionTypeName; - break; - default: - subject = $"AY:{AyaTypeTranslated}:{name}:{SubscriptionTypeName}"; - break; - } //Age relevant notification @@ -190,25 +182,37 @@ namespace AyaNova.Biz if (ageValue != TimeSpan.Zero) AgeDisplay = $"({AyaNova.Util.DateUtil.FormatTimeSpan(ageValue, LT["TimeSpanDays"], LT["TimeSpanHours"], LT["TimeSpanMinutes"], LT["TimeSpanSeconds"])})\n"; - //var test=AyaNova.Util.DateUtil.FormatTimeSpan(new TimeSpan(2,3,4,5), LT["TimeSpanDays"], LT["TimeSpanHours"], LT["TimeSpanMinutes"], LT["TimeSpanSeconds"]); + string subject = ""; + IMailer m = AyaNova.Util.ServiceProviderProvider.Mailer; var body = ""; - //NOTE: if need any other exemptions besides backup status make a separate static function "CanOpen(NotifyEventType)" - - if (ne.ObjectId != 0 || ne.EventType == NotifyEventType.BackupStatus) + //Special notification handling + switch (ne.EventType) { - body = $"{AgeDisplay}{AyaTypeTranslated}\n{OpenObjectUrlBuilder(ne.AyaType, ne.ObjectId, ne.EventType)}\n"; + case NotifyEventType.CustomerServiceImminent: + subject = SubscriptionTypeName; + body = LT["NotifyEventCustomerServiceImminentMessage"].Replace("{0}", AyaNova.Util.DateUtil.FormatTimeSpan(advanceNotice, LT["TimeSpanDays"], LT["TimeSpanHours"], LT["TimeSpanMinutes"], LT["TimeSpanSeconds"])); + body += $"\n{OpenObjectUrlBuilder(ne.AyaType, ne.ObjectId, ne.EventType)}\n"; + break; + default: + subject = $"AY:{AyaTypeTranslated}:{name}:{SubscriptionTypeName}"; + if (ne.ObjectId != 0 || ne.EventType == NotifyEventType.BackupStatus) + { + body = $"{AgeDisplay}{AyaTypeTranslated}\n{OpenObjectUrlBuilder(ne.AyaType, ne.ObjectId, ne.EventType)}\n"; + } + body += ne.Message; + break; } - body += ne.Message; - //Add link to subscription + + //Add link to subscription, all messages have this regardless of content //http://localhost:8080/open/51/1 //add subscription link, notifysub is object type 51 if (!body.EndsWith('\n')) body += "\n"; - body += $"-----\n{NotifySubscriptionTheWord}\n{OpenSubscriptionUrlBuilder(ne.NotifySubscriptionId)}\n"; + body += $"-----\n{NotifySubscriptionLinkText}\n{OpenSubscriptionUrlBuilder(ne.NotifySubscriptionId)}\n"; if (!ServerGlobalOpsSettingsCache.Notify.SmtpDeliveryActive) { @@ -216,9 +220,8 @@ namespace AyaNova.Biz log.LogInformation($"** WARNING: SMTP notification is currently set to Active=False; unable to deliver email notification, re-routed to in-app notification instead [UserId={ne.UserId}, Notify subscription={ne.NotifySubscriptionId}]. Change this setting or have users remove email delivery notifications if this is permanent **"); } else - { await m.SendEmailAsync(deliveryAddress, subject, body, ServerGlobalOpsSettingsCache.Notify); - } + } } catch (Exception ex) diff --git a/server/AyaNova/resource/de.json b/server/AyaNova/resource/de.json index bdc6dd7d..80a7abc5 100644 --- a/server/AyaNova/resource/de.json +++ b/server/AyaNova/resource/de.json @@ -508,6 +508,7 @@ "Notification": "Benachrichtigung", "NotifySubscription": "Benachrichtigungsabonnement", "NotifySubscriptionDelivery": "Benachrichtigungsliefermethode", + "NotifySubscriptionLinkText":"Benachrichtigungseinstellung ändern:", "Part": "Teil", "PartAssembly": "Teilebaugruppe", "PartByWarehouseInventory": "Teil nach Lagerbestand", @@ -2057,6 +2058,7 @@ "NotifyEventNotifyHealthCheck": "Integritätsprüfung des Benachrichtigungssystems", "NotifyEventBackupStatus": "Status der Sicherung", "NotifyEventCustomerServiceImminent": "Servicetermin", + "NotifyEventCustomerServiceImminentMessage": "Sie haben einen bevorstehenden Servicetermin in {0}\nVerwenden Sie den folgenden Link, um die Details anzuzeigen:", "NotifyEventPartRequested": "Teil angefordert", "NotifyEventWorkorderTotalExceedsThreshold": "Der Gesamtbetrag des Arbeitsauftrags überschreitet den Schwellenwert", "NotifyEventWorkorderStatusAge": "Arbeitsauftragsstatus für die Zeitspanne unverändert", diff --git a/server/AyaNova/resource/en.json b/server/AyaNova/resource/en.json index efe1439b..6b5236b7 100644 --- a/server/AyaNova/resource/en.json +++ b/server/AyaNova/resource/en.json @@ -508,6 +508,7 @@ "Notification": "Notification", "NotifySubscription": "Notification subscription", "NotifySubscriptionDelivery": "Notification delivery method", + "NotifySubscriptionLinkText":"Change notification setting:", "Part": "Part", "PartAssembly": "Part Assembly", "PartByWarehouseInventory": "Part by warehouse inventory", @@ -2056,7 +2057,8 @@ "NotifyEventPartRequestReceived": "Requested part received", "NotifyEventNotifyHealthCheck": "Notification system health check", "NotifyEventBackupStatus": "Backup status", - "NotifyEventCustomerServiceImminent": "Service appointment", + "NotifyEventCustomerServiceImminent": "Service reminder", + "NotifyEventCustomerServiceImminentMessage": "You have an upcoming service appointment in {0}\nUse the following link to view the details:", "NotifyEventPartRequested": "Part requested", "NotifyEventWorkorderTotalExceedsThreshold": "Work order total exceeds threshold", "NotifyEventWorkorderStatusAge": "Work order status age", diff --git a/server/AyaNova/resource/es.json b/server/AyaNova/resource/es.json index 671add90..ab86f284 100644 --- a/server/AyaNova/resource/es.json +++ b/server/AyaNova/resource/es.json @@ -508,6 +508,7 @@ "Notification": "Notificación", "NotifySubscription": "Suscripción a notificaciones", "NotifySubscriptionDelivery": "Método de envío de notificaciones", + "NotifySubscriptionLinkText":"Cambiar la configuración de notificación:", "Part": "Pieza", "PartAssembly": "Montaje de la pieza", "PartByWarehouseInventory": "Pieza de inventario de almacén", @@ -2057,6 +2058,7 @@ "NotifyEventNotifyHealthCheck": "Verificación del estado del sistema de notificación", "NotifyEventBackupStatus": "Estado de copia de seguridad", "NotifyEventCustomerServiceImminent": "Cita de servicio", + "NotifyEventCustomerServiceImminentMessage": "Tiene una próxima cita de servicio en {0}\nUtilice el siguiente enlace para ver los detalles:", "NotifyEventPartRequested": "Parte de servicio solicitada", "NotifyEventWorkorderTotalExceedsThreshold": "El monto total de la orden de trabajo excede el umbral", "NotifyEventWorkorderStatusAge": "Estado de la orden de trabajo sin cambios durante el período de tiempo", diff --git a/server/AyaNova/resource/fr.json b/server/AyaNova/resource/fr.json index 4ab101b1..5799fb72 100644 --- a/server/AyaNova/resource/fr.json +++ b/server/AyaNova/resource/fr.json @@ -508,6 +508,7 @@ "Notification": "Notification", "NotifySubscription": "Abonnement aux notifications", "NotifySubscriptionDelivery": "Méthode de notification", + "NotifySubscriptionLinkText":"Modifier le paramètre de notification :", "Part": "Pièce", "PartAssembly": "Assemblage de pièce", "PartByWarehouseInventory": "Pièce par stock de magasin", @@ -2057,6 +2058,7 @@ "NotifyEventNotifyHealthCheck": "Vérification de l'état du système de notification", "NotifyEventBackupStatus": "Statut de sauvegarde", "NotifyEventCustomerServiceImminent": "Rendez-vous de service", + "NotifyEventCustomerServiceImminentMessage": "Vous avez un rendez-vous de service à venir dans {0}\nUtilisez le lien suivant pour afficher les détails:", "NotifyEventPartRequested": "Pièce demandée", "NotifyEventWorkorderTotalExceedsThreshold": "Le montant total de l'ordre de travail dépasse le seuil", "NotifyEventWorkorderStatusAge": "Statut de l'ordre de travail inchangé pour la période de temps",