From 7b9a505e5230b6ea9a951088a709ee184c2ac90a Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Thu, 9 Nov 2023 20:02:11 +0000 Subject: [PATCH] case 4556 --- .vscode/launch.json | 2 +- docs/8.0/ayanova/docs/changelog.md | 4 + docs/8.0/ayanova/mkdocs.yml | 2 +- server/AyaNova/biz/CustomerNoteBiz.cs | 114 +++++++++++++++++++++++++- 4 files changed, 119 insertions(+), 3 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 178286d8..a080a8d6 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -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" }, diff --git a/docs/8.0/ayanova/docs/changelog.md b/docs/8.0/ayanova/docs/changelog.md index ccfa52d1..7524b6a5 100644 --- a/docs/8.0/ayanova/docs/changelog.md +++ b/docs/8.0/ayanova/docs/changelog.md @@ -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 diff --git a/docs/8.0/ayanova/mkdocs.yml b/docs/8.0/ayanova/mkdocs.yml index c70593b8..8bf6ae5a 100644 --- a/docs/8.0/ayanova/mkdocs.yml +++ b/docs/8.0/ayanova/mkdocs.yml @@ -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 diff --git a/server/AyaNova/biz/CustomerNoteBiz.cs b/server/AyaNova/biz/CustomerNoteBiz.cs index 995a2d8c..8a56970d 100644 --- a/server/AyaNova/biz/CustomerNoteBiz.cs +++ b/server/AyaNova/biz/CustomerNoteBiz.cs @@ -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 idList = new List(); + long FailedObjectCount = 0; + JObject jobData = JObject.Parse(job.JobInfo); + if (jobData.ContainsKey("idList")) + idList = ((JArray)jobData["idList"]).ToObject>(); + 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...