case 4173
This commit is contained in:
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -119,7 +119,7 @@
|
|||||||
"AYANOVA_DB_CONNECTION": "Server=localhost;Username=postgres;Password=raven;Database=AyaNova;CommandTimeout=300;",
|
"AYANOVA_DB_CONNECTION": "Server=localhost;Username=postgres;Password=raven;Database=AyaNova;CommandTimeout=300;",
|
||||||
"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_REMOVE_LICENSE_FROM_DB":"true",
|
//"AYANOVA_REMOVE_LICENSE_FROM_DB":"true",
|
||||||
//"AYANOVA_SET_SUPERUSER_PW": "abraxis",
|
//"AYANOVA_SET_SUPERUSER_PW": "abraxis",
|
||||||
"AYANOVA_BACKUP_PG_DUMP_PATH": "C:\\data\\code\\postgres_14\\bin"
|
"AYANOVA_BACKUP_PG_DUMP_PATH": "C:\\data\\code\\postgres_14\\bin"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
The Send email extension can be used to send an email to the selected objects email address.
|
The Send email extension can be used to send an email to the selected (Active) object's email address.
|
||||||
|
|
||||||
## Authorization Roles required
|
## Authorization Roles required
|
||||||
|
|
||||||
@@ -18,6 +18,6 @@ The Send email extension is accessed from the [extensions](ay-extensions.md) men
|
|||||||
|
|
||||||
## How the Send email extension works
|
## How the Send email extension works
|
||||||
|
|
||||||
Compose a message and start the job. AyaNova will attempt to send the message to the email address set for all selected objects with a small delay between each to avoid overloading your email server. Objects without an email address will be ignored.
|
Compose a message and start the job. AyaNova will attempt to send the message to the email address set for all selected objects with a small delay between each to avoid overloading your email server. Objects that are not set to Active or objects without an email address will be ignored.
|
||||||
|
|
||||||
**WARNING**: This extension allows you to mass email multiple objects at a time. AyaNova will automatically add a small delay between sending each message to prevent potentially overwhelming the email server, however, there may be limits on how many emails can be sent within a given time period so be sure to check with your email service provider to avoid potentially violating anti-spam policies.
|
**WARNING**: This extension allows you to mass email multiple objects at a time. AyaNova will automatically add a small delay between sending each message to prevent potentially overwhelming the email server, however, there may be limits on how many emails can be sent within a given time period so be sure to check with your email service provider to avoid potentially violating anti-spam policies.
|
||||||
|
|||||||
@@ -281,6 +281,18 @@ namespace AyaNova.Api.Controllers
|
|||||||
if (batchDirectSMTPParams.SelectedRequest == null)
|
if (batchDirectSMTPParams.SelectedRequest == null)
|
||||||
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "batchDirectSMTPParams.DataListSelectedRequest is required"));
|
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "batchDirectSMTPParams.DataListSelectedRequest is required"));
|
||||||
|
|
||||||
|
switch (batchDirectSMTPParams.SelectedRequest.AType)
|
||||||
|
{
|
||||||
|
case AyaType.Customer:
|
||||||
|
case AyaType.HeadOffice:
|
||||||
|
case AyaType.Vendor:
|
||||||
|
case AyaType.User:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, "AType", "Specified Type not supported"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!Authorized.HasModifyRole(HttpContext.Items, batchDirectSMTPParams.SelectedRequest.AType))
|
if (!Authorized.HasModifyRole(HttpContext.Items, batchDirectSMTPParams.SelectedRequest.AType))
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
return StatusCode(403, new ApiNotAuthorizedResponse());
|
||||||
@@ -295,10 +307,12 @@ namespace AyaNova.Api.Controllers
|
|||||||
UserIdFromContext.Id(HttpContext.Items),
|
UserIdFromContext.Id(HttpContext.Items),
|
||||||
UserTranslationIdFromContext.Id(HttpContext.Items));
|
UserTranslationIdFromContext.Id(HttpContext.Items));
|
||||||
|
|
||||||
var JobName = $"LT:BatchDirectSMTP - LT:{batchDirectSMTPParams.SelectedRequest.AType} ({batchDirectSMTPParams.SelectedRequest.SelectedRowIds.LongLength}) LT:User {UserNameFromContext.Name(HttpContext.Items)}";
|
var JobName = $"LT:BatchDirectSMTP - LT:{batchDirectSMTPParams.SelectedRequest.AType} ({batchDirectSMTPParams.SelectedRequest.SelectedRowIds.LongLength}), LT:User {UserNameFromContext.Name(HttpContext.Items)}, LT:MemoSubject '{batchDirectSMTPParams.Subject}'";
|
||||||
JObject o = JObject.FromObject(new
|
JObject o = JObject.FromObject(new
|
||||||
{
|
{
|
||||||
idList = batchDirectSMTPParams.SelectedRequest.SelectedRowIds
|
idList = batchDirectSMTPParams.SelectedRequest.SelectedRowIds,
|
||||||
|
subject = batchDirectSMTPParams.Subject,
|
||||||
|
message = batchDirectSMTPParams.TextBody
|
||||||
});
|
});
|
||||||
|
|
||||||
OpsJob j = new OpsJob();
|
OpsJob j = new OpsJob();
|
||||||
|
|||||||
@@ -647,9 +647,6 @@ namespace AyaNova.Biz
|
|||||||
SaveIt = false;
|
SaveIt = false;
|
||||||
ClearErrors();
|
ClearErrors();
|
||||||
Customer o = null;
|
Customer o = null;
|
||||||
//save a fetch if it's a delete
|
|
||||||
if (job.SubType != JobSubType.Delete)
|
|
||||||
o = await GetAsync(id, false);
|
|
||||||
switch (job.SubType)
|
switch (job.SubType)
|
||||||
{
|
{
|
||||||
case JobSubType.TagAddAny:
|
case JobSubType.TagAddAny:
|
||||||
@@ -658,6 +655,7 @@ namespace AyaNova.Biz
|
|||||||
case JobSubType.TagRemove:
|
case JobSubType.TagRemove:
|
||||||
case JobSubType.TagReplaceAny:
|
case JobSubType.TagReplaceAny:
|
||||||
case JobSubType.TagReplace:
|
case JobSubType.TagReplace:
|
||||||
|
o = await GetAsync(id, false);
|
||||||
SaveIt = TagBiz.ProcessBatchTagOperation(o.Tags, (string)jobData["tag"], jobData.ContainsKey("toTag") ? (string)jobData["toTag"] : null, job.SubType);
|
SaveIt = TagBiz.ProcessBatchTagOperation(o.Tags, (string)jobData["tag"], jobData.ContainsKey("toTag") ? (string)jobData["toTag"] : null, job.SubType);
|
||||||
break;
|
break;
|
||||||
case JobSubType.Delete:
|
case JobSubType.Delete:
|
||||||
@@ -667,6 +665,23 @@ namespace AyaNova.Biz
|
|||||||
FailedObjectCount++;
|
FailedObjectCount++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case JobSubType.DirectSMTP:
|
||||||
|
o = await GetAsync(id, false);
|
||||||
|
if (o != null && o.Active && !string.IsNullOrWhiteSpace(o.EmailAddress))
|
||||||
|
{
|
||||||
|
IMailer m = AyaNova.Util.ServiceProviderProvider.Mailer;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await m.SendEmailAsync(o.EmailAddress, (string)jobData["subject"], (string)jobData["message"], ServerGlobalOpsSettingsCache.Notify, null, null, null);
|
||||||
|
await Task.Delay(AyaNova.Util.ServerBootConfig.JOB_OBJECT_EMAIL_LOOP_DELAY);//a small delay to not overwhelm the mail server
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
FailedObjectCount++;
|
||||||
|
await NotifyEventHelper.AddOpsProblemEvent("SMTP direct message failed", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new System.ArgumentOutOfRangeException($"ProcessBatchJobAsync -> Invalid job Subtype{job.SubType}");
|
throw new System.ArgumentOutOfRangeException($"ProcessBatchJobAsync -> Invalid job Subtype{job.SubType}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -525,9 +525,6 @@ namespace AyaNova.Biz
|
|||||||
SaveIt = false;
|
SaveIt = false;
|
||||||
ClearErrors();
|
ClearErrors();
|
||||||
HeadOffice o = null;
|
HeadOffice o = null;
|
||||||
//save a fetch if it's a delete
|
|
||||||
if (job.SubType != JobSubType.Delete)
|
|
||||||
o = await GetAsync(id, false);
|
|
||||||
switch (job.SubType)
|
switch (job.SubType)
|
||||||
{
|
{
|
||||||
case JobSubType.TagAddAny:
|
case JobSubType.TagAddAny:
|
||||||
@@ -536,6 +533,7 @@ namespace AyaNova.Biz
|
|||||||
case JobSubType.TagRemove:
|
case JobSubType.TagRemove:
|
||||||
case JobSubType.TagReplaceAny:
|
case JobSubType.TagReplaceAny:
|
||||||
case JobSubType.TagReplace:
|
case JobSubType.TagReplace:
|
||||||
|
o = await GetAsync(id, false);
|
||||||
SaveIt = TagBiz.ProcessBatchTagOperation(o.Tags, (string)jobData["tag"], jobData.ContainsKey("toTag") ? (string)jobData["toTag"] : null, job.SubType);
|
SaveIt = TagBiz.ProcessBatchTagOperation(o.Tags, (string)jobData["tag"], jobData.ContainsKey("toTag") ? (string)jobData["toTag"] : null, job.SubType);
|
||||||
break;
|
break;
|
||||||
case JobSubType.Delete:
|
case JobSubType.Delete:
|
||||||
@@ -545,6 +543,23 @@ namespace AyaNova.Biz
|
|||||||
FailedObjectCount++;
|
FailedObjectCount++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case JobSubType.DirectSMTP:
|
||||||
|
o = await GetAsync(id, false);
|
||||||
|
if (o != null && o.Active && !string.IsNullOrWhiteSpace(o.EmailAddress))
|
||||||
|
{
|
||||||
|
IMailer m = AyaNova.Util.ServiceProviderProvider.Mailer;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await m.SendEmailAsync(o.EmailAddress, (string)jobData["subject"], (string)jobData["message"], ServerGlobalOpsSettingsCache.Notify, null, null, null);
|
||||||
|
await Task.Delay(AyaNova.Util.ServerBootConfig.JOB_OBJECT_EMAIL_LOOP_DELAY);//a small delay to not overwhelm the mail server
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
FailedObjectCount++;
|
||||||
|
await NotifyEventHelper.AddOpsProblemEvent("SMTP direct message failed", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new System.ArgumentOutOfRangeException($"ProcessBatchJobAsync -> Invalid job Subtype{job.SubType}");
|
throw new System.ArgumentOutOfRangeException($"ProcessBatchJobAsync -> Invalid job Subtype{job.SubType}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1262,9 +1262,6 @@ namespace AyaNova.Biz
|
|||||||
//a little different than normal here because the built in getasync doesn't return
|
//a little different than normal here because the built in getasync doesn't return
|
||||||
//a full User object normally
|
//a full User object normally
|
||||||
User o = null;
|
User o = null;
|
||||||
//save a fetch if it's a delete
|
|
||||||
if (job.SubType != JobSubType.Delete)
|
|
||||||
o = await GetAsync(id, false);
|
|
||||||
switch (job.SubType)
|
switch (job.SubType)
|
||||||
{
|
{
|
||||||
case JobSubType.TagAddAny:
|
case JobSubType.TagAddAny:
|
||||||
@@ -1273,6 +1270,7 @@ namespace AyaNova.Biz
|
|||||||
case JobSubType.TagRemove:
|
case JobSubType.TagRemove:
|
||||||
case JobSubType.TagReplaceAny:
|
case JobSubType.TagReplaceAny:
|
||||||
case JobSubType.TagReplace:
|
case JobSubType.TagReplace:
|
||||||
|
o = await GetAsync(id, false);
|
||||||
SaveIt = TagBiz.ProcessBatchTagOperation(o.Tags, (string)jobData["tag"], jobData.ContainsKey("toTag") ? (string)jobData["toTag"] : null, job.SubType);
|
SaveIt = TagBiz.ProcessBatchTagOperation(o.Tags, (string)jobData["tag"], jobData.ContainsKey("toTag") ? (string)jobData["toTag"] : null, job.SubType);
|
||||||
break;
|
break;
|
||||||
case JobSubType.Delete:
|
case JobSubType.Delete:
|
||||||
@@ -1282,6 +1280,23 @@ namespace AyaNova.Biz
|
|||||||
FailedObjectCount++;
|
FailedObjectCount++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case JobSubType.DirectSMTP:
|
||||||
|
o = await ct.User.AsNoTracking().Include(o => o.UserOptions).FirstOrDefaultAsync(z => z.Id == id);
|
||||||
|
if (o != null && o.Active && !string.IsNullOrWhiteSpace(o.UserOptions.EmailAddress))
|
||||||
|
{
|
||||||
|
IMailer m = AyaNova.Util.ServiceProviderProvider.Mailer;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await m.SendEmailAsync(o.UserOptions.EmailAddress, (string)jobData["subject"], (string)jobData["message"], ServerGlobalOpsSettingsCache.Notify, null, null, null);
|
||||||
|
await Task.Delay(AyaNova.Util.ServerBootConfig.JOB_OBJECT_EMAIL_LOOP_DELAY);//a small delay to not overwhelm the mail server
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
FailedObjectCount++;
|
||||||
|
await NotifyEventHelper.AddOpsProblemEvent("SMTP direct message failed", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new System.ArgumentOutOfRangeException($"ProcessBatchJobAsync -> Invalid job Subtype{job.SubType}");
|
throw new System.ArgumentOutOfRangeException($"ProcessBatchJobAsync -> Invalid job Subtype{job.SubType}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -457,9 +457,6 @@ namespace AyaNova.Biz
|
|||||||
SaveIt = false;
|
SaveIt = false;
|
||||||
ClearErrors();
|
ClearErrors();
|
||||||
Vendor o = null;
|
Vendor o = null;
|
||||||
//save a fetch if it's a delete
|
|
||||||
if (job.SubType != JobSubType.Delete)
|
|
||||||
o = await GetAsync(id, false);
|
|
||||||
switch (job.SubType)
|
switch (job.SubType)
|
||||||
{
|
{
|
||||||
case JobSubType.TagAddAny:
|
case JobSubType.TagAddAny:
|
||||||
@@ -468,6 +465,7 @@ namespace AyaNova.Biz
|
|||||||
case JobSubType.TagRemove:
|
case JobSubType.TagRemove:
|
||||||
case JobSubType.TagReplaceAny:
|
case JobSubType.TagReplaceAny:
|
||||||
case JobSubType.TagReplace:
|
case JobSubType.TagReplace:
|
||||||
|
o = await GetAsync(id, false);
|
||||||
SaveIt = TagBiz.ProcessBatchTagOperation(o.Tags, (string)jobData["tag"], jobData.ContainsKey("toTag") ? (string)jobData["toTag"] : null, job.SubType);
|
SaveIt = TagBiz.ProcessBatchTagOperation(o.Tags, (string)jobData["tag"], jobData.ContainsKey("toTag") ? (string)jobData["toTag"] : null, job.SubType);
|
||||||
break;
|
break;
|
||||||
case JobSubType.Delete:
|
case JobSubType.Delete:
|
||||||
@@ -477,6 +475,23 @@ namespace AyaNova.Biz
|
|||||||
FailedObjectCount++;
|
FailedObjectCount++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case JobSubType.DirectSMTP:
|
||||||
|
o = await GetAsync(id, false);
|
||||||
|
if (o != null && o.Active && !string.IsNullOrWhiteSpace(o.EmailAddress))
|
||||||
|
{
|
||||||
|
IMailer m = AyaNova.Util.ServiceProviderProvider.Mailer;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await m.SendEmailAsync(o.EmailAddress, (string)jobData["subject"], (string)jobData["message"], ServerGlobalOpsSettingsCache.Notify, null, null, null);
|
||||||
|
await Task.Delay(AyaNova.Util.ServerBootConfig.JOB_OBJECT_EMAIL_LOOP_DELAY);//a small delay to not overwhelm the mail server
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
FailedObjectCount++;
|
||||||
|
await NotifyEventHelper.AddOpsProblemEvent("SMTP direct message failed", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new System.ArgumentOutOfRangeException($"ProcessBatchJobAsync -> Invalid job Subtype{job.SubType}");
|
throw new System.ArgumentOutOfRangeException($"ProcessBatchJobAsync -> Invalid job Subtype{job.SubType}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace AyaNova.Util
|
|||||||
internal const int FAILED_AUTH_DELAY = 3000;//ms
|
internal const int FAILED_AUTH_DELAY = 3000;//ms
|
||||||
internal const int JOB_OBJECT_HANDLE_BATCH_JOB_LOOP_DELAY = 200;//ms this delay is a temporary measure to ensure super big time consuming batch jobs don't use all server CPU resources
|
internal const int JOB_OBJECT_HANDLE_BATCH_JOB_LOOP_DELAY = 200;//ms this delay is a temporary measure to ensure super big time consuming batch jobs don't use all server CPU resources
|
||||||
internal const int JOB_PROGRESS_UPDATE_AND_CANCEL_CHECK_SECONDS = 5;//seconds between progress updates and checks for cancellation of long running jobs
|
internal const int JOB_PROGRESS_UPDATE_AND_CANCEL_CHECK_SECONDS = 5;//seconds between progress updates and checks for cancellation of long running jobs
|
||||||
|
internal const int JOB_OBJECT_EMAIL_LOOP_DELAY = 500;//ms this delay ensures multiple email sendings in a job don't overwhelm the mail server
|
||||||
|
|
||||||
//UPLOAD LIMITS 1048576 = 1MiB for testing 10737420000 10737418240 10,737,418,240
|
//UPLOAD LIMITS 1048576 = 1MiB for testing 10737420000 10737418240 10,737,418,240
|
||||||
internal const long MAX_ATTACHMENT_UPLOAD_BYTES = 10737420000;//slight bit of overage as 10737418241=10GiB
|
internal const long MAX_ATTACHMENT_UPLOAD_BYTES = 10737420000;//slight bit of overage as 10737418241=10GiB
|
||||||
|
|||||||
Reference in New Issue
Block a user