This commit is contained in:
@@ -66,8 +66,8 @@ TODO: Translation keys needed:
|
|||||||
NotifyDeliveryMethod
|
NotifyDeliveryMethod
|
||||||
NotifyEventType
|
NotifyEventType
|
||||||
NotifyDeliveryAddress
|
NotifyDeliveryAddress
|
||||||
InTags
|
tags
|
||||||
OutTags
|
|
||||||
|
|
||||||
|
|
||||||
todo: updating subscriptions must clear out old events and notifications if they are affected
|
todo: updating subscriptions must clear out old events and notifications if they are affected
|
||||||
@@ -109,9 +109,9 @@ OBJECTS Saving an object triggers notification processing for that object:
|
|||||||
DUPES - there can be near dupes here because user may have multiple of identical but vary in only:
|
DUPES - there can be near dupes here because user may have multiple of identical but vary in only:
|
||||||
Delivery method
|
Delivery method
|
||||||
advancenoticetimespan (e.g. contract expiring could be one 90 days in advance to renegotiate and then one 10 days in advance for notify service to cancel etc)
|
advancenoticetimespan (e.g. contract expiring could be one 90 days in advance to renegotiate and then one 10 days in advance for notify service to cancel etc)
|
||||||
InTags - notify applies if has these tags
|
tags - notify applies if has these tags
|
||||||
empty means any
|
empty means any
|
||||||
OutTags - notify cancelled if has these tags
|
s - notify cancelled if has these tags
|
||||||
empty means any
|
empty means any
|
||||||
out trumps an in, default is safer option
|
out trumps an in, default is safer option
|
||||||
|
|
||||||
@@ -186,11 +186,11 @@ MailMessageDelivery
|
|||||||
|
|
||||||
/notifysubscription table - contains all user (and customer user) subscriptions to events and delivery method, if user wants two delivery
|
/notifysubscription table - contains all user (and customer user) subscriptions to events and delivery method, if user wants two delivery
|
||||||
methods they have two entries here, no other table indicates events to be tracked, has user id
|
methods they have two entries here, no other table indicates events to be tracked, has user id
|
||||||
also ayatype GLOBAL means that the subscription applies to events of any corebiz type
|
also ayatype must be specific not GLOBAL to avoid a "sorcerers apprentice" runaway issue and many role related issues potentially
|
||||||
so for example a CreatedWithTag notification or UpdatedWithTag notification will work on any object with that tag if global or a specific type i.e. customer with that tag
|
so for example a CreatedWithTag notification or UpdatedWithTag notification will work on any object with that tag if a specific type i.e. customer with that tag
|
||||||
Then they can control by tag as well, intags are used to filter and include (or any if no intags), outtags filter out and trump intags
|
Then they can control by tag as well, tags are used to filter and include (or any if no tags), s filter out and trump tags
|
||||||
These are also used for tag type conditions
|
These are also used for tag type conditions
|
||||||
(aID, userId, ayatype, aEventType, advancenoticetimespan, agevalue, idvalue, decvalue, aDeliveryMethod, deliveryaddress, attachreportid, intags, outtags, HASH)
|
(aID, userId, ayatype, aEventType, advancenoticetimespan, agevalue, idvalue, decvalue, aDeliveryMethod, deliveryaddress, attachreportid, tags, s, HASH)
|
||||||
|
|
||||||
/Notifyevent table - contains all events, created by updating objects or directly in some cases and used by generator for processing as deliveries
|
/Notifyevent table - contains all events, created by updating objects or directly in some cases and used by generator for processing as deliveries
|
||||||
created (timestamp used to clean out old stuck events), ayatype, objectid, eventtype, appliestouserid (single subscriber event), aEventDate, ASAVEDMESSAGE, HASH?
|
created (timestamp used to clean out old stuck events), ayatype, objectid, eventtype, appliestouserid (single subscriber event), aEventDate, ASAVEDMESSAGE, HASH?
|
||||||
@@ -261,13 +261,16 @@ UnitMeterReadingMultipleExceeded case 1254 [GENERAL]
|
|||||||
DefaultNotification case 3792 used for all system and old Quick notifications [EVERYONE]
|
DefaultNotification case 3792 used for all system and old Quick notifications [EVERYONE]
|
||||||
Always present for inapp, user can add more for email if they want and filters or whatever but there is always a built in non-visible subscription to inapp for this
|
Always present for inapp, user can add more for email if they want and filters or whatever but there is always a built in non-visible subscription to inapp for this
|
||||||
|
|
||||||
deprecated, use objectCUD events for this: TagNotification case 3799 [CONDITION: intag, outtag, ayatype global/specific]
|
deprecated, use objectCUD events for this: TagNotification case 3799 [CONDITION: tag, , ayatype global/specific]
|
||||||
(Note: this is actually just general notification if an object is created or updated and the tagging is optional)
|
(Note: this is actually just general notification if an object is created or updated and the tagging is optional)
|
||||||
|
|
||||||
CRUD Notifications:
|
CRUD Notifications:
|
||||||
(note: tag filterable and also can select type specifically or global for any type)
|
(note: tag filterable and select type specifically. Global is not a valid type for this to avoid issues)
|
||||||
(note: differs from tag notification above in that only applies on a CHANGE of TAGS, this is an always for this op and tags are just an optional filter)
|
(note:
|
||||||
[CONDITION: intag, outtag, ayatype global/specific]
|
|
||||||
|
### WHAT DOES THIS MEAN?:differs from tag notification above in that only applies on a CHANGE of TAGS, this is an always for this op and tags are just an optional filter)
|
||||||
|
|
||||||
|
[CONDITION: tag, , ayatype specific]
|
||||||
ObjectCreated
|
ObjectCreated
|
||||||
ObjectUpdated
|
ObjectUpdated
|
||||||
ObjectDeleted
|
ObjectDeleted
|
||||||
|
|||||||
@@ -37,12 +37,10 @@ namespace AyaNova.DataList
|
|||||||
dlistView.Add(cm);
|
dlistView.Add(cm);
|
||||||
|
|
||||||
cm = new JObject();
|
cm = new JObject();
|
||||||
cm.fld = "intags";
|
cm.fld = "tags";
|
||||||
dlistView.Add(cm);
|
dlistView.Add(cm);
|
||||||
|
|
||||||
cm = new JObject();
|
|
||||||
cm.fld = "outtags";
|
|
||||||
dlistView.Add(cm);
|
|
||||||
|
|
||||||
|
|
||||||
DefaultListView = dlistView.ToString(Newtonsoft.Json.Formatting.None);
|
DefaultListView = dlistView.ToString(Newtonsoft.Json.Formatting.None);
|
||||||
@@ -104,16 +102,11 @@ namespace AyaNova.DataList
|
|||||||
FieldDefinitions.Add(new AyaDataListFieldDefinition
|
FieldDefinitions.Add(new AyaDataListFieldDefinition
|
||||||
{
|
{
|
||||||
TKey = "InTags",
|
TKey = "InTags",
|
||||||
FieldKey = "intags",
|
FieldKey = "tags",
|
||||||
UiFieldDataType = (int)UiFieldDataType.Tags
|
UiFieldDataType = (int)UiFieldDataType.Tags
|
||||||
});
|
});
|
||||||
|
|
||||||
FieldDefinitions.Add(new AyaDataListFieldDefinition
|
|
||||||
{
|
|
||||||
TKey = "OutTags",
|
|
||||||
FieldKey = "outtags",
|
|
||||||
UiFieldDataType = (int)UiFieldDataType.Tags
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,22 +37,30 @@ namespace AyaNova.Biz
|
|||||||
await AddEvent(new NotifyEvent() { EventType = NotifyEventType.ServerOperationsProblem, Message = message });
|
await AddEvent(new NotifyEvent() { EventType = NotifyEventType.ServerOperationsProblem, Message = message });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Add event if there are subscribers
|
||||||
public static async Task AddEvent(NotifyEvent ev)
|
public static async Task AddEvent(NotifyEvent ev, List<string> inTags = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
log.LogTrace($"AddEvent processing: [{ev.ToString()}]");
|
log.LogTrace($"AddEvent processing: [{ev.ToString()}]");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
List<NotifySubscription> subs = new List<NotifySubscription>();
|
||||||
log.LogTrace("Notify set to RUNNING state and starting now");
|
|
||||||
|
|
||||||
|
|
||||||
using (AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext)
|
using (AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext)
|
||||||
{
|
{
|
||||||
//iterate subs, figure out who gets this event
|
//iterate subs, figure out who gets this event
|
||||||
//add to table for any that do
|
//add to table for any that do
|
||||||
var subs=await ct.NotifySubscription.AsNoTracking().Where(z=>z.EventType==ev.EventType &&)
|
if (inTags == null || inTags.Count==0)
|
||||||
|
{
|
||||||
|
//No tags
|
||||||
|
subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == ev.EventType && z.AyaType == ev.AyaType).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//In tags
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,14 +47,12 @@ namespace AyaNova.Biz
|
|||||||
return null;
|
return null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newObject.InTags = TagBiz.NormalizeTags(newObject.InTags);
|
newObject.Tags = TagBiz.NormalizeTags(newObject.Tags);
|
||||||
newObject.OutTags = TagBiz.NormalizeTags(newObject.OutTags);
|
|
||||||
|
|
||||||
await ct.NotifySubscription.AddAsync(newObject);
|
await ct.NotifySubscription.AddAsync(newObject);
|
||||||
await ct.SaveChangesAsync();
|
await ct.SaveChangesAsync();
|
||||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
|
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
|
||||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.InTags, null);
|
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
|
||||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.OutTags, null);
|
|
||||||
return newObject;
|
return newObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,8 +78,7 @@ namespace AyaNova.Biz
|
|||||||
await ct.SaveChangesAsync();
|
await ct.SaveChangesAsync();
|
||||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
|
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
|
||||||
//await SearchIndexAsync(newObject, true);
|
//await SearchIndexAsync(newObject, true);
|
||||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.InTags, null);
|
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
|
||||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.OutTags, null);
|
|
||||||
return newObject;
|
return newObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,8 +109,7 @@ namespace AyaNova.Biz
|
|||||||
NotifySubscription SnapshotOfOriginalDBObj = new NotifySubscription();
|
NotifySubscription SnapshotOfOriginalDBObj = new NotifySubscription();
|
||||||
CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj);
|
CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj);
|
||||||
CopyObject.Copy(putObject, dbObject, "Id");//can update serial
|
CopyObject.Copy(putObject, dbObject, "Id");//can update serial
|
||||||
dbObject.InTags = TagBiz.NormalizeTags(dbObject.InTags);
|
dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags);
|
||||||
dbObject.OutTags = TagBiz.NormalizeTags(dbObject.OutTags);
|
|
||||||
|
|
||||||
ct.Entry(dbObject).OriginalValues["Concurrency"] = putObject.Concurrency;
|
ct.Entry(dbObject).OriginalValues["Concurrency"] = putObject.Concurrency;
|
||||||
await ValidateAsync(dbObject);
|
await ValidateAsync(dbObject);
|
||||||
@@ -131,8 +127,7 @@ namespace AyaNova.Biz
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct);
|
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct);
|
||||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.InTags, SnapshotOfOriginalDBObj.InTags);
|
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags);
|
||||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.OutTags, SnapshotOfOriginalDBObj.OutTags);
|
|
||||||
return dbObject;
|
return dbObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,8 +154,7 @@ namespace AyaNova.Biz
|
|||||||
//Log event
|
//Log event
|
||||||
await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.EventType.ToString(), ct);
|
await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.EventType.ToString(), ct);
|
||||||
// await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct);
|
// await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct);
|
||||||
await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.InTags);
|
await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags);
|
||||||
await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.OutTags);
|
|
||||||
//await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct);
|
//await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct);
|
||||||
//TODO: DELETE RELATED RECORDS HERE
|
//TODO: DELETE RELATED RECORDS HERE
|
||||||
//all good do the commit
|
//all good do the commit
|
||||||
|
|||||||
@@ -15,10 +15,7 @@ namespace AyaNova.Models
|
|||||||
public uint Concurrency { get; set; }
|
public uint Concurrency { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public long UserId { get; set; }
|
public long UserId { get; set; }
|
||||||
public AyaType? AyaType { get; set; }//Note: could be Global meaning any corebiz object would be included if relevant (e.g. ObjectCreated)
|
|
||||||
[Required]
|
|
||||||
public NotifyEventType EventType { get; set; }
|
|
||||||
public TimeSpan? AdvanceNotice { get; set; } //Note: I've been doing nullable wrong sort of: https://stackoverflow.com/a/29149207/8939
|
public TimeSpan? AdvanceNotice { get; set; } //Note: I've been doing nullable wrong sort of: https://stackoverflow.com/a/29149207/8939
|
||||||
public long? IdValue { get; set; }
|
public long? IdValue { get; set; }
|
||||||
public decimal? DecValue { get; set; }
|
public decimal? DecValue { get; set; }
|
||||||
@@ -27,13 +24,18 @@ namespace AyaNova.Models
|
|||||||
public NotifyDeliveryMethod DeliveryMethod { get; set; }
|
public NotifyDeliveryMethod DeliveryMethod { get; set; }
|
||||||
public string DeliveryAddress { get; set; }
|
public string DeliveryAddress { get; set; }
|
||||||
public long? AttachReportId { get; set; }
|
public long? AttachReportId { get; set; }
|
||||||
public List<string> InTags { get; set; }
|
|
||||||
public List<string> OutTags { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
|
//CONDITIONS - Following fields are all conditions set on whether to notify or not
|
||||||
|
public AyaType AyaType { get; set; }//Note: must be specific object, not global for any object related stuff to avoid many role issues and also potential overload
|
||||||
|
[Required]
|
||||||
|
public NotifyEventType EventType { get; set; }
|
||||||
|
public List<string> Tags { get; set; }//Tags to filter an event, object *must* have these tags to generate event related to it (AT TIME OF UPDATE)
|
||||||
|
|
||||||
public NotifySubscription()
|
public NotifySubscription()
|
||||||
{
|
{
|
||||||
InTags = new List<string>();
|
Tags = new List<string>();
|
||||||
OutTags = new List<string>();
|
AyaType= AyaType.NoType;
|
||||||
}
|
}
|
||||||
|
|
||||||
}//eoc
|
}//eoc
|
||||||
|
|||||||
@@ -1857,7 +1857,6 @@
|
|||||||
"NotifyEventType": "Benachrichtigungsereignis",
|
"NotifyEventType": "Benachrichtigungsereignis",
|
||||||
"NotifyDeliveryAddress": "An Adresse liefern",
|
"NotifyDeliveryAddress": "An Adresse liefern",
|
||||||
"InTags": "Filtern Sie in diesen Tags",
|
"InTags": "Filtern Sie in diesen Tags",
|
||||||
"OutTags": "Filtern Sie diese Tags heraus",
|
|
||||||
"NotifyEventObjectDeleted": "Objekt gelöscht",
|
"NotifyEventObjectDeleted": "Objekt gelöscht",
|
||||||
"NotifyEventObjectCreated": "Objekt erstellt",
|
"NotifyEventObjectCreated": "Objekt erstellt",
|
||||||
"NotifyEventObjectModified": "Objekt geändert",
|
"NotifyEventObjectModified": "Objekt geändert",
|
||||||
|
|||||||
@@ -1857,7 +1857,6 @@
|
|||||||
"NotifyEventType": "Notification event",
|
"NotifyEventType": "Notification event",
|
||||||
"NotifyDeliveryAddress": "Deliver to address",
|
"NotifyDeliveryAddress": "Deliver to address",
|
||||||
"InTags": "Filter include tags",
|
"InTags": "Filter include tags",
|
||||||
"OutTags": "Filter exclude tags",
|
|
||||||
"NotifyEventObjectDeleted": "Object deleted",
|
"NotifyEventObjectDeleted": "Object deleted",
|
||||||
"NotifyEventObjectCreated": "Object created",
|
"NotifyEventObjectCreated": "Object created",
|
||||||
"NotifyEventObjectModified": "Object changed",
|
"NotifyEventObjectModified": "Object changed",
|
||||||
|
|||||||
@@ -1857,7 +1857,6 @@
|
|||||||
"NotifyEventType": "Evento de notificación",
|
"NotifyEventType": "Evento de notificación",
|
||||||
"NotifyDeliveryAddress": "Entregar a la dirección de correo electrónico",
|
"NotifyDeliveryAddress": "Entregar a la dirección de correo electrónico",
|
||||||
"InTags": "Filtrar incluir etiquetas",
|
"InTags": "Filtrar incluir etiquetas",
|
||||||
"OutTags": "Filtrar etiquetas excluidas",
|
|
||||||
"NotifyEventObjectDeleted": "Objeto eliminado",
|
"NotifyEventObjectDeleted": "Objeto eliminado",
|
||||||
"NotifyEventObjectCreated": "Objeto creado",
|
"NotifyEventObjectCreated": "Objeto creado",
|
||||||
"NotifyEventObjectModified": "Objeto cambiado",
|
"NotifyEventObjectModified": "Objeto cambiado",
|
||||||
|
|||||||
@@ -1857,7 +1857,6 @@
|
|||||||
"NotifyEventType": "Événement de notification",
|
"NotifyEventType": "Événement de notification",
|
||||||
"NotifyDeliveryAddress": "Livrer à l'adresse",
|
"NotifyDeliveryAddress": "Livrer à l'adresse",
|
||||||
"InTags": "Filtrer les balises inclusives",
|
"InTags": "Filtrer les balises inclusives",
|
||||||
"OutTags": "Filtrer les tags exclusifs",
|
|
||||||
"NotifyEventObjectDeleted": "Objet supprimé",
|
"NotifyEventObjectDeleted": "Objet supprimé",
|
||||||
"NotifyEventObjectCreated": "Objet créé",
|
"NotifyEventObjectCreated": "Objet créé",
|
||||||
"NotifyEventObjectModified": "Objet changé",
|
"NotifyEventObjectModified": "Objet changé",
|
||||||
|
|||||||
@@ -684,8 +684,8 @@ $BODY$;
|
|||||||
LogUpdateMessage(log);
|
LogUpdateMessage(log);
|
||||||
|
|
||||||
await ExecQueryAsync("CREATE TABLE anotifysubscription (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, " +
|
await ExecQueryAsync("CREATE TABLE anotifysubscription (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, " +
|
||||||
"userid bigint not null, ayatype integer, eventtype integer not null, advancenotice interval, " +
|
"userid bigint not null, ayatype integer not null, eventtype integer not null, advancenotice interval, " +
|
||||||
"idvalue bigint, decvalue decimal(19,4), agevalue interval, deliverymethod integer not null, deliveryaddress text, attachreportid bigint, intags varchar(255) ARRAY, outtags varchar(255) ARRAY)");
|
"idvalue bigint, decvalue decimal(19,4), agevalue interval, deliverymethod integer not null, deliveryaddress text, attachreportid bigint, tags varchar(255) ARRAY)");
|
||||||
|
|
||||||
await ExecQueryAsync("CREATE TABLE anotifyevent (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, created timestamp not null, " +
|
await ExecQueryAsync("CREATE TABLE anotifyevent (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, created timestamp not null, " +
|
||||||
"ayatype integer, objectid bigint, eventtype integer not null, subscriptionid bigint not null, idvalue bigint, decvalue decimal(19,4), eventdate timestamp, deliverdate timestamp, message text)");
|
"ayatype integer, objectid bigint, eventtype integer not null, subscriptionid bigint not null, idvalue bigint, decvalue decimal(19,4), eventdate timestamp, deliverdate timestamp, message text)");
|
||||||
|
|||||||
Reference in New Issue
Block a user