From 4e2978835502d84f3a23d313930d4f4eef29aff3 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Thu, 9 Jul 2020 19:09:54 +0000 Subject: [PATCH] --- .vscode/launch.json | 2 +- devdocs/specs/core-notification.txt | 23 +++++++++---- server/AyaNova/biz/NotifyEventType.cs | 47 +++++++++++++++++++++++++++ server/AyaNova/util/AySchema.cs | 34 +++++++++++-------- 4 files changed, 85 insertions(+), 21 deletions(-) create mode 100644 server/AyaNova/biz/NotifyEventType.cs diff --git a/.vscode/launch.json b/.vscode/launch.json index 396abc9b..33155498 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -45,7 +45,7 @@ //"AYANOVA_LOG_LEVEL": "Debug", "AYANOVA_DEFAULT_TRANSLATION": "en", //TRANSLATION MUST BE en for Integration TESTING - //"AYANOVA_PERMANENTLY_ERASE_DATABASE": "true", + "AYANOVA_PERMANENTLY_ERASE_DATABASE": "true", "AYANOVA_DB_CONNECTION": "Server=localhost;Username=postgres;Password=raven;Database=AyaNova;", "AYANOVA_USE_URLS": "http://*:7575;", "AYANOVA_FOLDER_USER_FILES": "c:\\temp\\RavenTestData\\userfiles", diff --git a/devdocs/specs/core-notification.txt b/devdocs/specs/core-notification.txt index cd70a6a5..bb2c8544 100644 --- a/devdocs/specs/core-notification.txt +++ b/devdocs/specs/core-notification.txt @@ -22,8 +22,9 @@ BACKEND TODO / SYSTEM FOR RAVEN TODO: need a utility that can hash any adhoc collection of fields to work with various notify related objects -TODO: Never creates a duplicate APP or EMAIL notify, so checks a hash in history log before sending -TODO: HASH uniquely identifies a notification delivery and it's logged with the history so before a new delivery is sent it's compared to the delivery log and if it was sent + (NOT RELIABLE UNFORTUNATELY, JUST CHECK MULTIPLE FIELDS INSTEAD) +TODO: Never creates a duplicate APP or EMAIL notify, so checks in history log before sending +TODO: HASH (NOT RELIABLE UNFORTUNATELY, JUST CHECK MULTIPLE FIELDS INSTEAD) uniquely identifies a notification delivery and it's logged with the history so before a new delivery is sent it's compared to the delivery log and if it was sent in the last 90 days then it skips it. This will avoid duplicated emails or runaway notifies etc. Hash needs to be unique to the destination user, teh source object and the event type exactly, if there is any difference then it should not hash the same TODO: import v7 needs to create users for each contact and set their default for deliveries of notifications based on old region and send notification setting @@ -83,6 +84,14 @@ JOBS deletes any notifyevent with no event date created more than 90 days ago If has event date and it's passed then deletes it if created more than 90 days ago (pretty sure there are no back dated events, once it's passed it's past) NotifyDeliveryLog - deletes all log items older than 90 days + Notify + Scan the notifyevent table and deliver notifications accordingly + +GlobalBizSettings + Add Notification system ACTIVE bool value + +GlobalOpsNotificationSettings (copy from backup settings) + SMTP creds, return address, emergency ops address ALL COREBIZ Need CRUD check for notification events @@ -92,7 +101,7 @@ ALL COREBIZ subscriptions code has either cached or on db lookup to see all that apply, returns an array of notifyeventtypes to be processed Processes each notifyeventtype that it handles or passes off to central one maybe in some cases if common code -NotifyEventType enum +/NotifyEventType enum A collection of every possible notification event in one central location (rather than the old system where each object type held it's own collection) Translation keys for each notify event type as these will display in the UI and in sent emails etc @@ -167,8 +176,8 @@ NewCSR [GENERAL] NewMemo [PERSONAL] QuickNotification DEPRECATED replaced by DefaultNotification below [PERSONAL] QuoteCreatedUpdated - a bit weird, which is it created or updated? :) [GENERAL] -ScheduleMarkerImminent (will rename) [PERSONAL] -ScheduleMarkerCreated (will rename) [PERSONAL] +ScheduleMarkerImminent (now "reminder") [PERSONAL] +ScheduleMarkerCreated (now "reminder") [PERSONAL] WorkorderItemScheduledUserCreatedUpdated [PERSONAL] WorkorderItemScheduledUserEventImminent [PERSONAL] WorkorderCloseByDatePassed (user) [general] @@ -179,6 +188,8 @@ WorkorderItemPartRequestPartsReceived [GENERAL] ## NEW +DEADMAN_Job_procesor_fail direct email and other notifications? + Not sure how this could work to be honest, it would need to have a generator to do the checking unless we're talking about another timer somewhere else Daily_Notify_health_check (biz and ops) [GENERAL] Nightly_Notify_health_check (biz and ops)[GENERAL] BackupStatus case 3786 (biz and ops) [GENERAL] @@ -193,7 +204,7 @@ QuoteStatusAge [PERSONAL (prepared by), GENERAL] UnitWarranyExpiry case 1361 [GENERAL] UnitMeterReadingMultipleExceeded case 1254 [GENERAL] DefaultNotification case 3792 used for all system and old Quick notifications [EVERYONE] -TagNotification case 3799 [CONDITION: intag, outtag, ayatype global/specific] +deprecated, use objectCUD events for this: TagNotification case 3799 [CONDITION: intag, outtag, ayatype global/specific] (Note: this is actually just general notification if an object is created or updated and the tagging is optional) CRUD Notifications: diff --git a/server/AyaNova/biz/NotifyEventType.cs b/server/AyaNova/biz/NotifyEventType.cs new file mode 100644 index 00000000..0a300078 --- /dev/null +++ b/server/AyaNova/biz/NotifyEventType.cs @@ -0,0 +1,47 @@ +namespace AyaNova.Biz +{ + + + /// + /// All AyaNova notification event types + /// + /// + public enum NotifyEventType : int + { + //see core-notifications.txt spec doc for a bit more info on each type (they are named a little bit differently) + + ObjectDeleted = 1, + ObjectCreated = 2, + ObjectModified = 3, + WorkorderStatusChange=4, + ContractExpiring=5, + CSRAccepted=6, + CSRRejected=7, + WorkorderClosed=8, + QuoteStatusChange=9, + WorkorderFollowUp=10, + ServiceBankDepleted=11, + ReminderImminent=12, + ScheduledOnWorkorder=13, + ScheduledOnWorkorderImminent=14, + WorkorderCloseByPassed=15, + OutsideServiceOverdue=16, + OutsideServiceReceived=17, + PartRequestReceived=18, + NotifyHealthCheck=19,//with timespan to set frequency + BackupStatus=20, + CustomerServiceImminent=21, + PartRequested=22, + WorkorderTotalExceedsThreshold=23,//"the Andy" + WorkorderStatusAge=24,//sitting too long in same status + UnitWarrantyExpiry=25, + UnitMeterReadingMultipleExceeded=26, + DefaultNotification=27//old quick notification, refers now to any direct text notification internal or user to user used for system notifications + + + //NEW ITEMS REQUIRE translation KEYS + + } + + +}//eons diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs index 44d24613..6df567a0 100644 --- a/server/AyaNova/util/AySchema.cs +++ b/server/AyaNova/util/AySchema.cs @@ -20,7 +20,7 @@ namespace AyaNova.Util /////////// CHANGE THIS ON NEW SCHEMA UPDATE //////////////////// //!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!! - private const int DESIRED_SCHEMA_LEVEL = 11; + private const int DESIRED_SCHEMA_LEVEL = 12; internal const long EXPECTED_COLUMN_COUNT = 328; internal const long EXPECTED_INDEX_COUNT = 134; @@ -674,22 +674,28 @@ $BODY$; - // ////////////////////////////////////////////////// - // // WikiPage table - // if (currentSchema < 11) - // { - // LogUpdateMessage(log); + ////////////////////////////////////////////////// + // NOTIFICATIONS tables + if (currentSchema < 12) + { + LogUpdateMessage(log); - // await ExecQueryAsync("CREATE TABLE awikipage (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, " + - // "objectid bigint not null, objecttype integer not null, " + - // "content text)"); + await ExecQueryAsync("CREATE TABLE anotifysubscription (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, " + + "subscriberid bigint, subscriberayatype integer, ayatype integer, eventtype integer not null, advancenotice interval, " + + "idvalue integer, deliverymethod integer not null, deliveryaddress text, attachreportid bigint, intags varchar(255) ARRAY NULL, outtags varchar(255) ARRAY NULL)"); - // //INDEX: Most selective first as there is more unique ID's than unique types - // //to take advantage of this always query with where objectid=xx and objecttype=yy order - // await ExecQueryAsync("CREATE INDEX awikipage_typeid_idx ON awikipage (objectid, objecttype );"); - // await SetSchemaLevelAsync(++currentSchema); - // } + 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, eventdate timestamp, savedmessage text"); + + //created (timestamp used to clean out old stuck events), ayatype, objectid, eventtype, appliestouserid (single subscriber event), aEventDate, ASAVEDMESSAGE, HASH? + + //INDEX: Most selective first as there is more unique ID's than unique types + //to take advantage of this always query with where objectid=xx and objecttype=yy order + // await ExecQueryAsync("CREATE INDEX awikipage_typeid_idx ON awikipage (objectid, objecttype );"); + + await SetSchemaLevelAsync(++currentSchema); + }