diff --git a/devdocs/todo.txt b/devdocs/todo.txt index 869546b2..49814925 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -32,6 +32,7 @@ IMMEDIATE ITEMS: - Tag groups (modify tags already coded) - X Modify tag to bring combined list of groups with tag picklist (NOPE, let the UI query both separately and integrate them at the UI level) - Modify tag to remove itself from tagroupmap if deleted + - Tag: add test for untag everything - Retag: code to tag an item should take into account if it's already tagged and not make a new record, just return existing - Localized text - ** DEVISE a system to ensure no unused keys are brought forward to raven diff --git a/server/AyaNova/Controllers/TagController.cs b/server/AyaNova/Controllers/TagController.cs index 555cfe92..90a3e165 100644 --- a/server/AyaNova/Controllers/TagController.cs +++ b/server/AyaNova/Controllers/TagController.cs @@ -316,6 +316,56 @@ namespace AyaNova.Api.Controllers } + /// + /// Untag all objects with this tag + /// Required roles: BizAdminFull, DispatchFull, InventoryFull, TechFull, AccountingFull + /// + /// + /// Ok + [HttpDelete("{id}")] + public async Task UnTagEverything([FromRoute] long id) + { + + if (!serverState.IsOpen) + { + return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); + } + + if (!ModelState.IsValid) + { + return BadRequest(new ApiErrorResponse(ModelState)); + } + + var dbObj = await ct.Tag.SingleOrDefaultAsync(m => m.Id == id); + if (dbObj == null) + { + return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); + } + + if (!Authorized.IsAuthorizedToModify(HttpContext.Items, AyaType.Tag, dbObj.OwnerId)) + { + return StatusCode(401, new ApiNotAuthorizedResponse()); + } + + var UserId = UserIdFromContext.Id(HttpContext.Items); + + //Instantiate the business object handler + TagBiz biz = new TagBiz(ct, UserId, UserRolesFromContext.Roles(HttpContext.Items)); + + //NOTE: ct.SaveChanges not required after this call + //Delete will look after it as it also needs to delete related records manully that are not mapped in EF Core + if (!biz.Delete(dbObj)) + { + return BadRequest(new ApiErrorResponse(biz.Errors)); + } + + //Log + EventLogProcessor.AddEntry(new Event(UserId, id, AyaType.Tag, AyaEvent.TagMassUntag), ct); + await ct.SaveChangesAsync(); + + return NoContent(); + } + /// /// Delete Tag diff --git a/server/AyaNova/biz/AyaEvent.cs b/server/AyaNova/biz/AyaEvent.cs index 05ce08d6..8275fff1 100644 --- a/server/AyaNova/biz/AyaEvent.cs +++ b/server/AyaNova/biz/AyaEvent.cs @@ -21,7 +21,8 @@ namespace AyaNova.Biz LicenseFetch=7, LicenseTrialRequest=8, ServerStateChange=9, - SeedDatabase=10 + SeedDatabase=10, + TagMassUntag=11 //NEW ITEMS REQUIRE LOCALE KEYS AND UPDATE EventLogProcessor code that prefetches required keys diff --git a/server/AyaNova/biz/TagBiz.cs b/server/AyaNova/biz/TagBiz.cs index b1286dd4..471990be 100644 --- a/server/AyaNova/biz/TagBiz.cs +++ b/server/AyaNova/biz/TagBiz.cs @@ -200,6 +200,19 @@ namespace AyaNova.Biz } + + //////////////////////////////////////////////////////////////////////////////////////////////// + // UNTAG - Untag this tag from everywhere it's used + // + internal bool Untag(Tag dbObj) + { + //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 + ct.Database.ExecuteSqlCommand($"delete from atagmap where tagid = {dbObj.Id}"); + ct.Database.ExecuteSqlCommand($"delete from ataggroupmap where tagid = {dbObj.Id}"); + return true; + } + //////////////////////////////////////////////////////////////////////////////////////////////// //VALIDATION // diff --git a/server/AyaNova/biz/TagGroupBiz.cs b/server/AyaNova/biz/TagGroupBiz.cs index 9e5f7f33..c9dc19a1 100644 --- a/server/AyaNova/biz/TagGroupBiz.cs +++ b/server/AyaNova/biz/TagGroupBiz.cs @@ -32,7 +32,7 @@ namespace AyaNova.Biz } - + //////////////////////////////////////////////////////////////////////////////////////////////// //CREATE @@ -195,7 +195,8 @@ namespace AyaNova.Biz ValidateCanDelete(dbObj); if (HasErrors) return false; - ct.TagGroup.Remove(dbObj); + ct.Database.ExecuteSqlCommand($"delete from ataggroupmap where taggroupid = {dbObj.Id}"); + ct.Database.ExecuteSqlCommand($"delete from ataggroup where id = {dbObj.Id}"); return true; } @@ -231,10 +232,10 @@ namespace AyaNova.Biz //whatever needs to be check to delete this object //See if any TagGroupmaps exist with this TagGroup in which case it's not deleteable - if (ct.TagGroupMap.Any(e => e.TagGroupId == inObj.Id)) - { - AddError(ValidationErrorType.ReferentialIntegrity, "object", "Can't be deleted while has relations"); - } + // if (ct.TagGroupMap.Any(e => e.TagGroupId == inObj.Id)) + // { + // AddError(ValidationErrorType.ReferentialIntegrity, "TagGroup", "Can't be deleted while has tags mapped"); + // } }