From c5ced2da86cbcdf3567479bc46cc2ae7b4aa54b4 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Thu, 10 Mar 2022 17:35:25 +0000 Subject: [PATCH] case 4132 --- .vscode/launch.json | 2 +- server/AyaNova/biz/QuoteBiz.cs | 2 +- server/AyaNova/biz/WorkOrderBiz.cs | 477 ++++++++++++++--------------- 3 files changed, 240 insertions(+), 241 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 7c905164..2c3525c1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -48,7 +48,7 @@ "AYANOVA_DATA_PATH": "c:\\temp\\ravendata", "AYANOVA_USE_URLS": "http://*:7575;", //"AYANOVA_PERMANENTLY_ERASE_DATABASE":"true", - "AYANOVA_SERVER_TEST_MODE": "true", + "AYANOVA_SERVER_TEST_MODE": "false", "AYANOVA_SERVER_TEST_MODE_TZ_OFFSET": "-8", //"AYANOVA_REPORT_RENDERING_TIMEOUT":"1", "AYANOVA_SERVER_TEST_MODE_SEEDLEVEL": "small", diff --git a/server/AyaNova/biz/QuoteBiz.cs b/server/AyaNova/biz/QuoteBiz.cs index 6e551a44..659b6a72 100644 --- a/server/AyaNova/biz/QuoteBiz.cs +++ b/server/AyaNova/biz/QuoteBiz.cs @@ -1317,7 +1317,7 @@ namespace AyaNova.Biz { //QuoteStatusAge = 29,//* Quote STATUS unchanged for set time (stuck in state), conditional on: Duration (how long stuck), exact status selected IdValue, Tags. Advance notice can NOT be set //Always clear any old ones for this object as they are all irrelevant the moment the state has changed: - await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, proposedObj.Id, NotifyEventType.QuoteStatusAge); + await NotifyEventHelper.ClearPriorEventsForObject(ct, AyaType.Quote, proposedObj.Id, NotifyEventType.QuoteStatusAge); var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.QuoteStatusAge && z.IdValue == oProposed.QuoteStatusId).ToListAsync(); foreach (var sub in subs) { diff --git a/server/AyaNova/biz/WorkOrderBiz.cs b/server/AyaNova/biz/WorkOrderBiz.cs index 95e22224..c119ee85 100644 --- a/server/AyaNova/biz/WorkOrderBiz.cs +++ b/server/AyaNova/biz/WorkOrderBiz.cs @@ -1779,304 +1779,303 @@ namespace AyaNova.Biz //## CREATED (this is the only possible notification CREATION ayaEvent type for a workorder state as they are create only) - if (ayaEvent == AyaEvent.Created) + + //# STATUS CHANGE (create new status) { - //# STATUS CHANGE (create new status) + //Conditions: must match specific status id value and also tags below + //delivery is immediate so no need to remove old ones of this kind + var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderStatusChange && z.IdValue == oProposed.WorkOrderStatusId).ToListAsync(); + foreach (var sub in subs) { - //Conditions: must match specific status id value and also tags below - //delivery is immediate so no need to remove old ones of this kind - var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderStatusChange && z.IdValue == oProposed.WorkOrderStatusId).ToListAsync(); + //not for inactive users + if (!await UserBiz.UserIsActive(sub.UserId)) continue; + + //Tag match? (will be true if no sub tags so always safe to call this) + if (NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags)) + { + NotifyEvent n = new NotifyEvent() + { + EventType = NotifyEventType.WorkorderStatusChange, + UserId = sub.UserId, + AyaType = AyaType.WorkOrder, + ObjectId = oProposed.WorkOrderId, + NotifySubscriptionId = sub.Id, + Name = $"{WorkorderInfo.Serial.ToString()} - {wos.Name}" + }; + await ct.NotifyEvent.AddAsync(n); + log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + await ct.SaveChangesAsync(); + } + } + }//workorder status change event + + //# STATUS AGE + { + //WorkorderStatusAge = 24,//* Workorder STATUS unchanged for set time (stuck in state), conditional on: Duration (how long stuck), exact status selected IdValue, Tags. Advance notice can NOT be set + //Always clear any old ones for this object as they are all irrelevant the moment the state has changed: + await NotifyEventHelper.ClearPriorEventsForObject(ct, AyaType.WorkOrder, proposedObj.Id, NotifyEventType.WorkorderStatusAge); + var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderStatusAge && z.IdValue == oProposed.WorkOrderStatusId).ToListAsync(); + foreach (var sub in subs) + { + //not for inactive users + if (!await UserBiz.UserIsActive(sub.UserId)) continue; + + //WorkOrder Tag match? (Not State, state has no tags, will be true if no sub tags so always safe to call this) + if (NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags)) + { + NotifyEvent n = new NotifyEvent() + { + EventType = NotifyEventType.WorkorderStatusAge, + UserId = sub.UserId, + AyaType = AyaType.WorkOrder, + ObjectId = oProposed.WorkOrderId, + NotifySubscriptionId = sub.Id, + Name = $"{WorkorderInfo.Serial.ToString()} - {wos.Name}" + }; + await ct.NotifyEvent.AddAsync(n); + log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + await ct.SaveChangesAsync(); + } + } + }//workorder status age event + + + //# COMPLETE BY OVERDUE + { + //NOTE: the initial notification is created by the Workorder Header notification as it's where this time delayed notification is first generated + //the only job here in state notification is to remove any prior finish overdue notifications waiting if a new state is selected that is a completed state + + //NOTE ABOUT RE-OPEN DECISION ON HOW THIS WORKS: + + //what though if it's not a Completed status, then I guess don't remove it, but what if it *was* a Completed status and it's change to a non Completed? + //that, in essence re-opens it so it's not Completed at that point. + //My decision on this june 2021 is that a work order Completed status notification is satisifed the moment it's saved with a Completed status + //and nothing afterwards restarts that process so if a person sets closed status then sets open status again no new Completed overdue notification will be generated + + if (wos.Completed) + { + //Workorder was just set to a completed status so remove any notify events lurking to deliver for overdue + await NotifyEventHelper.ClearPriorEventsForObject(ct, AyaType.WorkOrder, oProposed.WorkOrderId, NotifyEventType.WorkorderCompletedStatusOverdue); + } + }//workorder complete by overdue change event + + + //# WorkorderTotalExceedsThreshold / "The Andy" + { + if (wos.Completed) + { + + //see if any subscribers to the workorder total exceeds notification + //that are active then proceed to fetch billed woitem children and total workorder and send notification if necessary + + bool haveTotal = false; + decimal GrandTotal = 0m; + + //look for potential subscribers + var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderTotalExceedsThreshold).ToListAsync(); foreach (var sub in subs) { //not for inactive users if (!await UserBiz.UserIsActive(sub.UserId)) continue; //Tag match? (will be true if no sub tags so always safe to call this) - if (NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags)) + //check early to avoid cost of fetching and calculating total if unnecessary + if (!NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags)) continue; + + //get the total because we have at least one subscriber and matching tags + if (haveTotal == false) { + GrandTotal = await WorkorderGrandTotalAsync(oProposed.WorkOrderId, ct); + haveTotal = true; + + //Note: not a time delayed notification, however user could be flipping states quickly triggering multiple notifications that are in queue temporarily + //so this will prevent that: + await NotifyEventHelper.ClearPriorEventsForObject(ct, AyaType.WorkOrder, oProposed.WorkOrderId, NotifyEventType.WorkorderTotalExceedsThreshold); + } + //Ok, we're here because there is a subscriber who is active and tags match so only check left is total against decvalue + if (sub.DecValue < GrandTotal) + { + //notification is a go NotifyEvent n = new NotifyEvent() { - EventType = NotifyEventType.WorkorderStatusChange, + EventType = NotifyEventType.WorkorderTotalExceedsThreshold, UserId = sub.UserId, AyaType = AyaType.WorkOrder, ObjectId = oProposed.WorkOrderId, NotifySubscriptionId = sub.Id, - Name = $"{WorkorderInfo.Serial.ToString()} - {wos.Name}" + Name = $"{WorkorderInfo.Serial.ToString()}", + DecValue = GrandTotal }; await ct.NotifyEvent.AddAsync(n); log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); await ct.SaveChangesAsync(); } } - }//workorder status change event + } + }//"The Andy" for Dynamic Dental corp. notification - //# STATUS AGE + + //# WorkorderCompleted - Customer AND User but customer only notifies if it's their workorder + { + if (wos.Completed) { - //WorkorderStatusAge = 24,//* Workorder STATUS unchanged for set time (stuck in state), conditional on: Duration (how long stuck), exact status selected IdValue, Tags. Advance notice can NOT be set - //Always clear any old ones for this object as they are all irrelevant the moment the state has changed: - await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, proposedObj.Id, NotifyEventType.WorkorderStatusAge); - var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderStatusAge && z.IdValue == oProposed.WorkOrderStatusId).ToListAsync(); + //look for potential subscribers + var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderCompleted).ToListAsync(); foreach (var sub in subs) { //not for inactive users if (!await UserBiz.UserIsActive(sub.UserId)) continue; - //WorkOrder Tag match? (Not State, state has no tags, will be true if no sub tags so always safe to call this) - if (NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags)) + //Customer User? + var UserInfo = await ct.User.AsNoTracking().Where(x => x.Id == sub.UserId).Select(x => new { x.CustomerId, x.UserType, x.HeadOfficeId }).FirstOrDefaultAsync(); + if (UserInfo.UserType == UserType.Customer || UserInfo.UserType == UserType.HeadOffice) { - NotifyEvent n = new NotifyEvent() + //CUSTOMER USER + + //Quick short circuit: if workorder doesn't have a customer id then it's not going to match no matter what + if (WorkorderInfo.CustomerId == 0) continue; + + var customerUserRights = await UserBiz.CustomerUserEffectiveRightsAsync(sub.UserId); + + //Are they allowed right now to use this type of notification? + if (!customerUserRights.NotifyWOCompleted) continue; + + //is this their related work order? + if (UserInfo.CustomerId != WorkorderInfo.CustomerId) { - EventType = NotifyEventType.WorkorderStatusAge, - UserId = sub.UserId, + //not the same customer but might be a head office user and this is one of their customers so check for that + if (UserInfo.HeadOfficeId == null) continue;//can't match any head office so no need to go further + + //see if workorder customer's head office is the same id as the user's headofficeid (note that a customer user with the same head office as a *different* customer workorder doesn't qualify) + var CustomerInfo = await ct.Customer.AsNoTracking().Where(x => x.Id == WorkorderInfo.CustomerId).Select(x => new { x.HeadOfficeId, x.BillHeadOffice }).FirstOrDefaultAsync(); + if (!CustomerInfo.BillHeadOffice) continue;//can't possibly match so no need to go further + if (UserInfo.HeadOfficeId != CustomerInfo.HeadOfficeId) continue; + } + } + else + { + //INSIDE USER + //Tag match? (will be true if no sub tags so always safe to call this) + //check early to avoid cost of fetching and calculating total if unnecessary + if (!NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags)) continue; + } + + //Ok, we're here so it must be ok to notify user + NotifyEvent n = new NotifyEvent() + { + EventType = NotifyEventType.WorkorderCompleted, + UserId = sub.UserId, + AyaType = AyaType.WorkOrder, + ObjectId = oProposed.WorkOrderId, + NotifySubscriptionId = sub.Id, + Name = $"{WorkorderInfo.Serial.ToString()}" + }; + await ct.NotifyEvent.AddAsync(n); + log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + await ct.SaveChangesAsync(); + } + } + }//WorkorderCompleted + + + + //## CUSTOMER "PROXY" NOTIFICATIONS + var custInfo = await ct.Customer.AsNoTracking().Where(x => x.Id == WorkorderInfo.CustomerId).Select(x => new { x.Active, x.Tags, x.EmailAddress }).FirstOrDefaultAsync(); + if (custInfo != null && custInfo.Active && !string.IsNullOrWhiteSpace(custInfo.EmailAddress))//can this customer receive *any* customer notifications? + { + //-------- Customer is notifiable ------ + + //# STATUS CHANGE (create new status) + { + //Conditions: must match specific status id value and also tags below + //delivery is immediate so no need to remove old ones of this kind + var subs = await ct.CustomerNotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderStatusChange && z.IdValue == oProposed.WorkOrderStatusId).OrderBy(z => z.Id).ToListAsync(); + foreach (var sub in subs) + { + //Object tags must match and Customer tags must match + if (NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags) && NotifyEventHelper.ObjectHasAllSubscriptionTags(custInfo.Tags, sub.CustomerTags)) + { + CustomerNotifyEvent n = new CustomerNotifyEvent() + { + EventType = NotifyEventType.WorkorderStatusChange, + CustomerId = WorkorderInfo.CustomerId, AyaType = AyaType.WorkOrder, ObjectId = oProposed.WorkOrderId, - NotifySubscriptionId = sub.Id, - Name = $"{WorkorderInfo.Serial.ToString()} - {wos.Name}" + CustomerNotifySubscriptionId = sub.Id, + Name = WorkorderInfo.Serial.ToString() }; - await ct.NotifyEvent.AddAsync(n); - log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + await ct.CustomerNotifyEvent.AddAsync(n); + log.LogDebug($"Adding CustomerNotifyEvent: [{n.ToString()}]"); await ct.SaveChangesAsync(); + break;//we have a match no need to process any further subs for this event + } + } + }//workorder status change event + + + //# STATUS AGE + { + //WorkorderStatusAge = 24,//* Workorder STATUS unchanged for set time (stuck in state), conditional on: Duration (how long stuck), exact status selected IdValue, Tags. Advance notice can NOT be set + //Always clear any old ones for this object as they are all irrelevant the moment the state has changed: + await NotifyEventHelper.ClearPriorCustomerNotifyEventsForObject(ct, proposedObj.AyaType, proposedObj.Id, NotifyEventType.WorkorderStatusAge); + var subs = await ct.CustomerNotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderStatusAge && z.IdValue == oProposed.WorkOrderStatusId).OrderBy(z => z.Id).ToListAsync(); + foreach (var sub in subs) + { + //Object tags must match and Customer tags must match + if (NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags) && NotifyEventHelper.ObjectHasAllSubscriptionTags(custInfo.Tags, sub.CustomerTags)) + { + CustomerNotifyEvent n = new CustomerNotifyEvent() + { + EventType = NotifyEventType.WorkorderStatusAge, + CustomerId = WorkorderInfo.CustomerId, + AyaType = AyaType.WorkOrder, + ObjectId = oProposed.WorkOrderId, + CustomerNotifySubscriptionId = sub.Id, + Name = WorkorderInfo.Serial.ToString() + }; + await ct.CustomerNotifyEvent.AddAsync(n); + log.LogDebug($"Adding CustomerNotifyEvent: [{n.ToString()}]"); + await ct.SaveChangesAsync(); + break;//we have a match no need to process any further subs for this event } } }//workorder status age event - //# COMPLETE BY OVERDUE - { - //NOTE: the initial notification is created by the Workorder Header notification as it's where this time delayed notification is first generated - //the only job here in state notification is to remove any prior finish overdue notifications waiting if a new state is selected that is a completed state - - //NOTE ABOUT RE-OPEN DECISION ON HOW THIS WORKS: - - //what though if it's not a Completed status, then I guess don't remove it, but what if it *was* a Completed status and it's change to a non Completed? - //that, in essence re-opens it so it's not Completed at that point. - //My decision on this june 2021 is that a work order Completed status notification is satisifed the moment it's saved with a Completed status - //and nothing afterwards restarts that process so if a person sets closed status then sets open status again no new Completed overdue notification will be generated - - if (wos.Completed) - { - //Workorder was just set to a completed status so remove any notify events lurking to deliver for overdue - await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, oProposed.WorkOrderId, NotifyEventType.WorkorderCompletedStatusOverdue); - } - }//workorder complete by overdue change event - - - //# WorkorderTotalExceedsThreshold / "The Andy" + //# WorkorderCompleted { if (wos.Completed) { - - //see if any subscribers to the workorder total exceeds notification - //that are active then proceed to fetch billed woitem children and total workorder and send notification if necessary - - bool haveTotal = false; - decimal GrandTotal = 0m; - - //look for potential subscribers - var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderTotalExceedsThreshold).ToListAsync(); + var subs = await ct.CustomerNotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderCompleted).OrderBy(z => z.Id).ToListAsync(); foreach (var sub in subs) { - //not for inactive users - if (!await UserBiz.UserIsActive(sub.UserId)) continue; - - //Tag match? (will be true if no sub tags so always safe to call this) - //check early to avoid cost of fetching and calculating total if unnecessary - if (!NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags)) continue; - - //get the total because we have at least one subscriber and matching tags - if (haveTotal == false) + //Object tags must match and Customer tags must match + if (NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags) && NotifyEventHelper.ObjectHasAllSubscriptionTags(custInfo.Tags, sub.CustomerTags)) { - GrandTotal = await WorkorderGrandTotalAsync(oProposed.WorkOrderId, ct); - haveTotal = true; - //Note: not a time delayed notification, however user could be flipping states quickly triggering multiple notifications that are in queue temporarily - //so this will prevent that: - await NotifyEventHelper.ClearPriorEventsForObject(ct, AyaType.WorkOrder, oProposed.WorkOrderId, NotifyEventType.WorkorderTotalExceedsThreshold); - } - //Ok, we're here because there is a subscriber who is active and tags match so only check left is total against decvalue - if (sub.DecValue < GrandTotal) - { - //notification is a go - NotifyEvent n = new NotifyEvent() + CustomerNotifyEvent n = new CustomerNotifyEvent() { - EventType = NotifyEventType.WorkorderTotalExceedsThreshold, - UserId = sub.UserId, + EventType = NotifyEventType.WorkorderCompleted, + CustomerId = WorkorderInfo.CustomerId, AyaType = AyaType.WorkOrder, ObjectId = oProposed.WorkOrderId, - NotifySubscriptionId = sub.Id, - Name = $"{WorkorderInfo.Serial.ToString()}", - DecValue = GrandTotal + CustomerNotifySubscriptionId = sub.Id, + Name = WorkorderInfo.Serial.ToString() }; - await ct.NotifyEvent.AddAsync(n); - log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + await ct.CustomerNotifyEvent.AddAsync(n); + log.LogDebug($"Adding CustomerNotifyEvent: [{n.ToString()}]"); await ct.SaveChangesAsync(); + break;//we have a match no need to process any further subs for this event } } } - }//"The Andy" for Dynamic Dental corp. notification - - - //# WorkorderCompleted - Customer AND User but customer only notifies if it's their workorder - { - if (wos.Completed) - { - //look for potential subscribers - var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderCompleted).ToListAsync(); - foreach (var sub in subs) - { - //not for inactive users - if (!await UserBiz.UserIsActive(sub.UserId)) continue; - - //Customer User? - var UserInfo = await ct.User.AsNoTracking().Where(x => x.Id == sub.UserId).Select(x => new { x.CustomerId, x.UserType, x.HeadOfficeId }).FirstOrDefaultAsync(); - if (UserInfo.UserType == UserType.Customer || UserInfo.UserType == UserType.HeadOffice) - { - //CUSTOMER USER - - //Quick short circuit: if workorder doesn't have a customer id then it's not going to match no matter what - if (WorkorderInfo.CustomerId == 0) continue; - - var customerUserRights = await UserBiz.CustomerUserEffectiveRightsAsync(sub.UserId); - - //Are they allowed right now to use this type of notification? - if (!customerUserRights.NotifyWOCompleted) continue; - - //is this their related work order? - if (UserInfo.CustomerId != WorkorderInfo.CustomerId) - { - //not the same customer but might be a head office user and this is one of their customers so check for that - if (UserInfo.HeadOfficeId == null) continue;//can't match any head office so no need to go further - - //see if workorder customer's head office is the same id as the user's headofficeid (note that a customer user with the same head office as a *different* customer workorder doesn't qualify) - var CustomerInfo = await ct.Customer.AsNoTracking().Where(x => x.Id == WorkorderInfo.CustomerId).Select(x => new { x.HeadOfficeId, x.BillHeadOffice }).FirstOrDefaultAsync(); - if (!CustomerInfo.BillHeadOffice) continue;//can't possibly match so no need to go further - if (UserInfo.HeadOfficeId != CustomerInfo.HeadOfficeId) continue; - } - } - else - { - //INSIDE USER - //Tag match? (will be true if no sub tags so always safe to call this) - //check early to avoid cost of fetching and calculating total if unnecessary - if (!NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags)) continue; - } - - //Ok, we're here so it must be ok to notify user - NotifyEvent n = new NotifyEvent() - { - EventType = NotifyEventType.WorkorderCompleted, - UserId = sub.UserId, - AyaType = AyaType.WorkOrder, - ObjectId = oProposed.WorkOrderId, - NotifySubscriptionId = sub.Id, - Name = $"{WorkorderInfo.Serial.ToString()}" - }; - await ct.NotifyEvent.AddAsync(n); - log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); - await ct.SaveChangesAsync(); - } - } }//WorkorderCompleted + //----------------------- + }//all customer proxy if notifiable - //## CUSTOMER "PROXY" NOTIFICATIONS - var custInfo = await ct.Customer.AsNoTracking().Where(x => x.Id == WorkorderInfo.CustomerId).Select(x => new { x.Active, x.Tags, x.EmailAddress }).FirstOrDefaultAsync(); - if (custInfo != null && custInfo.Active && !string.IsNullOrWhiteSpace(custInfo.EmailAddress))//can this customer receive *any* customer notifications? - { - //-------- Customer is notifiable ------ - //# STATUS CHANGE (create new status) - { - //Conditions: must match specific status id value and also tags below - //delivery is immediate so no need to remove old ones of this kind - var subs = await ct.CustomerNotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderStatusChange && z.IdValue == oProposed.WorkOrderStatusId).OrderBy(z => z.Id).ToListAsync(); - foreach (var sub in subs) - { - //Object tags must match and Customer tags must match - if (NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags) && NotifyEventHelper.ObjectHasAllSubscriptionTags(custInfo.Tags, sub.CustomerTags)) - { - CustomerNotifyEvent n = new CustomerNotifyEvent() - { - EventType = NotifyEventType.WorkorderStatusChange, - CustomerId = WorkorderInfo.CustomerId, - AyaType = AyaType.WorkOrder, - ObjectId = oProposed.WorkOrderId, - CustomerNotifySubscriptionId = sub.Id, - Name = WorkorderInfo.Serial.ToString() - }; - await ct.CustomerNotifyEvent.AddAsync(n); - log.LogDebug($"Adding CustomerNotifyEvent: [{n.ToString()}]"); - await ct.SaveChangesAsync(); - break;//we have a match no need to process any further subs for this event - } - } - }//workorder status change event - - - //# STATUS AGE - { - //WorkorderStatusAge = 24,//* Workorder STATUS unchanged for set time (stuck in state), conditional on: Duration (how long stuck), exact status selected IdValue, Tags. Advance notice can NOT be set - //Always clear any old ones for this object as they are all irrelevant the moment the state has changed: - await NotifyEventHelper.ClearPriorCustomerNotifyEventsForObject(ct, proposedObj.AyaType, proposedObj.Id, NotifyEventType.WorkorderStatusAge); - var subs = await ct.CustomerNotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderStatusAge && z.IdValue == oProposed.WorkOrderStatusId).OrderBy(z => z.Id).ToListAsync(); - foreach (var sub in subs) - { - //Object tags must match and Customer tags must match - if (NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags) && NotifyEventHelper.ObjectHasAllSubscriptionTags(custInfo.Tags, sub.CustomerTags)) - { - CustomerNotifyEvent n = new CustomerNotifyEvent() - { - EventType = NotifyEventType.WorkorderStatusAge, - CustomerId = WorkorderInfo.CustomerId, - AyaType = AyaType.WorkOrder, - ObjectId = oProposed.WorkOrderId, - CustomerNotifySubscriptionId = sub.Id, - Name = WorkorderInfo.Serial.ToString() - }; - await ct.CustomerNotifyEvent.AddAsync(n); - log.LogDebug($"Adding CustomerNotifyEvent: [{n.ToString()}]"); - await ct.SaveChangesAsync(); - break;//we have a match no need to process any further subs for this event - } - } - }//workorder status age event - - - //# WorkorderCompleted - { - if (wos.Completed) - { - var subs = await ct.CustomerNotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderCompleted).OrderBy(z => z.Id).ToListAsync(); - foreach (var sub in subs) - { - //Object tags must match and Customer tags must match - if (NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags) && NotifyEventHelper.ObjectHasAllSubscriptionTags(custInfo.Tags, sub.CustomerTags)) - { - - CustomerNotifyEvent n = new CustomerNotifyEvent() - { - EventType = NotifyEventType.WorkorderCompleted, - CustomerId = WorkorderInfo.CustomerId, - AyaType = AyaType.WorkOrder, - ObjectId = oProposed.WorkOrderId, - CustomerNotifySubscriptionId = sub.Id, - Name = WorkorderInfo.Serial.ToString() - }; - await ct.CustomerNotifyEvent.AddAsync(n); - log.LogDebug($"Adding CustomerNotifyEvent: [{n.ToString()}]"); - await ct.SaveChangesAsync(); - break;//we have a match no need to process any further subs for this event - } - } - } - }//WorkorderCompleted - - //----------------------- - }//all customer proxy if notifiable - - - } }//end of process notifications