diff --git a/server/AyaNova/Controllers/AttachmentController.cs b/server/AyaNova/Controllers/AttachmentController.cs index c6757f16..79d2dff6 100644 --- a/server/AyaNova/Controllers/AttachmentController.cs +++ b/server/AyaNova/Controllers/AttachmentController.cs @@ -78,15 +78,15 @@ namespace AyaNova.Api.Controllers if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); - var dbObj = await ct.FileAttachment.SingleOrDefaultAsync(z => z.Id == id); - if (dbObj == null) + var dbObject = await ct.FileAttachment.SingleOrDefaultAsync(z => z.Id == id); + if (dbObject == null) { return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); } long UserId = UserIdFromContext.Id(HttpContext.Items); - if (!Authorized.HasModifyRole(HttpContext.Items, dbObj.AttachToObjectType)) + if (!Authorized.HasModifyRole(HttpContext.Items, dbObject.AttachToObjectType)) { return StatusCode(403, new ApiNotAuthorizedResponse()); } @@ -95,27 +95,27 @@ namespace AyaNova.Api.Controllers try { string ChangeTextra = string.Empty; - if (dbObj.DisplayFileName != inObj.DisplayFileName) + if (dbObject.DisplayFileName != inObj.DisplayFileName) { - ChangeTextra = $"\"{dbObj.DisplayFileName}\" => \"{inObj.DisplayFileName}\""; + ChangeTextra = $"\"{dbObject.DisplayFileName}\" => \"{inObj.DisplayFileName}\""; } - if (dbObj.Notes != inObj.Notes) + if (dbObject.Notes != inObj.Notes) { if (!string.IsNullOrWhiteSpace(ChangeTextra)) ChangeTextra += ", "; ChangeTextra += "Notes"; } - dbObj.DisplayFileName = inObj.DisplayFileName; - dbObj.Notes = inObj.Notes; + dbObject.DisplayFileName = inObj.DisplayFileName; + dbObject.Notes = inObj.Notes; //Set "original" value of concurrency token to input token //this will allow EF to check it out - ct.Entry(dbObj).OriginalValues["Concurrency"] = inObj.Concurrency; + ct.Entry(dbObject).OriginalValues["Concurrency"] = inObj.Concurrency; //Log event and save context - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentModified, ChangeTextra), ct); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.AttachToObjectId, dbObject.AttachToObjectType, AyaEvent.AttachmentModified, ChangeTextra), ct); @@ -133,7 +133,7 @@ namespace AyaNova.Api.Controllers } //Normallyh wouldn't return a whole list but in this case the UI demands it because of reactivity issues - var ret = await GetFileListForObjectAsync(dbObj.AttachToObjectType, dbObj.AttachToObjectId); + var ret = await GetFileListForObjectAsync(dbObject.AttachToObjectType, dbObject.AttachToObjectId); return Ok(ApiOkResponse.Response(ret)); } @@ -367,28 +367,28 @@ namespace AyaNova.Api.Controllers return BadRequest(new ApiErrorResponse(ModelState)); } - var dbObj = await ct.FileAttachment.SingleOrDefaultAsync(z => z.Id == id); - if (dbObj == null) + var dbObject = await ct.FileAttachment.SingleOrDefaultAsync(z => z.Id == id); + if (dbObject == null) { return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); } long UserId = UserIdFromContext.Id(HttpContext.Items); - if (!Authorized.HasDeleteRole(HttpContext.Items, dbObj.AttachToObjectType)) + if (!Authorized.HasDeleteRole(HttpContext.Items, dbObject.AttachToObjectType)) { return StatusCode(403, new ApiNotAuthorizedResponse()); } //do the delete //this handles removing the file if there are no refs left and also the db record for the attachment - await FileUtil.DeleteFileAttachmentAsync(dbObj, ct); + await FileUtil.DeleteFileAttachmentAsync(dbObject, ct); //Event log process delete - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDelete, dbObj.DisplayFileName), ct); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.AttachToObjectId, dbObject.AttachToObjectType, AyaEvent.AttachmentDelete, dbObject.DisplayFileName), ct); //Delete search index - await Search.ProcessDeletedObjectKeywordsAsync(dbObj.Id, AyaType.FileAttachment); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.FileAttachment, ct); return NoContent(); } @@ -448,8 +448,8 @@ namespace AyaNova.Api.Controllers } //Ok, user has a valid download key and it's not expired yet so get the attachment record - var dbObj = await ct.FileAttachment.SingleOrDefaultAsync(z => z.Id == id); - if (dbObj == null) + var dbObject = await ct.FileAttachment.SingleOrDefaultAsync(z => z.Id == id); + if (dbObject == null) { await Task.Delay(nFailedAuthDelay);//fishing protection return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); @@ -457,15 +457,15 @@ namespace AyaNova.Api.Controllers //is this allowed? - if (!Authorized.HasReadFullRole(DownloadUser.Roles, dbObj.AttachToObjectType)) + if (!Authorized.HasReadFullRole(DownloadUser.Roles, dbObject.AttachToObjectType)) { await Task.Delay(nFailedAuthDelay);//DOS protection return StatusCode(403, new ApiNotAuthorizedResponse()); } //they are allowed, let's send the file - string mimetype = dbObj.ContentType; - var filePath = FileUtil.GetPermanentAttachmentFilePath(dbObj.StoredFileName); + string mimetype = dbObject.ContentType; + var filePath = FileUtil.GetPermanentAttachmentFilePath(dbObject.StoredFileName); if (!System.IO.File.Exists(filePath)) { //TODO: notify OPSNOTIFY @@ -473,16 +473,16 @@ namespace AyaNova.Api.Controllers //and a red light on the dashboard //TODO: this should reset the validity - var errText = $"Physical file {dbObj.StoredFileName} not found despite attachment record, this file is missing"; + var errText = $"Physical file {dbObject.StoredFileName} not found despite attachment record, this file is missing"; log.LogError(errText); return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND, null, errText)); } //Log - await EventLogProcessor.LogEventToDatabaseAsync(new Event(DownloadUser.Id, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDownload, dbObj.DisplayFileName), ct); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(DownloadUser.Id, dbObject.AttachToObjectId, dbObject.AttachToObjectType, AyaEvent.AttachmentDownload, dbObject.DisplayFileName), ct); - return PhysicalFile(filePath, mimetype, dbObj.DisplayFileName); + return PhysicalFile(filePath, mimetype, dbObject.DisplayFileName); } @@ -491,11 +491,11 @@ namespace AyaNova.Api.Controllers async private Task GetFileListForObjectAsync(AyaType ayaType, long ayaId) { - var l = await ct.FileAttachment.AsNoTracking().Where(z => z.AttachToObjectId == ayaId && z.AttachToObjectType == ayaType) - .Select(z => new { z.Id, z.Concurrency, z.ContentType, z.DisplayFileName, z.LastModified, z.Notes }) - .ToArrayAsync(); - var v = l.OrderBy(z => z.DisplayFileName); - return v; + return await ct.FileAttachment.AsNoTracking().Where(z => z.AttachToObjectId == ayaId && z.AttachToObjectType == ayaType).OrderBy(z => z.DisplayFileName) + .Select(z => new { z.Id, z.Concurrency, z.ContentType, z.DisplayFileName, z.LastModified, z.Notes }) + .ToArrayAsync(); + // var v = l.OrderBy(z => z.DisplayFileName); + // return v; } diff --git a/server/AyaNova/Controllers/TranslationController.cs b/server/AyaNova/Controllers/TranslationController.cs index 05daaad0..e8a6d9eb 100644 --- a/server/AyaNova/Controllers/TranslationController.cs +++ b/server/AyaNova/Controllers/TranslationController.cs @@ -226,8 +226,8 @@ namespace AyaNova.Api.Controllers //Fetch translation and it's children //(fetch here so can return proper REST responses on failing basic validity) - var dbObj = await ct.Translation.Include(z => z.TranslationItems).SingleOrDefaultAsync(z => z.Id == id); - if (dbObj == null) + var dbObject = await ct.Translation.Include(z => z.TranslationItems).SingleOrDefaultAsync(z => z.Id == id); + if (dbObject == null) { return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); } @@ -240,7 +240,7 @@ namespace AyaNova.Api.Controllers //Instantiate the business object handler TranslationBiz biz = TranslationBiz.GetBiz(ct, HttpContext); - if (!await biz.DeleteAsync(dbObj)) + if (!await biz.DeleteAsync(dbObject)) { return BadRequest(new ApiErrorResponse(biz.Errors)); } diff --git a/server/AyaNova/Controllers/UserController.cs b/server/AyaNova/Controllers/UserController.cs index 8aa9033c..5dc66d17 100644 --- a/server/AyaNova/Controllers/UserController.cs +++ b/server/AyaNova/Controllers/UserController.cs @@ -260,8 +260,8 @@ namespace AyaNova.Api.Controllers //Instantiate the business object handler UserBiz biz = UserBiz.GetBiz(ct, HttpContext); - var dbObj = await ct.User.SingleOrDefaultAsync(z => z.Id == id); - if (dbObj == null) + var dbObject = await ct.User.SingleOrDefaultAsync(z => z.Id == id); + if (dbObject == null) { return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); } @@ -272,7 +272,7 @@ namespace AyaNova.Api.Controllers } - if (!await biz.DeleteAsync(dbObj)) + if (!await biz.DeleteAsync(dbObject)) { return BadRequest(new ApiErrorResponse(biz.Errors)); } diff --git a/server/AyaNova/biz/ContractBiz.cs b/server/AyaNova/biz/ContractBiz.cs index 8672523a..dfeba315 100644 --- a/server/AyaNova/biz/ContractBiz.cs +++ b/server/AyaNova/biz/ContractBiz.cs @@ -151,10 +151,11 @@ namespace AyaNova.Biz ct.Contract.Remove(dbObject); await ct.SaveChangesAsync(); - //Log event + await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType,ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); //all good do the commit await transaction.CommitAsync(); } diff --git a/server/AyaNova/biz/CustomerBiz.cs b/server/AyaNova/biz/CustomerBiz.cs index 88a2b715..1f92cbda 100644 --- a/server/AyaNova/biz/CustomerBiz.cs +++ b/server/AyaNova/biz/CustomerBiz.cs @@ -153,8 +153,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType,ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); //all good do the commit await transaction.CommitAsync(); } diff --git a/server/AyaNova/biz/DataListViewBiz.cs b/server/AyaNova/biz/DataListViewBiz.cs index d7f8bec2..0c970bda 100644 --- a/server/AyaNova/biz/DataListViewBiz.cs +++ b/server/AyaNova/biz/DataListViewBiz.cs @@ -80,18 +80,18 @@ namespace AyaNova.Biz //DUPLICATE // - internal async Task DuplicateAsync(DataListView dbObj) + internal async Task DuplicateAsync(DataListView dbObject) { DataListView outObj = new DataListView(); - CopyObject.Copy(dbObj, outObj); + CopyObject.Copy(dbObject, outObj); //generate unique name string newUniqueName = string.Empty; bool NotUnique = true; long l = 1; do { - newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObj.Name, l++, 255); + newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObject.Name, l++, 255); NotUnique = await ct.DataListView.AnyAsync(z => z.Name == newUniqueName); } while (NotUnique); outObj.Name = newUniqueName; @@ -157,25 +157,25 @@ namespace AyaNova.Biz // //put - internal async Task PutAsync(DataListView dbObj, DataListView inObj) + internal async Task PutAsync(DataListView dbObject, DataListView inObj) { //preserve the owner ID if none was specified if (inObj.UserId == 0) - inObj.UserId = dbObj.UserId; + inObj.UserId = dbObject.UserId; //Replace the db object with the PUT object - CopyObject.Copy(inObj, dbObj, "Id"); + CopyObject.Copy(inObj, dbObject, "Id"); //Set "original" value of concurrency token to input token //this will allow EF to check it out - ct.Entry(dbObj).OriginalValues["Concurrency"] = inObj.Concurrency; + ct.Entry(dbObject).OriginalValues["Concurrency"] = inObj.Concurrency; - await ValidateAsync(dbObj, false); + await ValidateAsync(dbObject, false); if (HasErrors) return false; await ct.SaveChangesAsync(); //Log modification and save context - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct); @@ -186,27 +186,27 @@ namespace AyaNova.Biz //////////////////////////////////////////////////////////////////////////////////////////////// //DELETE // - internal async Task DeleteAsync(DataListView dbObj) + internal async Task DeleteAsync(DataListView dbObject) { //Determine if the object can be deleted, do the deletion tentatively //Probably also in here deal with tags and associated search text etc //FUTURE POSSIBLE NEED - //ValidateCanDelete(dbObj); + //ValidateCanDelete(dbObject); if (HasErrors) return false; - ct.DataListView.Remove(dbObj); + ct.DataListView.Remove(dbObject); await ct.SaveChangesAsync(); //Delete sibling objects //Event log process delete - await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.Name, ct); + await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); //Delete search index - //Search.ProcessDeletedObjectKeywords(dbObj.Id, BizType); + //Search.ProcessDeletedObjectKeywords(dbObject.Id, BizType); return true; diff --git a/server/AyaNova/biz/FormCustomBiz.cs b/server/AyaNova/biz/FormCustomBiz.cs index fd8d635c..f0ce7ccd 100644 --- a/server/AyaNova/biz/FormCustomBiz.cs +++ b/server/AyaNova/biz/FormCustomBiz.cs @@ -115,24 +115,24 @@ namespace AyaNova.Biz // //put - internal async Task PutAsync(FormCustom dbObj, FormCustom inObj) + internal async Task PutAsync(FormCustom dbObject, FormCustom inObj) { //Replace the db object with the PUT object - CopyObject.Copy(inObj, dbObj, "Id"); + CopyObject.Copy(inObj, dbObject, "Id"); //Set "original" value of concurrency token to input token //this will allow EF to check it out - ct.Entry(dbObj).OriginalValues["Concurrency"] = inObj.Concurrency; + ct.Entry(dbObject).OriginalValues["Concurrency"] = inObj.Concurrency; - await ValidateAsync(dbObj, false); + await ValidateAsync(dbObject, false); if (HasErrors) return false; - dbObj.Template = JsonUtil.CompactJson(dbObj.Template); + dbObject.Template = JsonUtil.CompactJson(dbObject.Template); await ct.SaveChangesAsync(); //Log modification and save context - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct); return true; diff --git a/server/AyaNova/biz/HeadOfficeBiz.cs b/server/AyaNova/biz/HeadOfficeBiz.cs index 12d9feb1..3dc11293 100644 --- a/server/AyaNova/biz/HeadOfficeBiz.cs +++ b/server/AyaNova/biz/HeadOfficeBiz.cs @@ -153,8 +153,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); //all good do the commit await transaction.CommitAsync(); } diff --git a/server/AyaNova/biz/LoanUnitBiz.cs b/server/AyaNova/biz/LoanUnitBiz.cs index 8a62bcca..60c0a2ba 100644 --- a/server/AyaNova/biz/LoanUnitBiz.cs +++ b/server/AyaNova/biz/LoanUnitBiz.cs @@ -153,8 +153,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); //all good do the commit await transaction.CommitAsync(); } diff --git a/server/AyaNova/biz/PMBiz.cs b/server/AyaNova/biz/PMBiz.cs index a8a11320..1a0ef63c 100644 --- a/server/AyaNova/biz/PMBiz.cs +++ b/server/AyaNova/biz/PMBiz.cs @@ -106,11 +106,11 @@ namespace AyaNova.Biz //DUPLICATE // - internal async Task DuplicateAsync(PM dbObj) + internal async Task DuplicateAsync(PM dbObject) { await Task.CompletedTask; throw new System.NotImplementedException("STUB: WORKORDER DUPLICATE"); // PM outObj = new PM(); - // CopyObject.Copy(dbObj, outObj, "Wiki"); + // CopyObject.Copy(dbObject, outObj, "Wiki"); // // outObj.Name = Util.StringUtil.NameUniquify(outObj.Name, 255); // //generate unique name // string newUniqueName = string.Empty; @@ -118,7 +118,7 @@ namespace AyaNova.Biz // long l = 1; // do // { - // newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObj.Name, l++, 255); + // newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObject.Name, l++, 255); // NotUnique = await ct.PM.AnyAsync(z => z.Name == newUniqueName); // } while (NotUnique); @@ -144,38 +144,38 @@ namespace AyaNova.Biz // //put - internal async Task PutAsync(PM dbObj, PM putObj) + internal async Task PutAsync(PM dbObject, PM putObj) { // make a snapshot of the original for validation but update the original to preserve workflow PM SnapshotOfOriginalDBObj = new PM(); - CopyObject.Copy(dbObj, SnapshotOfOriginalDBObj); + CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj); //Replace the db object with the PUT object - CopyObject.Copy(putObj, dbObj, "Id,Serial"); + CopyObject.Copy(putObj, dbObject, "Id,Serial"); //if user has rights then change it, otherwise just ignore it and do the rest if (SnapshotOfOriginalDBObj.Serial != putObj.Serial && Authorized.HasAnyRole(CurrentUserRoles, RolesAllowedToChangeSerial)) { - dbObj.Serial = putObj.Serial; + dbObject.Serial = putObj.Serial; } - dbObj.Tags = TagBiz.NormalizeTags(dbObj.Tags); - dbObj.CustomFields = JsonUtil.CompactJson(dbObj.CustomFields); + dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags); + dbObject.CustomFields = JsonUtil.CompactJson(dbObject.CustomFields); //Set "original" value of concurrency token to input token //this will allow EF to check it out - ct.Entry(dbObj).OriginalValues["Concurrency"] = putObj.Concurrency; + ct.Entry(dbObject).OriginalValues["Concurrency"] = putObj.Concurrency; - await ValidateAsync(dbObj, SnapshotOfOriginalDBObj); + await ValidateAsync(dbObject, SnapshotOfOriginalDBObj); if (HasErrors) return false; //Log event and save context - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); - await SearchIndexAsync(dbObj, false); - await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct); + await SearchIndexAsync(dbObject, false); + await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); return true; } @@ -206,22 +206,22 @@ namespace AyaNova.Biz //////////////////////////////////////////////////////////////////////////////////////////////// //DELETE // - internal async Task DeleteAsync(PM dbObj) + internal async Task DeleteAsync(PM dbObject) { await Task.CompletedTask; throw new System.NotImplementedException("STUB: WORKORDER DELETE"); //Determine if the object can be deleted, do the deletion tentatively //Probably also in here deal with tags and associated search text etc - //NOT REQUIRED NOW BUT IF IN FUTURE ValidateCanDelete(dbObj); + //NOT REQUIRED NOW BUT IF IN FUTURE ValidateCanDelete(dbObject); // if (HasErrors) // return false; - // ct.PM.Remove(dbObj); + // ct.PM.Remove(dbObject); // await ct.SaveChangesAsync(); // //Log event - // await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.Serial.ToString(), ct); - // await Search.ProcessDeletedObjectKeywordsAsync(dbObj.Id, BizType); - // await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObj.Tags); + // await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Serial.ToString(), ct); + // await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + // await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); // return true; } diff --git a/server/AyaNova/biz/PMTemplateBiz.cs b/server/AyaNova/biz/PMTemplateBiz.cs index 39687b82..b1786b72 100644 --- a/server/AyaNova/biz/PMTemplateBiz.cs +++ b/server/AyaNova/biz/PMTemplateBiz.cs @@ -153,8 +153,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); //all good do the commit await transaction.CommitAsync(); } diff --git a/server/AyaNova/biz/PartBiz.cs b/server/AyaNova/biz/PartBiz.cs index c4326ba1..9dbd4e08 100644 --- a/server/AyaNova/biz/PartBiz.cs +++ b/server/AyaNova/biz/PartBiz.cs @@ -153,8 +153,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); //all good do the commit await transaction.CommitAsync(); } diff --git a/server/AyaNova/biz/ProjectBiz.cs b/server/AyaNova/biz/ProjectBiz.cs index 845005f2..da19e0fe 100644 --- a/server/AyaNova/biz/ProjectBiz.cs +++ b/server/AyaNova/biz/ProjectBiz.cs @@ -153,8 +153,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); //all good do the commit await transaction.CommitAsync(); } diff --git a/server/AyaNova/biz/PurchaseOrderBiz.cs b/server/AyaNova/biz/PurchaseOrderBiz.cs index 0d3c22fe..f9af5897 100644 --- a/server/AyaNova/biz/PurchaseOrderBiz.cs +++ b/server/AyaNova/biz/PurchaseOrderBiz.cs @@ -153,8 +153,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); //all good do the commit await transaction.CommitAsync(); } diff --git a/server/AyaNova/biz/QuoteBiz.cs b/server/AyaNova/biz/QuoteBiz.cs index 03221a02..498e5059 100644 --- a/server/AyaNova/biz/QuoteBiz.cs +++ b/server/AyaNova/biz/QuoteBiz.cs @@ -105,12 +105,12 @@ namespace AyaNova.Biz //DUPLICATE // - internal async Task DuplicateAsync(Quote dbObj) + internal async Task DuplicateAsync(Quote dbObject) { await Task.CompletedTask; throw new System.NotImplementedException("STUB: WORKORDER DUPLICATE"); // Quote outObj = new Quote(); - // CopyObject.Copy(dbObj, outObj, "Wiki"); + // CopyObject.Copy(dbObject, outObj, "Wiki"); // // outObj.Name = Util.StringUtil.NameUniquify(outObj.Name, 255); // //generate unique name // string newUniqueName = string.Empty; @@ -118,7 +118,7 @@ namespace AyaNova.Biz // long l = 1; // do // { - // newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObj.Name, l++, 255); + // newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObject.Name, l++, 255); // NotUnique = await ct.Quote.AnyAsync(z => z.Name == newUniqueName); // } while (NotUnique); @@ -144,38 +144,38 @@ namespace AyaNova.Biz // //put - internal async Task PutAsync(Quote dbObj, Quote putObj) + internal async Task PutAsync(Quote dbObject, Quote putObj) { // make a snapshot of the original for validation but update the original to preserve workflow Quote SnapshotOfOriginalDBObj = new Quote(); - CopyObject.Copy(dbObj, SnapshotOfOriginalDBObj); + CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj); //Replace the db object with the PUT object - CopyObject.Copy(putObj, dbObj, "Id,Serial"); + CopyObject.Copy(putObj, dbObject, "Id,Serial"); //if user has rights then change it, otherwise just ignore it and do the rest if (SnapshotOfOriginalDBObj.Serial != putObj.Serial && Authorized.HasAnyRole(CurrentUserRoles, RolesAllowedToChangeSerial)) { - dbObj.Serial = putObj.Serial; + dbObject.Serial = putObj.Serial; } - dbObj.Tags = TagBiz.NormalizeTags(dbObj.Tags); - dbObj.CustomFields = JsonUtil.CompactJson(dbObj.CustomFields); + dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags); + dbObject.CustomFields = JsonUtil.CompactJson(dbObject.CustomFields); //Set "original" value of concurrency token to input token //this will allow EF to check it out - ct.Entry(dbObj).OriginalValues["Concurrency"] = putObj.Concurrency; + ct.Entry(dbObject).OriginalValues["Concurrency"] = putObj.Concurrency; - await ValidateAsync(dbObj, SnapshotOfOriginalDBObj); + await ValidateAsync(dbObject, SnapshotOfOriginalDBObj); if (HasErrors) return false; //Log event and save context - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); - await SearchIndexAsync(dbObj, false); - await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct); + await SearchIndexAsync(dbObject, false); + await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); return true; } @@ -206,23 +206,23 @@ namespace AyaNova.Biz //////////////////////////////////////////////////////////////////////////////////////////////// //DELETE // - internal async Task DeleteAsync(Quote dbObj) + internal async Task DeleteAsync(Quote dbObject) { await Task.CompletedTask; throw new System.NotImplementedException("STUB: WORKORDER DELETE"); //Determine if the object can be deleted, do the deletion tentatively //Probably also in here deal with tags and associated search text etc - //NOT REQUIRED NOW BUT IF IN FUTURE ValidateCanDelete(dbObj); + //NOT REQUIRED NOW BUT IF IN FUTURE ValidateCanDelete(dbObject); // if (HasErrors) // return false; - // ct.Quote.Remove(dbObj); + // ct.Quote.Remove(dbObject); // await ct.SaveChangesAsync(); // //Log event - // await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.Serial.ToString(), ct); - // await Search.ProcessDeletedObjectKeywordsAsync(dbObj.Id, BizType); - // await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObj.Tags); + // await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Serial.ToString(), ct); + // await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + // await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); // return true; } diff --git a/server/AyaNova/biz/QuoteTemplateBiz.cs b/server/AyaNova/biz/QuoteTemplateBiz.cs index 60e579c6..df7d1daa 100644 --- a/server/AyaNova/biz/QuoteTemplateBiz.cs +++ b/server/AyaNova/biz/QuoteTemplateBiz.cs @@ -91,11 +91,11 @@ namespace AyaNova.Biz //DUPLICATE // - internal async Task DuplicateAsync(QuoteTemplate dbObj) + internal async Task DuplicateAsync(QuoteTemplate dbObject) { QuoteTemplate outObj = new QuoteTemplate(); - CopyObject.Copy(dbObj, outObj, "Wiki"); + CopyObject.Copy(dbObject, outObj, "Wiki"); // outObj.Name = Util.StringUtil.NameUniquify(outObj.Name, 255); //generate unique name string newUniqueName = string.Empty; @@ -103,7 +103,7 @@ namespace AyaNova.Biz long l = 1; do { - newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObj.Name, l++, 255); + newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObject.Name, l++, 255); NotUnique = await ct.QuoteTemplate.AnyAsync(z => z.Name == newUniqueName); } while (NotUnique); @@ -129,36 +129,36 @@ namespace AyaNova.Biz // //put - internal async Task PutAsync(QuoteTemplate dbObj, QuoteTemplate inObj) + internal async Task PutAsync(QuoteTemplate dbObject, QuoteTemplate inObj) { //make a snapshot of the original for validation but update the original to preserve workflow QuoteTemplate SnapshotOfOriginalDBObj = new QuoteTemplate(); - CopyObject.Copy(dbObj, SnapshotOfOriginalDBObj); + CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj); //Replace the db object with the PUT object - CopyObject.Copy(inObj, dbObj, "Id"); + CopyObject.Copy(inObj, dbObject, "Id"); - dbObj.Tags = TagBiz.NormalizeTags(dbObj.Tags); - dbObj.CustomFields = JsonUtil.CompactJson(dbObj.CustomFields); + dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags); + dbObject.CustomFields = JsonUtil.CompactJson(dbObject.CustomFields); //Set "original" value of concurrency token to input token //this will allow EF to check it out - ct.Entry(dbObj).OriginalValues["Concurrency"] = inObj.Concurrency; + ct.Entry(dbObject).OriginalValues["Concurrency"] = inObj.Concurrency; - await ValidateAsync(dbObj, SnapshotOfOriginalDBObj); + await ValidateAsync(dbObject, SnapshotOfOriginalDBObj); if (HasErrors) return false; //Log event and save context - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); - await SearchIndexAsync(dbObj, false); - await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct); + await SearchIndexAsync(dbObject, false); + await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); return true; } - + private async Task SearchIndexAsync(QuoteTemplate obj, bool isNew) { //SEARCH INDEXING @@ -183,21 +183,22 @@ namespace AyaNova.Biz //////////////////////////////////////////////////////////////////////////////////////////////// //DELETE // - internal async Task DeleteAsync(QuoteTemplate dbObj) + internal async Task DeleteAsync(QuoteTemplate dbObject) { //Determine if the object can be deleted, do the deletion tentatively //Probably also in here deal with tags and associated search text etc - //NOT REQUIRED NOW BUT IF IN FUTURE ValidateCanDelete(dbObj); + //NOT REQUIRED NOW BUT IF IN FUTURE ValidateCanDelete(dbObject); if (HasErrors) return false; - ct.QuoteTemplate.Remove(dbObj); + ct.QuoteTemplate.Remove(dbObject); await ct.SaveChangesAsync(); //Log event - await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObj.Id, BizType); - await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObj.Tags); + await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); + await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); return true; } diff --git a/server/AyaNova/biz/Search.cs b/server/AyaNova/biz/Search.cs index e9eed238..64476bf4 100644 --- a/server/AyaNova/biz/Search.cs +++ b/server/AyaNova/biz/Search.cs @@ -650,12 +650,11 @@ namespace AyaNova.Biz await ProcessKeywordsAsync(searchIndexObjectParameters, false); } - public static async Task ProcessDeletedObjectKeywordsAsync(long objectID, AyaType objectType) + public static async Task ProcessDeletedObjectKeywordsAsync(long objectID, AyaType objectType, AyContext ct) { //Be careful in future, if you put ToString at the end of each object in the string interpolation //npgsql driver will assume it's a string and put quotes around it triggering an error that a string can't be compared to an int - using (AyContext ct = ServiceProviderProvider.DBContext) - await ct.Database.ExecuteSqlInterpolatedAsync($"delete from asearchkey where objectid={objectID} and objecttype={(int)objectType}"); + await ct.Database.ExecuteSqlInterpolatedAsync($"delete from asearchkey where objectid={objectID} and objecttype={(int)objectType}"); //nothing to save here, it's a direct command already executed } diff --git a/server/AyaNova/biz/TranslationBiz.cs b/server/AyaNova/biz/TranslationBiz.cs index b7b43928..c463efce 100644 --- a/server/AyaNova/biz/TranslationBiz.cs +++ b/server/AyaNova/biz/TranslationBiz.cs @@ -315,16 +315,16 @@ namespace AyaNova.Biz //DELETE // - internal async Task DeleteAsync(Translation dbObj) + internal async Task DeleteAsync(Translation dbObject) { //Determine if the object can be deleted, do the deletion tentatively - await ValidateCanDeleteAsync(dbObj); + await ValidateCanDeleteAsync(dbObject); if (HasErrors) return false; - ct.Translation.Remove(dbObj); + ct.Translation.Remove(dbObject); await ct.SaveChangesAsync(); //Log - await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.Translation, dbObj.Id, dbObj.Name, ct); + await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.Translation, dbObject.Id, dbObject.Name, ct); return true; } diff --git a/server/AyaNova/biz/UnitBiz.cs b/server/AyaNova/biz/UnitBiz.cs index 012e428e..2c1bb242 100644 --- a/server/AyaNova/biz/UnitBiz.cs +++ b/server/AyaNova/biz/UnitBiz.cs @@ -153,8 +153,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); //all good do the commit await transaction.CommitAsync(); } diff --git a/server/AyaNova/biz/UnitModelBiz.cs b/server/AyaNova/biz/UnitModelBiz.cs index 6b8968c5..aae71e42 100644 --- a/server/AyaNova/biz/UnitModelBiz.cs +++ b/server/AyaNova/biz/UnitModelBiz.cs @@ -153,8 +153,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); //all good do the commit await transaction.CommitAsync(); } diff --git a/server/AyaNova/biz/UserBiz.cs b/server/AyaNova/biz/UserBiz.cs index 4d6cc89d..75c41b81 100644 --- a/server/AyaNova/biz/UserBiz.cs +++ b/server/AyaNova/biz/UserBiz.cs @@ -86,8 +86,8 @@ namespace AyaNova.Biz { using (AyContext ct = ServiceProviderProvider.DBContext) { - User dbObj = ct.User.FirstOrDefault(z => z.Id == 1); - dbObj.Password = Hasher.hash(dbObj.Salt, ServerBootConfig.AYANOVA_SET_SUPERUSER_PW); + User dbObject = ct.User.FirstOrDefault(z => z.Id == 1); + dbObject.Password = Hasher.hash(dbObject.Salt, ServerBootConfig.AYANOVA_SET_SUPERUSER_PW); ct.SaveChanges(); //TODO: notify OPSNOTIFY } @@ -304,12 +304,12 @@ namespace AyaNova.Biz // internal async Task ChangePasswordAsync(long userId, string newPassword) { - User dbObj = await ct.User.FirstOrDefaultAsync(z => z.Id == userId); - dbObj.Password = Hasher.hash(dbObj.Salt, newPassword); + User dbObject = await ct.User.FirstOrDefaultAsync(z => z.Id == userId); + dbObject.Password = Hasher.hash(dbObject.Salt, newPassword); await ct.SaveChangesAsync(); //Log modification and save context - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct); return true; } @@ -340,28 +340,39 @@ namespace AyaNova.Biz //////////////////////////////////////////////////////////////////////////////////////////////// //DELETE // - internal async Task DeleteAsync(User dbObj) + internal async Task DeleteAsync(User dbObject) { - await ValidateCanDelete(dbObj); + await ValidateCanDelete(dbObject); if (HasErrors) return false; - //Remove the object - ct.User.Remove(dbObj); - await ct.SaveChangesAsync(); + using (var transaction = await ct.Database.BeginTransactionAsync()) + { + try + { + //Remove the object + ct.User.Remove(dbObject); + await ct.SaveChangesAsync(); - //Delete sibling objects - //USEROPTIONS - await ct.Database.ExecuteSqlInterpolatedAsync($"delete from auseroptions where userid = {dbObj.Id}"); - //personal datalistview - await ct.Database.ExecuteSqlInterpolatedAsync($"delete from adatalistview where public = {false} and userid = {dbObj.Id}"); + //Delete sibling objects + //USEROPTIONS + await ct.Database.ExecuteSqlInterpolatedAsync($"delete from auseroptions where userid = {dbObject.Id}"); + //personal datalistview + await ct.Database.ExecuteSqlInterpolatedAsync($"delete from adatalistview where public = {false} and userid = {dbObject.Id}"); - await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.Name, ct); - - await Search.ProcessDeletedObjectKeywordsAsync(dbObj.Id, BizType); - await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObj.Tags); - - return true; + await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); + await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + await transaction.CommitAsync(); + } + catch + { + //Just re-throw for now, let exception handler deal, but in future may want to deal with this more here + throw; + } + return true; + } } diff --git a/server/AyaNova/biz/UserOptionsBiz.cs b/server/AyaNova/biz/UserOptionsBiz.cs index 8f7958ce..f0448fb7 100644 --- a/server/AyaNova/biz/UserOptionsBiz.cs +++ b/server/AyaNova/biz/UserOptionsBiz.cs @@ -43,23 +43,23 @@ namespace AyaNova.Biz // //put - internal async Task PutAsync(UserOptions dbObj, UserOptions inObj) + internal async Task PutAsync(UserOptions dbObject, UserOptions inObj) { //Replace the db object with the PUT object - CopyObject.Copy(inObj, dbObj, "Id, UserId"); + CopyObject.Copy(inObj, dbObject, "Id, UserId"); //Set "original" value of concurrency token to input token //this will allow EF to check it out - ct.Entry(dbObj).OriginalValues["Concurrency"] = inObj.Concurrency; + ct.Entry(dbObject).OriginalValues["Concurrency"] = inObj.Concurrency; - Validate(dbObj); + Validate(dbObject); if (HasErrors) return false; await ct.SaveChangesAsync(); //Log - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, AyaType.User, AyaEvent.Modified), ct); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, AyaType.User, AyaEvent.Modified), ct); return true; } diff --git a/server/AyaNova/biz/VendorBiz.cs b/server/AyaNova/biz/VendorBiz.cs index 18d8d21f..e57d13db 100644 --- a/server/AyaNova/biz/VendorBiz.cs +++ b/server/AyaNova/biz/VendorBiz.cs @@ -153,8 +153,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); //all good do the commit await transaction.CommitAsync(); } diff --git a/server/AyaNova/biz/WidgetBiz.cs b/server/AyaNova/biz/WidgetBiz.cs index 01d88c16..5812124e 100644 --- a/server/AyaNova/biz/WidgetBiz.cs +++ b/server/AyaNova/biz/WidgetBiz.cs @@ -158,8 +158,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); //all good do the commit await transaction.CommitAsync(); } diff --git a/server/AyaNova/biz/WorkOrderBiz.cs b/server/AyaNova/biz/WorkOrderBiz.cs index 54bd63d2..c93590e9 100644 --- a/server/AyaNova/biz/WorkOrderBiz.cs +++ b/server/AyaNova/biz/WorkOrderBiz.cs @@ -212,8 +212,9 @@ namespace AyaNova.Biz await ct.SaveChangesAsync(); await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Serial.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); #if (DEBUG) @@ -553,8 +554,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItem, dbObject.Id, "wo:" + dbObject.WorkOrderId.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItem); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItem, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); //all good do the commit if it's ours if (parentTransaction == null) @@ -756,8 +758,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemExpense, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemExpense); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemExpense, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); return true; } @@ -945,8 +948,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemLabor, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemLabor); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemLabor, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); return true; } @@ -1133,8 +1137,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemLoan, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemLoan); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemLoan, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); return true; } @@ -1322,8 +1327,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemPart, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemPart); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemPart, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); return true; } @@ -1508,8 +1514,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemPartRequest, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemPartRequest); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemPartRequest, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); return true; } @@ -1697,8 +1704,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemScheduledUser, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemScheduledUser); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemScheduledUser, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); return true; } @@ -1886,8 +1894,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemTask, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemTask); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemTask, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); return true; } @@ -2075,8 +2084,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemTravel, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemTravel); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemTravel, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); return true; } @@ -2264,8 +2274,9 @@ namespace AyaNova.Biz //Log event await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemUnit, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemUnit); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemUnit, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); return true; } diff --git a/server/AyaNova/biz/WorkorderTemplateBiz.cs b/server/AyaNova/biz/WorkorderTemplateBiz.cs index d016903c..6b53c803 100644 --- a/server/AyaNova/biz/WorkorderTemplateBiz.cs +++ b/server/AyaNova/biz/WorkorderTemplateBiz.cs @@ -91,11 +91,11 @@ namespace AyaNova.Biz //DUPLICATE // - internal async Task DuplicateAsync(WorkOrderTemplate dbObj) + internal async Task DuplicateAsync(WorkOrderTemplate dbObject) { WorkOrderTemplate outObj = new WorkOrderTemplate(); - CopyObject.Copy(dbObj, outObj, "Wiki"); + CopyObject.Copy(dbObject, outObj, "Wiki"); // outObj.Name = Util.StringUtil.NameUniquify(outObj.Name, 255); //generate unique name string newUniqueName = string.Empty; @@ -103,7 +103,7 @@ namespace AyaNova.Biz long l = 1; do { - newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObj.Name, l++, 255); + newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObject.Name, l++, 255); NotUnique = await ct.WorkOrderTemplate.AnyAsync(z => z.Name == newUniqueName); } while (NotUnique); @@ -129,32 +129,32 @@ namespace AyaNova.Biz // //put - internal async Task PutAsync(WorkOrderTemplate dbObj, WorkOrderTemplate inObj) + internal async Task PutAsync(WorkOrderTemplate dbObject, WorkOrderTemplate inObj) { //make a snapshot of the original for validation but update the original to preserve workflow WorkOrderTemplate SnapshotOfOriginalDBObj = new WorkOrderTemplate(); - CopyObject.Copy(dbObj, SnapshotOfOriginalDBObj); + CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj); //Replace the db object with the PUT object - CopyObject.Copy(inObj, dbObj, "Id"); + CopyObject.Copy(inObj, dbObject, "Id"); - dbObj.Tags = TagBiz.NormalizeTags(dbObj.Tags); - dbObj.CustomFields = JsonUtil.CompactJson(dbObj.CustomFields); + dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags); + dbObject.CustomFields = JsonUtil.CompactJson(dbObject.CustomFields); //Set "original" value of concurrency token to input token //this will allow EF to check it out - ct.Entry(dbObj).OriginalValues["Concurrency"] = inObj.Concurrency; + ct.Entry(dbObject).OriginalValues["Concurrency"] = inObj.Concurrency; - await ValidateAsync(dbObj, SnapshotOfOriginalDBObj); + await ValidateAsync(dbObject, SnapshotOfOriginalDBObj); if (HasErrors) return false; //Log event and save context - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); - await SearchIndexAsync(dbObj, false); - await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct); + await SearchIndexAsync(dbObject, false); + await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); return true; } @@ -184,21 +184,22 @@ namespace AyaNova.Biz //////////////////////////////////////////////////////////////////////////////////////////////// //DELETE // - internal async Task DeleteAsync(WorkOrderTemplate dbObj) + internal async Task DeleteAsync(WorkOrderTemplate dbObject) { //Determine if the object can be deleted, do the deletion tentatively //Probably also in here deal with tags and associated search text etc - //NOT REQUIRED NOW BUT IF IN FUTURE ValidateCanDelete(dbObj); + //NOT REQUIRED NOW BUT IF IN FUTURE ValidateCanDelete(dbObject); if (HasErrors) return false; - ct.WorkOrderTemplate.Remove(dbObj); + ct.WorkOrderTemplate.Remove(dbObject); await ct.SaveChangesAsync(); //Log event - await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.Name, ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObj.Id, BizType); - await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObj.Tags); + await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); + await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); return true; } diff --git a/server/AyaNova/util/FileUtil.cs b/server/AyaNova/util/FileUtil.cs index 239cb292..d7f98c56 100644 --- a/server/AyaNova/util/FileUtil.cs +++ b/server/AyaNova/util/FileUtil.cs @@ -416,6 +416,19 @@ namespace AyaNova.Util } + ////////////////////////////////////////////////////////// + // + // Delete all attachments for object + // + internal static async Task DeleteAttachmentsForObjectAsync(AyaType ayaType, long ayaId, AyContext ct) + { + var deleteList = await ct.FileAttachment.Where(z => z.AttachToObjectId == ayaId && z.AttachToObjectType == ayaType).ToListAsync(); + foreach (var d in deleteList) + { + await DeleteFileAttachmentAsync(d, ct); + } + } + /// /// Delete a file attachment /// checks ref count and if would be zero deletes file physically @@ -540,12 +553,12 @@ namespace AyaNova.Util //got to be at least 32 chars if (FileName.Length < 32) return false; //probably all 64 chars but let's not count on that and go with folder is correct - + //what *should* the path be for a file of this name? - var ExpectedFullPath=GetPermanentAttachmentFilePath(FileName); + var ExpectedFullPath = GetPermanentAttachmentFilePath(FileName); //if expected equals real then it's very likely an orphaned file - return fullPathName==ExpectedFullPath; - + return fullPathName == ExpectedFullPath; + }