diff --git a/.vscode/launch.json b/.vscode/launch.json index 4373ca4..7cade77 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -25,7 +25,7 @@ }, "env": { // "ASPNETCORE_ENVIRONMENT": "Development", - "SOCKEYE_JWT_SECRET": "1111111MyRandom32CharacterSecret", + "SOCKEYE_JWT_SECRET": "xxxxxxxxSockeye32CharacterSecret", "SOCKEYE_LOG_LEVEL": "Info", //"SOCKEYE_LOG_LEVEL": "Debug", //"SOCKEYE_LOG_LEVEL": "Trace", diff --git a/server/ControllerHelpers/ApiServerState.cs b/server/ControllerHelpers/ApiServerState.cs index fd03fb9..bc5d8b5 100644 --- a/server/ControllerHelpers/ApiServerState.cs +++ b/server/ControllerHelpers/ApiServerState.cs @@ -19,7 +19,8 @@ namespace Sockeye.Api.ControllerHelpers UNKNOWN = 0, ///No access for anyone API completely locked down. Not set by user but rather by internal server operations like importing or backup. Closed = 1, - + ///Access only to SuperUser account for migration from Rockfish + MigrateMode = 2, ///Access only to API Operations routes. Can be set by Ops user OpsOnly = 3, ///Open for all users (default). Can be set by Ops user @@ -128,7 +129,7 @@ namespace Sockeye.Api.ControllerHelpers throw new System.NotSupportedException("ApiServerState:ApiErrorCode - No error code is associated with server state OPEN"); case ServerState.OpsOnly: return ApiErrorCode.API_OPS_ONLY; - + case ServerState.Closed: return ApiErrorCode.API_CLOSED; @@ -177,7 +178,7 @@ namespace Sockeye.Api.ControllerHelpers } } - + public bool IsOpen { get diff --git a/server/Controllers/EnumListController.cs b/server/Controllers/EnumListController.cs index fca0eb6..f0fdfa0 100644 --- a/server/Controllers/EnumListController.cs +++ b/server/Controllers/EnumListController.cs @@ -556,10 +556,14 @@ namespace Sockeye.Api.Controllers else if (keyNameInLowerCase == StringUtil.TrimTypeName(typeof(TrialRequestStatus).ToString()).ToLowerInvariant()) { TranslationKeysToFetch.Add("TrialRequestStatusNew"); + TranslationKeysToFetch.Add("TrialRequestStatusAwaitingEmailValidation"); + TranslationKeysToFetch.Add("TrialRequestStatusAwaitingApproval"); TranslationKeysToFetch.Add("TrialRequestStatusApproved"); TranslationKeysToFetch.Add("TrialRequestStatusRejected"); var LT = await TranslationBiz.GetSubsetStaticAsync(TranslationKeysToFetch, translationId); ReturnList.Add(new NameIdItem() { Name = LT["TrialRequestStatusNew"], Id = (long)TrialRequestStatus.New }); + ReturnList.Add(new NameIdItem() { Name = LT["TrialRequestStatusAwaitingEmailValidation"], Id = (long)TrialRequestStatus.AwaitingEmailValidation }); + ReturnList.Add(new NameIdItem() { Name = LT["TrialRequestStatusAwaitingApproval"], Id = (long)TrialRequestStatus.AwaitingApproval }); ReturnList.Add(new NameIdItem() { Name = LT["TrialRequestStatusApproved"], Id = (long)TrialRequestStatus.Approved }); ReturnList.Add(new NameIdItem() { Name = LT["TrialRequestStatusRejected"], Id = (long)TrialRequestStatus.Rejected }); } diff --git a/server/biz/CustomerBiz.cs b/server/biz/CustomerBiz.cs index f9ae8f2..2f103d8 100644 --- a/server/biz/CustomerBiz.cs +++ b/server/biz/CustomerBiz.cs @@ -633,6 +633,7 @@ namespace Sockeye.Biz // public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]"); diff --git a/server/biz/CustomerNoteBiz.cs b/server/biz/CustomerNoteBiz.cs index 82dcec6..b549766 100644 --- a/server/biz/CustomerNoteBiz.cs +++ b/server/biz/CustomerNoteBiz.cs @@ -270,6 +270,7 @@ namespace Sockeye.Biz public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]"); diff --git a/server/biz/GZCaseBiz.cs b/server/biz/GZCaseBiz.cs index 88d12c5..708fc0b 100644 --- a/server/biz/GZCaseBiz.cs +++ b/server/biz/GZCaseBiz.cs @@ -412,6 +412,7 @@ namespace Sockeye.Biz // public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]"); diff --git a/server/biz/GlobalBizSettingsBiz.cs b/server/biz/GlobalBizSettingsBiz.cs index f3a72fd..d66221f 100644 --- a/server/biz/GlobalBizSettingsBiz.cs +++ b/server/biz/GlobalBizSettingsBiz.cs @@ -132,6 +132,14 @@ namespace Sockeye.Biz public async Task ImportRockfish(AyContext ct, ILogger log) { log.LogInformation("Start import from rockfish, authenticating"); + ApiServerState apiServerState = (ApiServerState)ServiceProviderProvider.Provider.GetService(typeof(ApiServerState)); + + //get the current server state so can set back to it later + ApiServerState.ServerState wasServerState = apiServerState.GetState(); + string wasReason = apiServerState.Reason; + apiServerState.SetOpsOnly("Migrating from Rockfish"); + ServerBootConfig.MIGRATING = true; + //Authenticate to rockfish //string sUrl = $"{LICENSE_SERVER_URL_ROCKFISH}rvr"; string URL_ROCKFISH = "https://rockfish.ayanova.com/"; @@ -766,6 +774,12 @@ namespace Sockeye.Biz var msg = "*** RockFish import FAILED ***"; log.LogError(ex, msg); } + finally + { + ServerBootConfig.MIGRATING = false; + log.LogInformation($"Migrate Rockfish: setting server state back to {wasServerState.ToString()}"); + apiServerState.SetState(wasServerState, wasReason); + } diff --git a/server/biz/HeadOfficeBiz.cs b/server/biz/HeadOfficeBiz.cs index 3f69020..2a02888 100644 --- a/server/biz/HeadOfficeBiz.cs +++ b/server/biz/HeadOfficeBiz.cs @@ -553,6 +553,7 @@ namespace Sockeye.Biz // public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]"); diff --git a/server/biz/LicenseBiz.cs b/server/biz/LicenseBiz.cs index cc509c6..ec2379a 100644 --- a/server/biz/LicenseBiz.cs +++ b/server/biz/LicenseBiz.cs @@ -432,10 +432,10 @@ namespace Sockeye.Biz string keyNoWS = System.Text.RegularExpressions.Regex.Replace(StringUtil.Extract(l.Key, "[KEY", "KEY]").Trim(), "(\"(?:[^\"\\\\]|\\\\.)*\")|\\s+", "$1"); var jKey = JObject.Parse(keyNoWS); -// #if (DEBUG) -// if (jKey["Key"]["DBID"].Value() == "mRntGkdwvYCDOAOroCQpB5Elbct09iNIS7lcU7QgRCY=") -// System.Diagnostics.Debugger.Break(); -// #endif + // #if (DEBUG) + // if (jKey["Key"]["DBID"].Value() == "mRntGkdwvYCDOAOroCQpB5Elbct09iNIS7lcU7QgRCY=") + // System.Diagnostics.Debugger.Break(); + // #endif var jaFeatures = (JArray)jKey.SelectToken("Key.Features"); @@ -972,6 +972,7 @@ namespace Sockeye.Biz // public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]"); @@ -997,8 +998,7 @@ namespace Sockeye.Biz if (ayaEvent == SockEvent.Created || ayaEvent == SockEvent.Modified) { - - + } }//end of process notifications diff --git a/server/biz/MemoBiz.cs b/server/biz/MemoBiz.cs index 603b4cc..e32b438 100644 --- a/server/biz/MemoBiz.cs +++ b/server/biz/MemoBiz.cs @@ -485,6 +485,7 @@ namespace Sockeye.Biz // public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]"); diff --git a/server/biz/ProductBiz.cs b/server/biz/ProductBiz.cs index 55e5146..dc877bd 100644 --- a/server/biz/ProductBiz.cs +++ b/server/biz/ProductBiz.cs @@ -404,6 +404,7 @@ namespace Sockeye.Biz // public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]"); diff --git a/server/biz/PurchaseBiz.cs b/server/biz/PurchaseBiz.cs index c7412a0..1f2eebd 100644 --- a/server/biz/PurchaseBiz.cs +++ b/server/biz/PurchaseBiz.cs @@ -427,6 +427,7 @@ namespace Sockeye.Biz // public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]"); @@ -452,7 +453,35 @@ namespace Sockeye.Biz if (ayaEvent == SockEvent.Created || ayaEvent == SockEvent.Modified) { + //# NEW PURCHASE VENDOR NOTIFICATION + if (ayaEvent == SockEvent.Created && (!string.IsNullOrWhiteSpace(o.VendorData))) + { + //Get product name and get customer name to notify + var productName = await ct.Product.AsNoTracking().Where(x => x.Id == o.ProductId).Select(x => x.Name).FirstOrDefaultAsync(); + var customerName = await ct.Customer.AsNoTracking().Where(x => x.Id == o.CustomerId).Select(x => x.Name).FirstOrDefaultAsync(); + { + //Newly created only and immediate delivery so no need to remove + var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.PurchaseNotificationReceived).ToListAsync(); + foreach (var sub in subs) + { + //not for inactive users + if (!await UserBiz.UserIsActive(sub.UserId)) continue; + NotifyEvent n = new NotifyEvent() + { + EventType = NotifyEventType.PurchaseNotificationReceived, + UserId = sub.UserId, + SockType = BizType, + ObjectId = o.Id, + NotifySubscriptionId = sub.Id, + Name = $"Purchase - {customerName}, {productName} x {o.Quantity} " + }; + await ct.NotifyEvent.AddAsync(n); + log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + await ct.SaveChangesAsync(); + } + } + }//new purchase notification event } diff --git a/server/biz/ReminderBiz.cs b/server/biz/ReminderBiz.cs index acb8d34..5171119 100644 --- a/server/biz/ReminderBiz.cs +++ b/server/biz/ReminderBiz.cs @@ -475,6 +475,7 @@ namespace Sockeye.Biz // public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]"); diff --git a/server/biz/ReviewBiz.cs b/server/biz/ReviewBiz.cs index 7b9e443..6c1bc2e 100644 --- a/server/biz/ReviewBiz.cs +++ b/server/biz/ReviewBiz.cs @@ -549,6 +549,7 @@ namespace Sockeye.Biz // public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]"); diff --git a/server/biz/SubscriptionServerBiz.cs b/server/biz/SubscriptionServerBiz.cs index 4c214ba..a96dffb 100644 --- a/server/biz/SubscriptionServerBiz.cs +++ b/server/biz/SubscriptionServerBiz.cs @@ -410,6 +410,7 @@ namespace Sockeye.Biz // public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]"); @@ -435,6 +436,39 @@ namespace Sockeye.Biz if (ayaEvent == SockEvent.Created || ayaEvent == SockEvent.Modified) { + //# NEW TRIAL SERVER REQUEST + if (ayaEvent == SockEvent.Created && o.Trial == true) + { + { + //Conditions: must match specific status id value and also tags below + //Newly created only and immediate delivery so no need to remove + var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.SubscriptionServerRequestReceived).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(o.Tags, sub.Tags)) + { + NotifyEvent n = new NotifyEvent() + { + EventType = NotifyEventType.SubscriptionServerRequestReceived, + UserId = sub.UserId, + SockType = BizType, + ObjectId = o.Id, + NotifySubscriptionId = sub.Id, + Name = $"{o.TrialCompany} - trial server requested" + }; + await ct.NotifyEvent.AddAsync(n); + log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + await ct.SaveChangesAsync(); + } + } + } + }//new trial server request event + + //# SUBSCRIPTION SERVER EXPIRY { //notify users about warranty expiry (time delayed) @@ -498,7 +532,7 @@ namespace Sockeye.Biz } } - }//subscription server expiry event + }//subscription server last updated event diff --git a/server/biz/TrialLicenseRequestBiz.cs b/server/biz/TrialLicenseRequestBiz.cs index d510651..433354a 100644 --- a/server/biz/TrialLicenseRequestBiz.cs +++ b/server/biz/TrialLicenseRequestBiz.cs @@ -270,7 +270,7 @@ namespace Sockeye.Biz private VizCache vc = new VizCache(); - + //////////////////////////////////////////////////////////////////////////////////////////////// // IMPORT EXPORT @@ -405,6 +405,7 @@ namespace Sockeye.Biz // public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]"); @@ -418,21 +419,135 @@ namespace Sockeye.Biz //SPECIFIC EVENTS FOR THIS OBJECT TrialLicenseRequest o = (TrialLicenseRequest)proposedObj; - //## DELETED EVENTS - //any event added below needs to be removed, so - //just blanket remove any event for this object of eventtype that would be added below here - //do it regardless any time there's an update and then - //let this code below handle the refreshing addition that could have changes - //await NotifyEventHelper.ClearPriorEventsForObject(ct, SockType.TrialLicenseRequest, o.Id, NotifyEventType.ContractExpiring); - - - //## CREATED / MODIFIED EVENTS - if (ayaEvent == SockEvent.Created || ayaEvent == SockEvent.Modified) + //# TRIAL KEY REQUEST EMAIL CONFIRMED - NOTIFY US IS READY FOR PROCESSING + if (ayaEvent == SockEvent.Modified && o.EmailValidated && o.Status == TrialRequestStatus.AwaitingApproval && o.Processed == null) { + { + //Newly created only and immediate delivery so no need to remove + var subs = await ct.NotifySubscription.AsNoTracking().Where(z => z.EventType == NotifyEventType.LicenseTrialRequestReceived).ToListAsync(); + foreach (var sub in subs) + { + //not for inactive users + if (!await UserBiz.UserIsActive(sub.UserId)) continue; + + NotifyEvent n = new NotifyEvent() + { + EventType = NotifyEventType.LicenseTrialRequestReceived, + UserId = sub.UserId, + SockType = BizType, + ObjectId = o.Id, + NotifySubscriptionId = sub.Id, + Name = $"{o.CompanyName} - trial license requested" + }; + await ct.NotifyEvent.AddAsync(n); + log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]"); + await ct.SaveChangesAsync(); + } + } + }//new trial key request event - } + + //## ------------------ DEFAULT NOTIFICATIONS ---------------- + //ValidateEmail request message,RavenTrialApproved (which sends pending manual generation message) and RavenTrialRejected messages are sent in this block + // + // + var custInfo = await ct.Customer.AsNoTracking().Where(x => x.Id == o.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 + + //----------------------- + } //------------------ /default notifications --------------- + + }//end of process notifications diff --git a/server/biz/TrialRequestStatus.cs b/server/biz/TrialRequestStatus.cs index cacf112..23dfe2b 100644 --- a/server/biz/TrialRequestStatus.cs +++ b/server/biz/TrialRequestStatus.cs @@ -3,8 +3,10 @@ namespace Sockeye.Biz public enum TrialRequestStatus { New = 0, - Approved = 1, - Rejected = 2 + AwaitingEmailValidation = 1, + AwaitingApproval = 2, + Approved = 3, + Rejected = 4 } }//eons \ No newline at end of file diff --git a/server/biz/UserBiz.cs b/server/biz/UserBiz.cs index cf5732f..120517e 100644 --- a/server/biz/UserBiz.cs +++ b/server/biz/UserBiz.cs @@ -954,6 +954,7 @@ namespace Sockeye.Biz // public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]"); diff --git a/server/biz/VendorBiz.cs b/server/biz/VendorBiz.cs index 6863b18..be3d9ef 100644 --- a/server/biz/VendorBiz.cs +++ b/server/biz/VendorBiz.cs @@ -538,6 +538,7 @@ namespace Sockeye.Biz // public async Task HandlePotentialNotificationEvent(SockEvent SockEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { + if (ServerBootConfig.MIGRATING) return; ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, SockEvent:{SockEvent}]"); diff --git a/server/util/AySchema.cs b/server/util/AySchema.cs index d1a7498..72f3dfc 100644 --- a/server/util/AySchema.cs +++ b/server/util/AySchema.cs @@ -980,6 +980,8 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusNew', 'New' FROM atranslation t where t.baselanguage = 'en'"); await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusApproved', 'Approved' FROM atranslation t where t.baselanguage = 'en'"); await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusRejected', 'Rejected' FROM atranslation t where t.baselanguage = 'en'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusAwaitingEmailValidation', 'Awaiting email validation' FROM atranslation t where t.baselanguage = 'en'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusAwaitingApproval', 'Awaiting approval' FROM atranslation t where t.baselanguage = 'en'"); //spanish translations await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialLicenseRequest', 'Trial license request' FROM atranslation t where t.baselanguage = 'es'"); @@ -995,6 +997,8 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusNew', 'New' FROM atranslation t where t.baselanguage = 'es'"); await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusApproved', 'Approved' FROM atranslation t where t.baselanguage = 'es'"); await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusRejected', 'Rejected' FROM atranslation t where t.baselanguage = 'es'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusAwaitingEmailValidation', 'Awaiting email validation' FROM atranslation t where t.baselanguage = 'es'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusAwaitingApproval', 'Awaiting approval' FROM atranslation t where t.baselanguage = 'es'"); //french translations await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialLicenseRequest', 'Trial license request' FROM atranslation t where t.baselanguage = 'fr'"); @@ -1010,6 +1014,8 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusNew', 'New' FROM atranslation t where t.baselanguage = 'fr'"); await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusApproved', 'Approved' FROM atranslation t where t.baselanguage = 'fr'"); await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusRejected', 'Rejected' FROM atranslation t where t.baselanguage = 'fr'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusAwaitingEmailValidation', 'Awaiting email validation' FROM atranslation t where t.baselanguage = 'fr'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusAwaitingApproval', 'Awaiting approval' FROM atranslation t where t.baselanguage = 'fr'"); //german translations await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialLicenseRequest', 'Trial license request' FROM atranslation t where t.baselanguage = 'de'"); @@ -1025,6 +1031,8 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusNew', 'New' FROM atranslation t where t.baselanguage = 'de'"); await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusApproved', 'Approved' FROM atranslation t where t.baselanguage = 'de'"); await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusRejected', 'Rejected' FROM atranslation t where t.baselanguage = 'de'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusAwaitingEmailValidation', 'Awaiting email validation' FROM atranslation t where t.baselanguage = 'de'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'TrialRequestStatusAwaitingApproval', 'Awaiting approval' FROM atranslation t where t.baselanguage = 'de'"); #endregion triallicenserequest @@ -1387,7 +1395,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); await SetSchemaLevelAsync(currentSchema); } - + //######################################### //!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!! diff --git a/server/util/ServerBootConfig.cs b/server/util/ServerBootConfig.cs index 99c9b96..50dd31a 100644 --- a/server/util/ServerBootConfig.cs +++ b/server/util/ServerBootConfig.cs @@ -26,7 +26,11 @@ namespace Sockeye.Util internal const long MAX_TRANSLATION_UPLOAD_BYTES = 15728640;//15MiB limit; currently export file is 200kb * 50 maximum at a time = 15mb //############################################################################################################ - + //############################ + //MIGRATING FLAG INTERNAL ONLY + //used to speed up rockfish migration with bypasses to notification processing + internal static bool MIGRATING { get; set; } + //############################ //Diagnostic static values used during development, may not be related to config at all, this is just a convenient class to put them in #if (DEBUG) diff --git a/todo.txt b/todo.txt index 3e0a117..9ad528c 100644 --- a/todo.txt +++ b/todo.txt @@ -1,11 +1,22 @@ TODO: -- Subscriptionserverbiz state change trigger potential notification and event log event!!! - -- Event log and event for server state change event should trigger an entry in the event log automatically -- events serverstate change can subscribe and be alerted etc - Purchase event must trigger notification event subscribable (might already due to created etc) +- figure out and implement default notifications for Customers where appropriate + these do not need to be subscribed to, they are automatic unless we need a way to prevent like a certain tag or something? + but do the ones only that are currently in rockfish + + This would be done just like any current customer notification but wouldn't check for subscribers as it would be automatic + maybe like how ayanova does //## CUSTOMER "PROXY" NOTIFICATIONS like in wokrorder closed + + + make sure to add + if (ServerBootConfig.MIGRATING) return; + check or all hell will break loose + Also wrap the notification in a DEBUG block so that it will send to gzmailadmin only instead of customer actual email + this way can really test out anything without fear + + - Message templates back and front new global setting fields: V7NewKey (rockfish v7 template) @@ -15,18 +26,12 @@ TODO: ValidateEmail (rockfish RVRController line 102) RavenTrialApproved (rockfish TrialController line 94) RavenTrialRejected (rockfish TrialController line 131) + + +- TODO: subscription server approved + Need message template and automatic proxy notification to customer - -- new notification event type and related code back and front for subscriptions etc - want all old rockfish style and new sockeye notifications to go through proper notify event code - - new: trial subscription server requested - - new: trial subscription server expiration - - new: subscription server expiration past - so if they don't re-up no active license then it warns me to shut it down - One for shutting down server and another for decommissioning - - - v7 license fetch route - v8 license fetch route - v8 trial request route @@ -47,7 +52,7 @@ TODO: fetched is set correctly headers tls version (once online are the same, should be since it's going through nginx technically for the tls part) -- Test v8 key fetch, trial request, the whole shebang locally +- Test v8 key fetch, trial request, all critical event notifications, event logging - the whole shebang locally - ONLINE TEST Install and put on sockeye.ayanova.com subdomain in nginx on alternate port Test ui functionality logins etc