case 4556

This commit is contained in:
2023-11-09 20:02:11 +00:00
parent e86bb56a06
commit 7b9a505e52
4 changed files with 119 additions and 3 deletions

2
.vscode/launch.json vendored
View File

@@ -65,7 +65,7 @@
"AYANOVA_USE_URLS": "http://*:7575;",
//"AYANOVA_PERMANENTLY_ERASE_DATABASE":"true",
//"AYANOVA_REMOVE_LICENSE_FROM_DB":"true",
//"AYANOVA_REPORT_RENDERING_TIMEOUT":"1",
"AYANOVA_REPORT_RENDERING_TIMEOUT":"1",
//"AYANOVA_REPORT_RENDER_API_URL_OVERRIDE": "http://localhost:7575",
"AYANOVA_BACKUP_PG_DUMP_PATH": "C:\\data\\code\\postgres_15\\bin"
},

View File

@@ -12,6 +12,10 @@ See the [upgrade instructions](ops-upgrade.md) section of this manual for detail
Released 2023-XX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
**Fixed**
- Server: Customer notes Tag extension: fixed "Job failed" error when using tag extension for customer notes
**Changed**
- App, Server: Reporting - the ayT translation key helper function now shows an error directly in the rendered report in place of an incorrect or uncached translation key rather than the report failing entirely with an error message

View File

@@ -7,7 +7,7 @@ theme:
site_name: AyaNova manual
site_dir: "../../../server/AyaNova/wwwroot/docs"
strict: true
copyright: Copyright © 2023 Ground Zero Tech-Works Inc. REV-2023-11-02
copyright: Copyright © 2023 Ground Zero Tech-Works Inc. REV-2023-11-09
extra:
generator: false
# Extensions

View File

@@ -11,7 +11,7 @@ using Microsoft.Extensions.Logging;
namespace AyaNova.Biz
{
internal class CustomerNoteBiz : BizObject, ISearchAbleObject, IReportAbleObject, IExportAbleObject, INotifiableObject
internal class CustomerNoteBiz : BizObject, IJobObject, ISearchAbleObject, IReportAbleObject, IExportAbleObject, INotifiableObject
{
internal CustomerNoteBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles)
{
@@ -290,6 +290,118 @@ namespace AyaNova.Biz
//JOB / OPERATIONS
//
////////////////////////////////////////////////////////////////////////////////////////////////
//JOB / OPERATIONS
//
public async Task HandleJobAsync(OpsJob job)
{
//Hand off the particular job to the corresponding processing code
//NOTE: If this code throws an exception the caller (JobsBiz::ProcessJobsAsync) will automatically set the job to failed and log the exeption so
//basically any error condition during job processing should throw up an exception if it can't be handled
switch (job.JobType)
{
case JobType.BatchCoreObjectOperation:
await ProcessBatchJobAsync(job);
break;
default:
throw new System.ArgumentOutOfRangeException($"CustomerBiz.HandleJob-> Invalid job type{job.JobType.ToString()}");
}
}
private async Task ProcessBatchJobAsync(OpsJob job)
{
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Running);
await JobsBiz.LogJobAsync(job.GId, $"LT:StartJob {job.SubType}");
List<long> idList = new List<long>();
long FailedObjectCount = 0;
JObject jobData = JObject.Parse(job.JobInfo);
if (jobData.ContainsKey("idList"))
idList = ((JArray)jobData["idList"]).ToObject<List<long>>();
else
idList = await ct.Customer.AsNoTracking().Select(z => z.Id).ToListAsync();
bool SaveIt = false;
//---------------------------------
//case 4192
TimeSpan ProgressAndCancelCheckSpan = new TimeSpan(0, 0, ServerBootConfig.JOB_PROGRESS_UPDATE_AND_CANCEL_CHECK_SECONDS);
DateTime LastProgressCheck = DateTime.UtcNow.Subtract(new TimeSpan(1, 1, 1, 1, 1));
var TotalRecords = idList.LongCount();
long CurrentRecord = -1;
//---------------------------------
foreach (long id in idList)
{
try
{
//--------------------------------
//case 4192
//Update progress / cancel requested?
CurrentRecord++;
if (DateUtil.IsAfterDuration(LastProgressCheck, ProgressAndCancelCheckSpan))
{
await JobsBiz.UpdateJobProgressAsync(job.GId, $"{CurrentRecord}/{TotalRecords}");
if (await JobsBiz.GetJobStatusAsync(job.GId) == JobStatus.CancelRequested)
break;
LastProgressCheck = DateTime.UtcNow;
}
//---------------------------------
SaveIt = false;
ClearErrors();
CustomerNote o = null;
switch (job.SubType)
{
case JobSubType.TagAddAny:
case JobSubType.TagAdd:
case JobSubType.TagRemoveAny:
case JobSubType.TagRemove:
case JobSubType.TagReplaceAny:
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);
break;
case JobSubType.Delete:
if (!await DeleteAsync(id))
{
await JobsBiz.LogJobAsync(job.GId, $"LT:Errors {GetErrorsAsString()} id {id}");
FailedObjectCount++;
}
break;
default:
throw new System.ArgumentOutOfRangeException($"ProcessBatchJobAsync -> Invalid job Subtype{job.SubType}");
}
if (SaveIt)
{
o = await PutAsync(o);
if (o == null)
{
await JobsBiz.LogJobAsync(job.GId, $"LT:Errors {GetErrorsAsString()} id {id}");
FailedObjectCount++;
}
}
//delay so we're not tying up all the resources in a tight loop
await Task.Delay(AyaNova.Util.ServerBootConfig.JOB_OBJECT_HANDLE_BATCH_JOB_LOOP_DELAY);
}
catch (Exception ex)
{
await JobsBiz.LogJobAsync(job.GId, $"LT:Errors id({id})");
await JobsBiz.LogJobAsync(job.GId, ExceptionUtil.ExtractAllExceptionMessages(ex));
}
}
//---------------------------------
//case 4192
await JobsBiz.UpdateJobProgressAsync(job.GId, $"{++CurrentRecord}/{TotalRecords}");
//---------------------------------
await JobsBiz.LogJobAsync(job.GId, $"LT:BatchJob {job.SubType} {idList.Count}{(FailedObjectCount > 0 ? " - LT:Failed " + FailedObjectCount : "")}");
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Completed);
}
//Other job handlers here...