This commit is contained in:
@@ -202,20 +202,10 @@ namespace Sockeye.Biz
|
||||
|
||||
private async Task ValidateAsync(GZCase proposedObj, GZCase currentObj)
|
||||
{
|
||||
bool isNew = currentObj == null;
|
||||
await Task.CompletedTask;
|
||||
// bool isNew = currentObj == null;
|
||||
|
||||
|
||||
|
||||
//Any form customizations to validate?
|
||||
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == SockType.GZCase.ToString());
|
||||
if (FormCustomization != null)
|
||||
{
|
||||
//Yeppers, do the validation, there are two, the custom fields and the regular fields that might be set to required
|
||||
|
||||
//validate users choices for required non custom fields
|
||||
RequiredFieldsValidator.Validate(this, FormCustomization, proposedObj);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -240,24 +240,7 @@ namespace Sockeye.Biz
|
||||
|
||||
|
||||
|
||||
private static string GenFetchCode()
|
||||
{
|
||||
|
||||
//sufficient for this purpose
|
||||
//https://stackoverflow.com/a/1344258/8939
|
||||
|
||||
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
var stringChars = new char[10];
|
||||
var random = new Random();
|
||||
|
||||
for (int i = 0; i < stringChars.Length; i++)
|
||||
{
|
||||
stringChars[i] = chars[random.Next(chars.Length)];
|
||||
}
|
||||
|
||||
var finalString = new String(stringChars);
|
||||
return finalString;
|
||||
}
|
||||
|
||||
|
||||
private static Dictionary<string, DateTime> LicenseToPluginsArray(License l)
|
||||
@@ -309,7 +292,7 @@ namespace Sockeye.Biz
|
||||
|
||||
StringBuilder sbKey = new StringBuilder();
|
||||
StringWriter sw = new StringWriter(sbKey);
|
||||
l.FetchCode = GenFetchCode();
|
||||
l.FetchCode = StringUtil.GenFetchCode();
|
||||
using (Newtonsoft.Json.JsonWriter w = new Newtonsoft.Json.JsonTextWriter(sw))
|
||||
{
|
||||
w.Formatting = Newtonsoft.Json.Formatting.Indented;
|
||||
|
||||
@@ -500,6 +500,12 @@ namespace Sockeye.Biz
|
||||
try
|
||||
{
|
||||
await ct.SaveChangesAsync();
|
||||
|
||||
//TODO: NOTIFICATION ON NEW KEY
|
||||
//BUT NOT if REVOKED token is the regto, we don't want them to know, just let AyaNova install it
|
||||
//this is for non-payment scenarios or chargebacks after license was sent
|
||||
|
||||
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
@@ -761,19 +767,7 @@ namespace Sockeye.Biz
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Any form customizations to validate?
|
||||
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == SockType.License.ToString());
|
||||
if (FormCustomization != null)
|
||||
{
|
||||
//Yeppers, do the validation, there are two, the custom fields and the regular fields that might be set to required
|
||||
|
||||
//validate users choices for required non custom fields
|
||||
RequiredFieldsValidator.Validate(this, FormCustomization, proposedObj);
|
||||
|
||||
}
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
@@ -998,7 +992,7 @@ namespace Sockeye.Biz
|
||||
if (ayaEvent == SockEvent.Created || ayaEvent == SockEvent.Modified)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}//end of process notifications
|
||||
|
||||
@@ -202,20 +202,7 @@ namespace Sockeye.Biz
|
||||
|
||||
private async Task ValidateAsync(Product proposedObj, Product currentObj)
|
||||
{
|
||||
bool isNew = currentObj == null;
|
||||
|
||||
|
||||
|
||||
//Any form customizations to validate?
|
||||
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == SockType.Product.ToString());
|
||||
if (FormCustomization != null)
|
||||
{
|
||||
//Yeppers, do the validation, there are two, the custom fields and the regular fields that might be set to required
|
||||
|
||||
//validate users choices for required non custom fields
|
||||
RequiredFieldsValidator.Validate(this, FormCustomization, proposedObj);
|
||||
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -203,20 +203,7 @@ namespace Sockeye.Biz
|
||||
|
||||
private async Task ValidateAsync(Purchase proposedObj, Purchase currentObj)
|
||||
{
|
||||
bool isNew = currentObj == null;
|
||||
|
||||
|
||||
|
||||
//Any form customizations to validate?
|
||||
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == SockType.Purchase.ToString());
|
||||
if (FormCustomization != null)
|
||||
{
|
||||
//Yeppers, do the validation, there are two, the custom fields and the regular fields that might be set to required
|
||||
|
||||
//validate users choices for required non custom fields
|
||||
RequiredFieldsValidator.Validate(this, FormCustomization, proposedObj);
|
||||
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,12 @@ namespace Sockeye.Biz
|
||||
//Key generator controller
|
||||
public static class RavenKeyFactory
|
||||
{
|
||||
//Sept 2022 decided all trial periods are 7 days, they can keep renewing a new trial by erasing data or request a longer period case by case
|
||||
public const int TRIAL_PERIOD_DAYS = 7;
|
||||
|
||||
|
||||
//Jan 2023 values
|
||||
public const int TRIAL_KEY_SUBSCRIPTION_PERIOD_DAYS = 7;
|
||||
public const int TRIAL_KEY_SUBSCRIPTION_CUSTOMER_USERS = 25555;//SEEDING required
|
||||
public const int TRIAL_KEY_SUBSCRIPTION_MAX_DATA_GB = 20;
|
||||
public const int TRIAL_KEY_PERPETUAL_PERIOD_DAYS = 14;
|
||||
public const int TRIAL_KEY_USERS = 5000;//SEEDING required minimum
|
||||
|
||||
//Unlicensed token
|
||||
private const string UNLICENSED_TOKEN = "UNLICENSED";
|
||||
@@ -29,8 +31,6 @@ namespace Sockeye.Biz
|
||||
|
||||
//LICENSE USER COUNT FEATURES
|
||||
|
||||
|
||||
|
||||
//SUBSCRIPTION
|
||||
private const string ACTIVE_INTERNAL_USERS_FEATURE_NAME = "ActiveInternalUsers";
|
||||
private const string ACTIVE_CUSTOMER_USERS_FEATURE_NAME = "ActiveCustomerUsers";
|
||||
|
||||
@@ -208,20 +208,7 @@ namespace Sockeye.Biz
|
||||
|
||||
private async Task ValidateAsync(SubscriptionServer proposedObj, SubscriptionServer currentObj)
|
||||
{
|
||||
bool isNew = currentObj == null;
|
||||
|
||||
|
||||
|
||||
//Any form customizations to validate?
|
||||
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == SockType.SubscriptionServer.ToString());
|
||||
if (FormCustomization != null)
|
||||
{
|
||||
//Yeppers, do the validation, there are two, the custom fields and the regular fields that might be set to required
|
||||
|
||||
//validate users choices for required non custom fields
|
||||
RequiredFieldsValidator.Validate(this, FormCustomization, proposedObj);
|
||||
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -49,11 +49,50 @@ namespace Sockeye.Biz
|
||||
else
|
||||
{
|
||||
newObject.Tags = TagBiz.NormalizeTags(newObject.Tags);
|
||||
|
||||
//Process a new request / Generate an email confirm code
|
||||
newObject.EmailConfirmCode = StringUtil.GenFetchCode();
|
||||
newObject.EmailValidated = false;
|
||||
newObject.Status = TrialRequestStatus.AwaitingEmailValidation;
|
||||
|
||||
await ct.TrialLicenseRequest.AddAsync(newObject);
|
||||
await ct.SaveChangesAsync();
|
||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, SockEvent.Created), ct);
|
||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(1, newObject.Id, BizType, SockEvent.Created), ct);
|
||||
await SearchIndexAsync(newObject, true);
|
||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
|
||||
|
||||
|
||||
//## ------------------ DEFAULT NOTIFICATIONS TO CUSTOMER ----------------
|
||||
//ValidateEmail request message,RavenTrialApproved (which sends pending manual generation message) and RavenTrialRejected messages are sent in this block
|
||||
//
|
||||
//Send verification request
|
||||
var verifyUrl = ServerGlobalOpsSettingsCache.Notify.SockeyeServerURL.Trim().TrimEnd('/') + $"/trial-license-request/verify/{newObject.EmailConfirmCode}";
|
||||
var body = ServerGlobalBizSettings.Cache.ValidateEmail.Replace("{verifyUrl}", verifyUrl);//$"Please verify your email address by clicking the link below or copy and pasting into a browser\r\n{verifyUrl}\r\nOnce your email is verified the request will be processed manually during business hours.\r\n(If you did not request this you can ignore this message)";
|
||||
|
||||
var notifyDirectSMTP = new Sockeye.Api.Controllers.NotifyController.NotifyDirectSMTP()
|
||||
{
|
||||
ToAddress = newObject.Email,
|
||||
Subject = "AyaNova trial request email verification",
|
||||
TextBody = body
|
||||
};
|
||||
|
||||
|
||||
IMailer m = Sockeye.Util.ServiceProviderProvider.Mailer;
|
||||
try
|
||||
{
|
||||
await m.SendEmailAsync(notifyDirectSMTP.ToAddress, notifyDirectSMTP.Subject, notifyDirectSMTP.TextBody, ServerGlobalOpsSettingsCache.Notify, null, null, null);
|
||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(1, notifyDirectSMTP.ObjectId, notifyDirectSMTP.SockType, SockEvent.DirectSMTP, $"\"{notifyDirectSMTP.Subject}\"->{notifyDirectSMTP.ToAddress}"), ct);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var err = "TrialLicenseRequest sending email confirmation request: SMTP direct message failed";
|
||||
await NotifyEventHelper.AddOpsProblemEvent(err, ex);
|
||||
AddError(ApiErrorCode.API_SERVER_ERROR, null, ExceptionUtil.ExtractAllExceptionMessages(ex));
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
await HandlePotentialNotificationEvent(SockEvent.Created, newObject);
|
||||
return newObject;
|
||||
}
|
||||
@@ -92,10 +131,58 @@ namespace Sockeye.Biz
|
||||
putObject.Tags = TagBiz.NormalizeTags(putObject.Tags);
|
||||
await ValidateAsync(putObject, dbObject);
|
||||
if (HasErrors) return null;
|
||||
|
||||
|
||||
//Automated processint
|
||||
//## ------------------ DEFAULT NOTIFICATIONS TO CUSTOMER ----------------
|
||||
//RavenTrialApproved (which sends pending manual generation message) and RavenTrialRejected messages are sent in this block
|
||||
Sockeye.Api.Controllers.NotifyController.NotifyDirectSMTP notifyDirectSMTP = null;
|
||||
if (dbObject.Status == TrialRequestStatus.AwaitingApproval && putObject.Status == TrialRequestStatus.Approved)
|
||||
{
|
||||
//APPROVED, generate and save key to be approved for release by us
|
||||
putObject.Processed = DateTime.UtcNow;
|
||||
License l = new License();
|
||||
l.Active = false;//not released to customer until we set to active and save
|
||||
l.DbId = putObject.DbId;
|
||||
l.PGroup = putObject.PGroup;
|
||||
l.TrialMode = true;
|
||||
l.RegTo = putObject.CompanyName;
|
||||
//perpet and sub both same number of users, covers seeded data values
|
||||
l.Users = RavenKeyFactory.TRIAL_KEY_USERS;
|
||||
|
||||
if (putObject.PGroup == ProductGroup.RavenPerpetual)
|
||||
{
|
||||
l.LicenseExpire = l.MaintenanceExpire = DateTime.UtcNow.AddDays(RavenKeyFactory.TRIAL_KEY_PERPETUAL_PERIOD_DAYS);
|
||||
}
|
||||
if (putObject.PGroup == ProductGroup.RavenSubscription)
|
||||
{
|
||||
l.LicenseExpire = l.MaintenanceExpire = DateTime.UtcNow.AddDays(RavenKeyFactory.TRIAL_KEY_SUBSCRIPTION_PERIOD_DAYS);
|
||||
l.CustomerUsers = RavenKeyFactory.TRIAL_KEY_SUBSCRIPTION_CUSTOMER_USERS;
|
||||
l.MaxDataGB = RavenKeyFactory.TRIAL_KEY_SUBSCRIPTION_MAX_DATA_GB;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (dbObject.Status == TrialRequestStatus.AwaitingApproval && putObject.Status == TrialRequestStatus.Rejected)
|
||||
{
|
||||
//REJECTED, send email
|
||||
putObject.Processed = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ct.Replace(dbObject, putObject);
|
||||
try
|
||||
{
|
||||
await ct.SaveChangesAsync();
|
||||
|
||||
//EMAIL?
|
||||
if (notifyDirectSMTP != null)
|
||||
{
|
||||
//send an email
|
||||
}
|
||||
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
@@ -204,20 +291,12 @@ namespace Sockeye.Biz
|
||||
|
||||
private async Task ValidateAsync(TrialLicenseRequest proposedObj, TrialLicenseRequest currentObj)
|
||||
{
|
||||
bool isNew = currentObj == null;
|
||||
await Task.CompletedTask;
|
||||
// bool isNew = currentObj == null;
|
||||
|
||||
|
||||
//no need to validate required fields, they are set to required in the model with an attribute
|
||||
|
||||
//Any form customizations to validate?
|
||||
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == SockType.TrialLicenseRequest.ToString());
|
||||
if (FormCustomization != null)
|
||||
{
|
||||
//Yeppers, do the validation, there are two, the custom fields and the regular fields that might be set to required
|
||||
|
||||
//validate users choices for required non custom fields
|
||||
RequiredFieldsValidator.Validate(this, FormCustomization, proposedObj);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -449,103 +528,101 @@ namespace Sockeye.Biz
|
||||
|
||||
|
||||
|
||||
//## ------------------ 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
|
||||
// todo: maybe this should be a direct smtp message, not bother with the notification system at all as that's how it was done in rockfish and it's kind of orthogonal
|
||||
|
||||
// if ( == !string.IsNullOrWhiteSpace(o.Email))//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
|
||||
// // //# 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))
|
||||
// {
|
||||
// // //# 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
|
||||
// // 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 ---------------
|
||||
// //-----------------------
|
||||
// } //------------------ /default notifications ---------------
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -165,6 +165,30 @@ namespace Sockeye.Util
|
||||
return Encoding.ASCII.GetString(bytes); // returns: "Hello world" for "48656C6C6F20776F726C64"
|
||||
}
|
||||
|
||||
|
||||
//Generate a random code for email validation and v7 license key fetching
|
||||
//doesn't have to be perfect, it's only temporary and
|
||||
//requires knowledge of the customer / trial user
|
||||
//email address to use it so it's kind of 2 factor
|
||||
public static string GenFetchCode()
|
||||
{
|
||||
|
||||
//sufficient for this purpose
|
||||
//https://stackoverflow.com/a/1344258/8939
|
||||
|
||||
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
var stringChars = new char[10];
|
||||
var random = new Random();
|
||||
|
||||
for (int i = 0; i < stringChars.Length; i++)
|
||||
{
|
||||
stringChars[i] = chars[random.Next(chars.Length)];
|
||||
}
|
||||
|
||||
var finalString = new String(stringChars);
|
||||
return finalString;
|
||||
}
|
||||
|
||||
}//eoc
|
||||
|
||||
}//eons
|
||||
5
todo.txt
5
todo.txt
@@ -1,5 +1,8 @@
|
||||
TODO:
|
||||
|
||||
DOCS
|
||||
Once it's up and running update docs to mention that perpetual trial period is two weeks subscription is one week
|
||||
|
||||
|
||||
- Purchase event must trigger notification event subscribable (might already due to created etc)
|
||||
- figure out and implement default notifications for Customers where appropriate
|
||||
@@ -30,7 +33,7 @@ TODO:
|
||||
|
||||
- TODO: subscription server approved
|
||||
Need message template and automatic proxy notification to customer
|
||||
|
||||
|
||||
|
||||
- v7 license fetch route
|
||||
- v8 license fetch route
|
||||
|
||||
Reference in New Issue
Block a user