case 4132

This commit is contained in:
2022-03-10 17:35:25 +00:00
parent 35f8096a0f
commit c5ced2da86
3 changed files with 240 additions and 241 deletions

2
.vscode/launch.json vendored
View File

@@ -48,7 +48,7 @@
"AYANOVA_DATA_PATH": "c:\\temp\\ravendata", "AYANOVA_DATA_PATH": "c:\\temp\\ravendata",
"AYANOVA_USE_URLS": "http://*:7575;", "AYANOVA_USE_URLS": "http://*:7575;",
//"AYANOVA_PERMANENTLY_ERASE_DATABASE":"true", //"AYANOVA_PERMANENTLY_ERASE_DATABASE":"true",
"AYANOVA_SERVER_TEST_MODE": "true", "AYANOVA_SERVER_TEST_MODE": "false",
"AYANOVA_SERVER_TEST_MODE_TZ_OFFSET": "-8", "AYANOVA_SERVER_TEST_MODE_TZ_OFFSET": "-8",
//"AYANOVA_REPORT_RENDERING_TIMEOUT":"1", //"AYANOVA_REPORT_RENDERING_TIMEOUT":"1",
"AYANOVA_SERVER_TEST_MODE_SEEDLEVEL": "small", "AYANOVA_SERVER_TEST_MODE_SEEDLEVEL": "small",

View File

@@ -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 //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: //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(); var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.QuoteStatusAge && z.IdValue == oProposed.QuoteStatusId).ToListAsync();
foreach (var sub in subs) foreach (var sub in subs)
{ {

View File

@@ -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) //## 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 //not for inactive users
//delivery is immediate so no need to remove old ones of this kind if (!await UserBiz.UserIsActive(sub.UserId)) continue;
var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderStatusChange && z.IdValue == oProposed.WorkOrderStatusId).ToListAsync();
//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) foreach (var sub in subs)
{ {
//not for inactive users //not for inactive users
if (!await UserBiz.UserIsActive(sub.UserId)) continue; if (!await UserBiz.UserIsActive(sub.UserId)) continue;
//Tag match? (will be true if no sub tags so always safe to call this) //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() NotifyEvent n = new NotifyEvent()
{ {
EventType = NotifyEventType.WorkorderStatusChange, EventType = NotifyEventType.WorkorderTotalExceedsThreshold,
UserId = sub.UserId, UserId = sub.UserId,
AyaType = AyaType.WorkOrder, AyaType = AyaType.WorkOrder,
ObjectId = oProposed.WorkOrderId, ObjectId = oProposed.WorkOrderId,
NotifySubscriptionId = sub.Id, NotifySubscriptionId = sub.Id,
Name = $"{WorkorderInfo.Serial.ToString()} - {wos.Name}" Name = $"{WorkorderInfo.Serial.ToString()}",
DecValue = GrandTotal
}; };
await ct.NotifyEvent.AddAsync(n); await ct.NotifyEvent.AddAsync(n);
log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]");
await ct.SaveChangesAsync(); 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 //look for potential subscribers
//Always clear any old ones for this object as they are all irrelevant the moment the state has changed: var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderCompleted).ToListAsync();
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();
foreach (var sub in subs) foreach (var sub in subs)
{ {
//not for inactive users //not for inactive users
if (!await UserBiz.UserIsActive(sub.UserId)) continue; 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) //Customer User?
if (NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags)) 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, //not the same customer but might be a head office user and this is one of their customers so check for that
UserId = sub.UserId, 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, AyaType = AyaType.WorkOrder,
ObjectId = oProposed.WorkOrderId, ObjectId = oProposed.WorkOrderId,
NotifySubscriptionId = sub.Id, CustomerNotifySubscriptionId = sub.Id,
Name = $"{WorkorderInfo.Serial.ToString()} - {wos.Name}" Name = WorkorderInfo.Serial.ToString()
}; };
await ct.NotifyEvent.AddAsync(n); await ct.CustomerNotifyEvent.AddAsync(n);
log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); log.LogDebug($"Adding CustomerNotifyEvent: [{n.ToString()}]");
await ct.SaveChangesAsync(); 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 }//workorder status age event
//# COMPLETE BY OVERDUE //# WorkorderCompleted
{
//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"
{ {
if (wos.Completed) if (wos.Completed)
{ {
var subs = await ct.CustomerNotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.WorkorderCompleted).OrderBy(z => z.Id).ToListAsync();
//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) foreach (var sub in subs)
{ {
//not for inactive users //Object tags must match and Customer tags must match
if (!await UserBiz.UserIsActive(sub.UserId)) continue; if (NotifyEventHelper.ObjectHasAllSubscriptionTags(WorkorderInfo.Tags, sub.Tags) && NotifyEventHelper.ObjectHasAllSubscriptionTags(custInfo.Tags, sub.CustomerTags))
//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)
{ {
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 CustomerNotifyEvent n = new CustomerNotifyEvent()
//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.WorkorderTotalExceedsThreshold, EventType = NotifyEventType.WorkorderCompleted,
UserId = sub.UserId, CustomerId = WorkorderInfo.CustomerId,
AyaType = AyaType.WorkOrder, AyaType = AyaType.WorkOrder,
ObjectId = oProposed.WorkOrderId, ObjectId = oProposed.WorkOrderId,
NotifySubscriptionId = sub.Id, CustomerNotifySubscriptionId = sub.Id,
Name = $"{WorkorderInfo.Serial.ToString()}", Name = WorkorderInfo.Serial.ToString()
DecValue = GrandTotal
}; };
await ct.NotifyEvent.AddAsync(n); await ct.CustomerNotifyEvent.AddAsync(n);
log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); log.LogDebug($"Adding CustomerNotifyEvent: [{n.ToString()}]");
await ct.SaveChangesAsync(); 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 }//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 }//end of process notifications