diff --git a/server/AyaNova/Controllers/TagController.cs b/server/AyaNova/Controllers/TagController.cs index 81cf20f2..127206c1 100644 --- a/server/AyaNova/Controllers/TagController.cs +++ b/server/AyaNova/Controllers/TagController.cs @@ -70,6 +70,8 @@ namespace AyaNova.Api.Controllers } + + ///////////////////////////////////////////////////////////// //BULK OPS // @@ -274,7 +276,7 @@ namespace AyaNova.Api.Controllers JObject o = JObject.FromObject(new { idList = idList, - fromTag = fromTag, + tag = fromTag, toTag = toTag }); @@ -320,7 +322,7 @@ namespace AyaNova.Api.Controllers var JobName = $"Bulk operation: Replace tag \"{fromTag}\" with tag \"{toTag}\" on any {ayaType}"; JObject o = JObject.FromObject(new { - fromTag = fromTag, + tag = fromTag, toTag = toTag }); diff --git a/server/AyaNova/biz/BizObject.cs b/server/AyaNova/biz/BizObject.cs index 1dbe1d55..d4d350d4 100644 --- a/server/AyaNova/biz/BizObject.cs +++ b/server/AyaNova/biz/BizObject.cs @@ -25,7 +25,7 @@ namespace AyaNova.Biz internal AyaType BizType { get; set; } internal AyaNova.Models.AyContext ct { get; set; } internal long UserId { get; set; } - internal long UserTranslationId { get; set; } + internal long UserTranslationId { get; set; } internal AuthorizationRoles CurrentUserRoles { get; set; } #endregion @@ -41,6 +41,7 @@ namespace AyaNova.Biz public bool HasErrors => _errors.Any(); + public void ClearErrors() => _errors.Clear(); public void AddvalidationError(ValidationError validationError) { @@ -73,7 +74,7 @@ namespace AyaNova.Biz if (string.IsNullOrWhiteSpace(msg)) { //msg = e.ErrorType.ToString(); - msg=ApiErrorCodeStockMessage.GetMessage(e.Code); + msg = ApiErrorCodeStockMessage.GetMessage(e.Code); } sb.AppendLine($"Target: {e.Target} error: {msg}"); } diff --git a/server/AyaNova/biz/JobType.cs b/server/AyaNova/biz/JobType.cs index 31ffeaa9..670b3a37 100644 --- a/server/AyaNova/biz/JobType.cs +++ b/server/AyaNova/biz/JobType.cs @@ -23,10 +23,10 @@ namespace AyaNova.Biz NotSet = 0, TagAdd = 1, TagAddAny = 2, - TagRemove = 4, - TagRemoveAny = 5, - TagReplace = 6, - TagReplaceAny = 7 + TagRemove = 3, + TagRemoveAny = 4, + TagReplace = 5, + TagReplaceAny = 6 } diff --git a/server/AyaNova/biz/WidgetBiz.cs b/server/AyaNova/biz/WidgetBiz.cs index 29f08a73..9d4b2ed3 100644 --- a/server/AyaNova/biz/WidgetBiz.cs +++ b/server/AyaNova/biz/WidgetBiz.cs @@ -1,5 +1,7 @@ +using System; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; +using System.Linq; using EnumsNET; using AyaNova.Util; using AyaNova.Api.ControllerHelpers; @@ -326,30 +328,95 @@ namespace AyaNova.Biz //Simulate a long running job here await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Running, ct); - await JobsBiz.LogJobAsync(job.GId, $"Widget BulkJob {job.SubType} started...", ct); + await JobsBiz.LogJobAsync(job.GId, $"Bulk job {job.SubType} started...", ct); List idList = new List(); - + long ProcessedObjectCount = 0; JObject jobData = JObject.Parse(job.JobInfo); + + //cache some info from the jobInfo if present + //TAGS? + string ToTag = null; + string Tag = null; + if (jobData.ContainsKey("tag")) + Tag = (string)jobData["tag"]; + + if (jobData.ContainsKey("toTag")) + ToTag = (string)jobData["toTag"]; + if (jobData.ContainsKey("idList")) { idList = jobData["idList"].Value>(); } - else{ + else + { //we need to fetch a list of them all because ALL items was selected + //If they wanted to filter (say by Active=true) they can do that from a grid list mass op + idList = await ct.Widget.Select(m => m.Id).ToListAsync(); } var seedLevel = (Seeder.SeedLevel)jobData["seedLevel"].Value(); var timeZoneOffset = jobData["timeZoneOffset"].Value(); - //either process an id list or fetch all objects and process - - //call out processor for each item in turn - switch (job.SubType) + bool SaveIt = false; + //Iterate the list fetching each in turn and sending to the processor to handle + foreach (long id in idList) { - case JobSubType.TagAdd: - } + try + { + SaveIt = false; + //errors would pile up here if not cleared on each iteration + ClearErrors(); - await JobsBiz.LogJobAsync(job.GId, $"Widget BulkJob {job.SubType} completed", ct); + //Fetch + var o = await GetAsync(id, false); + //call out processor for each item in turn + switch (job.SubType) + { + case JobSubType.TagAddAny: + case JobSubType.TagAdd: + if (!o.Tags.Contains(Tag)) + { + o.Tags.Add(Tag); + SaveIt = true; + } + break; + case JobSubType.TagRemoveAny: + case JobSubType.TagRemove: + SaveIt = o.Tags.Remove(Tag); + break; + case JobSubType.TagReplaceAny: + case JobSubType.TagReplace: + int index = o.Tags.IndexOf(Tag); + if (index != -1) + { + o.Tags[index] = ToTag; + SaveIt = true; + } + break; + default: + throw new System.ArgumentOutOfRangeException($"ProcessBulkJob -> Invalid job Subtype{job.SubType}"); + } + + if (SaveIt) + { + o = await PutAsync(o); + if (o == null) + await JobsBiz.LogJobAsync(job.GId, $"Error processing item {id}: {GetErrorsAsString()}", ct); + else + ProcessedObjectCount++; + }else{ + + ProcessedObjectCount++; + } + + } + catch (Exception ex) + { + await JobsBiz.LogJobAsync(job.GId, $"Error processing item {id}", ct); + await JobsBiz.LogJobAsync(job.GId, ExceptionUtil.ExtractAllExceptionMessages(ex), ct); + } + } + await JobsBiz.LogJobAsync(job.GId, $"Bulk job {job.SubType} processed {ProcessedObjectCount} of {idList.Count}", ct); await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Completed, ct); }