From b6d799e5c00982f9f321a7aec3fe3b53883e3740 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Thu, 6 Dec 2018 16:28:04 +0000 Subject: [PATCH] mass untag --- devdocs/todo.txt | 8 +- .../AyaNova/Controllers/AyaTypeController.cs | 16 +- .../Controllers/JobOperationsController.cs | 2 +- server/AyaNova/Controllers/TagController.cs | 305 ----------- .../AyaNova/Controllers/TagGroupController.cs | 337 ------------ .../Controllers/TagGroupMapController.cs | 197 ------- .../AyaNova/Controllers/TagMapController.cs | 264 ---------- server/AyaNova/biz/AyaEvent.cs | 3 +- server/AyaNova/biz/AyaType.cs | 12 +- .../AyaNova/biz/BizObjectExistsInDatabase.cs | 6 +- server/AyaNova/biz/BizObjectFactory.cs | 6 +- server/AyaNova/biz/BizObjectNameFetcher.cs | 5 +- .../AyaNova/biz/BizObjectNameFetcherDirect.cs | 7 +- server/AyaNova/biz/BizRoles.cs | 42 +- server/AyaNova/biz/ImportAyaNova7Biz.cs | 44 +- server/AyaNova/biz/Search.cs | 160 +++--- server/AyaNova/biz/TagBiz.cs | 497 ------------------ server/AyaNova/biz/TagGroupBiz.cs | 340 ------------ server/AyaNova/biz/TagGroupMapBiz.cs | 139 ----- server/AyaNova/biz/TagMapBiz.cs | 184 ------- server/AyaNova/biz/TaggableAttribute.cs | 15 - server/AyaNova/biz/UserBiz.cs | 6 +- server/AyaNova/biz/WidgetBiz.cs | 6 +- server/AyaNova/models/AyContext.cs | 6 +- server/AyaNova/models/Tag.cs | 21 - server/AyaNova/models/TagGroup.cs | 21 - server/AyaNova/models/TagGroupMap.cs | 23 - server/AyaNova/models/TagMap.cs | 25 - server/AyaNova/models/dto/TagGroupMapInfo.cs | 13 - server/AyaNova/models/dto/TagMapGroupInfo.cs | 15 - server/AyaNova/models/dto/TagMapInfo.cs | 14 - server/AyaNova/util/AySchema.cs | 38 +- server/AyaNova/util/DbUtil.cs | 3 +- test/raven-integration/AyaType/AyaType.cs | 2 +- 34 files changed, 158 insertions(+), 2624 deletions(-) delete mode 100644 server/AyaNova/Controllers/TagController.cs delete mode 100644 server/AyaNova/Controllers/TagGroupController.cs delete mode 100644 server/AyaNova/Controllers/TagGroupMapController.cs delete mode 100644 server/AyaNova/Controllers/TagMapController.cs delete mode 100644 server/AyaNova/biz/TagBiz.cs delete mode 100644 server/AyaNova/biz/TagGroupBiz.cs delete mode 100644 server/AyaNova/biz/TagGroupMapBiz.cs delete mode 100644 server/AyaNova/biz/TagMapBiz.cs delete mode 100644 server/AyaNova/biz/TaggableAttribute.cs delete mode 100644 server/AyaNova/models/Tag.cs delete mode 100644 server/AyaNova/models/TagGroup.cs delete mode 100644 server/AyaNova/models/TagGroupMap.cs delete mode 100644 server/AyaNova/models/TagMap.cs delete mode 100644 server/AyaNova/models/dto/TagGroupMapInfo.cs delete mode 100644 server/AyaNova/models/dto/TagMapGroupInfo.cs delete mode 100644 server/AyaNova/models/dto/TagMapInfo.cs diff --git a/devdocs/todo.txt b/devdocs/todo.txt index 399ada69..ec06f11c 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -16,6 +16,11 @@ SON OF TAGS //DONE - Unicode tag names - Remove old tag code, models, schema tables, cleanup and db erase code that refers to them + - THINGS TO FIX AS A RESULT OF THIS: + - Search.cs search code had a ton of tag stuff in it, rejig that shit + - Import AyaNova7 biz tons of tag stuff + + - Add new tag code to all taggable objects - Update seeder to tag objects with known set of tags for test and eval purposes - Seed widget with predictable tags (Maybe colour names "red", "green", "blue" etc) @@ -118,8 +123,7 @@ SERVER - Delete user should delete private datafilters - Did I code how to handle implications of user delete anywhere yet?? - - Taggable attribute exists, is it being used to ensure that objects that are taggable only are being tagged? - - Attachable attribute does this, search for "IsAttachable" to see how it's done + - Stage 2 AFTER POSTED TEST ROUND COMPLETED - Error handling at client (log? display?) diff --git a/server/AyaNova/Controllers/AyaTypeController.cs b/server/AyaNova/Controllers/AyaTypeController.cs index 22dee256..60594843 100644 --- a/server/AyaNova/Controllers/AyaTypeController.cs +++ b/server/AyaNova/Controllers/AyaTypeController.cs @@ -56,20 +56,18 @@ namespace AyaNova.Api.Controllers var values = Enum.GetValues(typeof(AyaType)); foreach (AyaType t in values) { - - string name=t.ToString(); - if(t.HasAttribute(typeof(AttachableAttribute))){ - name+=" [Attachable]"; + + string name = t.ToString(); + if (t.HasAttribute(typeof(AttachableAttribute))) + { + name += " [Attachable]"; } - if(t.HasAttribute(typeof(TaggableAttribute))){ - name+=" [Taggable]"; - } - + l.Add(new NameIdItem() { Name = name, Id = (long)t }); } - + return Ok(new ApiOkResponse(l)); } diff --git a/server/AyaNova/Controllers/JobOperationsController.cs b/server/AyaNova/Controllers/JobOperationsController.cs index 1b171098..f5b195cb 100644 --- a/server/AyaNova/Controllers/JobOperationsController.cs +++ b/server/AyaNova/Controllers/JobOperationsController.cs @@ -15,7 +15,7 @@ namespace AyaNova.Api.Controllers { /// - /// Tag controller + /// JobOperations controller /// [ApiVersion("8.0")] [Route("api/v{version:apiVersion}/[controller]")] diff --git a/server/AyaNova/Controllers/TagController.cs b/server/AyaNova/Controllers/TagController.cs deleted file mode 100644 index 8f2bdaec..00000000 --- a/server/AyaNova/Controllers/TagController.cs +++ /dev/null @@ -1,305 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Routing; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.JsonPatch; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; -using AyaNova.Models; -using AyaNova.Api.ControllerHelpers; -using AyaNova.Biz; - - -namespace AyaNova.Api.Controllers -{ - - /// - /// Tag controller - /// - [ApiVersion("8.0")] - [Route("api/v{version:apiVersion}/[controller]")] - [Produces("application/json")] - [Authorize] - public class TagController : Controller - { - private readonly AyContext ct; - private readonly ILogger log; - private readonly ApiServerState serverState; - - - /// - /// ctor - /// - /// - /// - /// - public TagController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) - { - ct = dbcontext; - log = logger; - serverState = apiServerState; - } - - - /// - /// Get Tag - /// - /// Required roles: - /// AnyOne - /// - /// - /// A tag - [HttpGet("{id}")] - public async Task GetTag([FromRoute] long id) - { - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - - //Instantiate the business object handler - TagBiz biz = TagBiz.GetBiz(ct, HttpContext); - - if (!Authorized.IsAuthorizedToReadFullRecord(HttpContext.Items, biz.BizType)) - return StatusCode(401, new ApiNotAuthorizedResponse()); - - if (!ModelState.IsValid) - return BadRequest(new ApiErrorResponse(ModelState)); - - var o = await biz.GetAsync(id); - if (o == null) - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - - return Ok(new ApiOkResponse(o)); - } - - - /// - /// Get Tag pick list - /// - /// Required roles: AnyRole - /// - /// This endpoint queries the Name property of tags for - /// items that **START WITH** the characters submitted in the - /// "q" parameter - /// - /// Unlike most other picklists, wildcard characters if found in the query will be escaped and be considered part of the search string - /// Query is case insensitive as all tags are lowercase - /// - /// Empty queries will return all tags - /// - /// - /// Paged id/name collection of tags with paging data - [HttpGet("PickList", Name = nameof(PickList))] - public async Task PickList([FromQuery] string q, [FromQuery] PagingOptions pagingOptions) - { - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - - //Instantiate the business object handler - TagBiz biz = TagBiz.GetBiz(ct, HttpContext); - - if (!Authorized.IsAuthorizedToReadFullRecord(HttpContext.Items, biz.BizType))//Note: anyone can read a tag, but that might change in future so keeping this code in - return StatusCode(401, new ApiNotAuthorizedResponse()); - - if (!ModelState.IsValid) - return BadRequest(new ApiErrorResponse(ModelState)); - - ApiPagedResponse pr = await biz.GetPickListAsync(Url, nameof(PickList), pagingOptions, q); - return Ok(new ApiOkWithPagingResponse(pr)); - } - - - /// - /// Post TAG - /// - /// Required roles: - /// BizAdminFull, DispatchFull, InventoryFull, TechFull, AccountingFull - /// - /// String name of tag - /// object - [HttpPost] - public async Task PostTag([FromBody] NameItem inObj) - { - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - - //Instantiate the business object handler - TagBiz biz = TagBiz.GetBiz(ct, HttpContext); - - //If a user has change roles, or editOwnRoles then they can create, true is passed for isOwner since they are creating so by definition the owner - if (!Authorized.IsAuthorizedToCreate(HttpContext.Items, biz.BizType)) - return StatusCode(401, new ApiNotAuthorizedResponse()); - - if (!ModelState.IsValid) - return BadRequest(new ApiErrorResponse(ModelState)); - - //Create and validate - Tag o = await biz.CreateAsync(inObj.Name); - if (o == null) - return BadRequest(new ApiErrorResponse(biz.Errors)); - else - return CreatedAtAction("GetTag", new { id = o.Id }, new ApiCreatedResponse(o)); - } - - - /// - /// Put (update) Tag - /// - /// Required roles: - /// BizAdminFull, DispatchFull, InventoryFull, TechFull, AccountingFull - /// - /// - /// - /// - /// - [HttpPut("{id}")] - public async Task PutTag([FromRoute] long id, [FromBody] Tag oIn) - { - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - - if (!ModelState.IsValid) - return BadRequest(new ApiErrorResponse(ModelState)); - - //Instantiate the business object handler - TagBiz biz = TagBiz.GetBiz(ct, HttpContext); - - var oFromDb = await biz.GetAsync(id); - if (oFromDb == null) - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - - if (!Authorized.IsAuthorizedToModify(HttpContext.Items, biz.BizType, oFromDb.OwnerId)) - return StatusCode(401, new ApiNotAuthorizedResponse()); - - try - { - if (!biz.Put(oFromDb, oIn)) - return BadRequest(new ApiErrorResponse(biz.Errors)); - } - catch (DbUpdateConcurrencyException) - { - if (!await biz.ExistsAsync(id)) - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - else - return StatusCode(409, new ApiErrorResponse(ApiErrorCode.CONCURRENCY_CONFLICT)); - } - return Ok(new ApiOkResponse(new { ConcurrencyToken = oFromDb.ConcurrencyToken })); - } - - - /// - /// Patch (update) Tag - /// Required roles: BizAdminFull, DispatchFull, InventoryFull, TechFull, AccountingFull - /// - /// - /// - /// - /// - [HttpPatch("{id}/{concurrencyToken}")] - public async Task PatchTag([FromRoute] long id, [FromRoute] uint concurrencyToken, [FromBody]JsonPatchDocument objectPatch) - { - - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - - if (!ModelState.IsValid) - return BadRequest(new ApiErrorResponse(ModelState)); - - //Instantiate the business object handler - TagBiz biz = TagBiz.GetBiz(ct, HttpContext); - var oFromDb = await biz.GetAsync(id); - - if (oFromDb == null) - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - - if (!Authorized.IsAuthorizedToModify(HttpContext.Items, biz.BizType, oFromDb.OwnerId)) - return StatusCode(401, new ApiNotAuthorizedResponse()); - - try - { - //patch and validate - if (!biz.Patch(oFromDb, objectPatch, concurrencyToken)) - return BadRequest(new ApiErrorResponse(biz.Errors)); - } - catch (DbUpdateConcurrencyException) - { - if (!await biz.ExistsAsync(id)) - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - else - return StatusCode(409, new ApiErrorResponse(ApiErrorCode.CONCURRENCY_CONFLICT)); - } - return Ok(new ApiOkResponse(new { ConcurrencyToken = oFromDb.ConcurrencyToken })); - } - - - /// - /// Untag all objects with this tag - /// Required roles: BizAdminFull, DispatchFull, InventoryFull, TechFull, AccountingFull - /// - /// TagId - /// Ok - [HttpPost("UntagAll/{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)); - - //Instantiate the business object handler - TagBiz biz = TagBiz.GetBiz(ct, HttpContext); - - var dbObj = await biz.GetAsync(id); - if (dbObj == null) - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - - if (!Authorized.IsAuthorizedToModify(HttpContext.Items, biz.BizType, dbObj.OwnerId)) - return StatusCode(401, new ApiNotAuthorizedResponse()); - - //Untag from all places - if (!biz.Untag(dbObj)) - return BadRequest(new ApiErrorResponse(biz.Errors)); - - return NoContent(); - } - - - /// - /// Delete Tag - /// Required roles: BizAdminFull, DispatchFull, InventoryFull, TechFull, AccountingFull - /// - /// - /// Ok - [HttpDelete("{id}")] - public async Task DeleteTag([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)); - - //Instantiate the business object handler - TagBiz biz = TagBiz.GetBiz(ct, HttpContext); - - var dbObj = await biz.GetAsync(id); - if (dbObj == null) - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - - if (!Authorized.IsAuthorizedToDelete(HttpContext.Items, biz.BizType, dbObj.OwnerId)) - return StatusCode(401, new ApiNotAuthorizedResponse()); - - if (!biz.Delete(dbObj)) - return BadRequest(new ApiErrorResponse(biz.Errors)); - - return NoContent(); - } - - - //------------ - - - } -} \ No newline at end of file diff --git a/server/AyaNova/Controllers/TagGroupController.cs b/server/AyaNova/Controllers/TagGroupController.cs deleted file mode 100644 index ad1bb58b..00000000 --- a/server/AyaNova/Controllers/TagGroupController.cs +++ /dev/null @@ -1,337 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using System.Collections.Generic; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Routing; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.JsonPatch; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; -using AyaNova.Models; -using AyaNova.Api.ControllerHelpers; -using AyaNova.Biz; - - -namespace AyaNova.Api.Controllers -{ - - /// - /// TagGroup controller - /// - [ApiVersion("8.0")] - [Route("api/v{version:apiVersion}/[controller]")] - [Produces("application/json")] - [Authorize] - public class TagGroupController : Controller - { - private readonly AyContext ct; - private readonly ILogger log; - private readonly ApiServerState serverState; - - - /// - /// ctor - /// - /// - /// - /// - public TagGroupController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) - { - ct = dbcontext; - log = logger; - serverState = apiServerState; - } - - - /// - /// Get TagGroup - /// - /// Required roles: - /// AnyOne - /// - /// - /// A TagGroup - [HttpGet("{id}")] - public async Task GetTagGroup([FromRoute] long id) - { - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - - if (!Authorized.IsAuthorizedToReadFullRecord(HttpContext.Items, AyaType.TagGroup)) - return StatusCode(401, new ApiNotAuthorizedResponse()); - - if (!ModelState.IsValid) - return BadRequest(new ApiErrorResponse(ModelState)); - - //Instantiate the business object handler - TagGroupBiz biz = TagGroupBiz.GetBiz(ct, HttpContext); - - var o = await biz.GetAsync(id); - if (o == null) - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - return Ok(new ApiOkResponse(o)); - } - - - /// - /// Get TagGroup pick list, list of tag groups with name and ID - /// - /// Required roles: AnyRole - /// - /// This endpoint queries the Name property of TagGroups for - /// items that **START WITH** the characters submitted in the - /// "q" parameter - /// - /// Unlike most other picklists, wildcard characters if found in the query will be escaped and be considered part of the search string - /// Query is case insensitive as all TagGroups are lowercase - /// - /// Empty queries will return all TagGroups - /// - /// - /// Paged id/name collection of TagGroups with paging data - [HttpGet("TagGroupPickList", Name = nameof(TagGroupPickList))] - public async Task TagGroupPickList([FromQuery] string q, [FromQuery] PagingOptions pagingOptions) - { - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - - if (!Authorized.IsAuthorizedToReadFullRecord(HttpContext.Items, AyaType.TagGroup))//Note: anyone can read a TagGroup, but that might change in future so keeping this code in - return StatusCode(401, new ApiNotAuthorizedResponse()); - - if (!ModelState.IsValid) - return BadRequest(new ApiErrorResponse(ModelState)); - - //Instantiate the business object handler - TagGroupBiz biz = TagGroupBiz.GetBiz(ct, HttpContext); - - ApiPagedResponse pr = await biz.GetPickListAsync(Url, nameof(TagGroupPickList), pagingOptions, q); - return Ok(new ApiOkWithPagingResponse(pr)); - } - - - - - /// - /// Get Tag pick list from group - /// Required roles: AnyRole - /// - /// - /// TagGroupId - /// name value list of all tags in group - [HttpGet("TagsInGroupPickList/{id}")] - public async Task TagsInGroupPickList([FromRoute] long id) - { - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - - if (!Authorized.IsAuthorizedToReadFullRecord(HttpContext.Items, AyaType.TagGroup))//Note: anyone can read a tag-group, but that might change in future so keeping this code in - return StatusCode(401, new ApiNotAuthorizedResponse()); - - if (!ModelState.IsValid) - return BadRequest(new ApiErrorResponse(ModelState)); - - //Instantiate the business object handler - TagGroupBiz biz = TagGroupBiz.GetBiz(ct, HttpContext); - - var l = await biz.GetTagsInGroupPickListAsync(id); - return Ok(new ApiOkResponse(l)); - } - - /// - /// Post TagGroup - /// - /// Required roles: - /// BizAdminFull, DispatchFull, InventoryFull, TechFull, AccountingFull - /// - /// String name of TagGroup - /// object - [HttpPost] - public async Task PostTagGroup([FromBody] NameItem inObj) - { - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - - //If a user has change roles, or editOwnRoles then they can create, true is passed for isOwner since they are creating so by definition the owner - if (!Authorized.IsAuthorizedToCreate(HttpContext.Items, AyaType.TagGroup)) - return StatusCode(401, new ApiNotAuthorizedResponse()); - - if (!ModelState.IsValid) - return BadRequest(new ApiErrorResponse(ModelState)); - - //Instantiate the business object handler - TagGroupBiz biz = TagGroupBiz.GetBiz(ct, HttpContext); - - //Create and validate - TagGroup o = await biz.CreateAsync(inObj.Name); - if (o == null) - return BadRequest(new ApiErrorResponse(biz.Errors)); - else - return CreatedAtAction("GetTagGroup", new { id = o.Id }, new ApiCreatedResponse(o)); - } - - - - /// - /// Put (update) TagGroup - /// - /// Required roles: - /// BizAdminFull, DispatchFull, InventoryFull, TechFull, AccountingFull - /// - /// - /// - /// - /// - [HttpPut("{id}")] - public async Task PutTagGroup([FromRoute] long id, [FromBody] TagGroup oIn) - { - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - - if (!ModelState.IsValid) - return BadRequest(new ApiErrorResponse(ModelState)); - - //Instantiate the business object handler - TagGroupBiz biz = TagGroupBiz.GetBiz(ct, HttpContext); - var oFromDb = await biz.GetAsync(id); - - if (oFromDb == null) - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - - if (!Authorized.IsAuthorizedToModify(HttpContext.Items, AyaType.TagGroup, oFromDb.OwnerId)) - return StatusCode(401, new ApiNotAuthorizedResponse()); - - try - { - if (!biz.Put(oFromDb, oIn)) - return BadRequest(new ApiErrorResponse(biz.Errors)); - } - catch (DbUpdateConcurrencyException) - { - if (!await biz.ExistsAsync(id)) - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - else - return StatusCode(409, new ApiErrorResponse(ApiErrorCode.CONCURRENCY_CONFLICT)); - } - - return Ok(new ApiOkResponse(new { ConcurrencyToken = oFromDb.ConcurrencyToken })); - } - - - /// - /// Patch (update) TagGroup - /// Required roles: BizAdminFull, DispatchFull, InventoryFull, TechFull, AccountingFull - /// - /// - /// - /// - /// - [HttpPatch("{id}/{concurrencyToken}")] - public async Task PatchTagGroup([FromRoute] long id, [FromRoute] uint concurrencyToken, [FromBody]JsonPatchDocument objectPatch) - { - - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - - if (!ModelState.IsValid) - return BadRequest(new ApiErrorResponse(ModelState)); - - //Instantiate the business object handler - TagGroupBiz biz = TagGroupBiz.GetBiz(ct, HttpContext); - - var oFromDb = await biz.GetAsync(id); - - if (oFromDb == null) - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - - if (!Authorized.IsAuthorizedToModify(HttpContext.Items, AyaType.TagGroup, oFromDb.OwnerId)) - return StatusCode(401, new ApiNotAuthorizedResponse()); - - try - { - if (!biz.Patch(oFromDb, objectPatch, concurrencyToken)) - return BadRequest(new ApiErrorResponse(biz.Errors)); - } - catch (DbUpdateConcurrencyException) - { - if (!await biz.ExistsAsync(id)) - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - else - return StatusCode(409, new ApiErrorResponse(ApiErrorCode.CONCURRENCY_CONFLICT)); - } - return Ok(new ApiOkResponse(new { ConcurrencyToken = oFromDb.ConcurrencyToken })); - } - - - - /// - /// Delete TagGroup - Does not delete Tags from objects or Tags themselves, only the group - /// Required roles: BizAdminFull, DispatchFull, InventoryFull, TechFull, AccountingFull - /// - /// - /// Ok - [HttpDelete("{id}")] - public async Task DeleteTagGroup([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)); - - //Instantiate the business object handler - TagGroupBiz biz = TagGroupBiz.GetBiz(ct, HttpContext); - - var dbObj = await biz.GetAsync(id); - if (dbObj == null) - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - - if (!Authorized.IsAuthorizedToDelete(HttpContext.Items, AyaType.TagGroup, dbObj.OwnerId)) - return StatusCode(401, new ApiNotAuthorizedResponse()); - - if (!biz.Delete(dbObj)) - return BadRequest(new ApiErrorResponse(biz.Errors)); - - return NoContent(); - } - - - /// - /// Post TagMap from group - Map a group of tags to an object / Id - /// Required roles: Same roles as tagged object - /// - /// - /// TagMapGroupInfo - /// A list of names and id's of tags that were applied to object - [HttpPost("TagObject")] - public async Task TagObject([FromBody] TagMapGroupInfo inObj) - { - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - - //If a user has change roles, or editOwnRoles then they can create, true is passed for isOwner since they are creating so by definition the owner - if (!Authorized.IsAuthorizedToCreate(HttpContext.Items, AyaType.TagMap)) - return StatusCode(401, new ApiNotAuthorizedResponse()); - - //Rights to parent taggable object? - if (!Authorized.IsAuthorizedToCreate(HttpContext.Items, inObj.TagToObjectType)) - return StatusCode(401, new ApiNotAuthorizedResponse()); - - if (!ModelState.IsValid) - return BadRequest(new ApiErrorResponse(ModelState)); - - //Instantiate the business object handler - TagGroupBiz biz = TagGroupBiz.GetBiz(ct, HttpContext); - - //Create and return list - List l = await biz.TagObject(inObj); - if (l == null) - return BadRequest(new ApiErrorResponse(biz.Errors)); - else - return Ok(new ApiOkResponse(l)); - } - - - //------------ - }//eoc -}//eons \ No newline at end of file diff --git a/server/AyaNova/Controllers/TagGroupMapController.cs b/server/AyaNova/Controllers/TagGroupMapController.cs deleted file mode 100644 index e1b06046..00000000 --- a/server/AyaNova/Controllers/TagGroupMapController.cs +++ /dev/null @@ -1,197 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Routing; -using Microsoft.AspNetCore.Authorization; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; -using AyaNova.Models; -using AyaNova.Api.ControllerHelpers; -using AyaNova.Biz; - - -namespace AyaNova.Api.Controllers -{ - - /// - /// TagGroupMap controller - /// - [ApiVersion("8.0")] - [Route("api/v{version:apiVersion}/[controller]")] - [Produces("application/json")] - [Authorize] - public class TagGroupMapController : Controller - { - private readonly AyContext ct; - private readonly ILogger log; - private readonly ApiServerState serverState; - - - /// - /// ctor - /// - /// - /// - /// - public TagGroupMapController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) - { - ct = dbcontext; - log = logger; - serverState = apiServerState; - } - - - /// - /// Get TagGroupMap object - /// Required roles: BizAdminFull, DispatchFull, InventoryFull, TechFull, AccountingFull - /// - /// - /// A TagGroupMap - [HttpGet("{id}")] - public async Task GetTagGroupMap([FromRoute] long id) - { - if (!serverState.IsOpen) - { - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - } - - if (!Authorized.IsAuthorizedToReadFullRecord(HttpContext.Items, AyaType.TagGroupMap)) - { - return StatusCode(401, new ApiNotAuthorizedResponse()); - } - - if (!ModelState.IsValid) - { - return BadRequest(new ApiErrorResponse(ModelState)); - } - - //Instantiate the business object handler - TagGroupMapBiz biz = new TagGroupMapBiz(ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items)); - - var o = await biz.GetAsync(id); - - if (o == null) - { - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - } - - - return Ok(new ApiOkResponse(o)); - } - - - /// - /// Post TagGroupMap - Map a tag to a group - /// Required roles: BizAdminFull, DispatchFull, InventoryFull, TechFull, AccountingFull - /// - /// TagGroupMapInfo - /// object - [HttpPost] - public async Task PostTagGroupMap([FromBody] TagGroupMapInfo inObj) - { - if (!serverState.IsOpen) - { - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - } - - if (!Authorized.IsAuthorizedToCreate(HttpContext.Items, AyaType.TagGroupMap)) - { - return StatusCode(401, new ApiNotAuthorizedResponse()); - } - - - if (!ModelState.IsValid) - { - return BadRequest(new ApiErrorResponse(ModelState)); - } - - //Instantiate the business object handler - TagGroupMapBiz biz = new TagGroupMapBiz(ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items)); - - //Create and validate - TagGroupMap o = await biz.CreateAsync(inObj); - - if (o == null) - { - //error return - return BadRequest(new ApiErrorResponse(biz.Errors)); - } - else - { - //save and success return - await ct.SaveChangesAsync(); - - //BIZLOG: Not going to log this for now, it's too common an operation and would require bringing in more info. If decide to implement should log the parent object with text of tag instead - //and don't forget about import from v7 as well - - return CreatedAtAction("GetTagGroupMap", new { id = o.Id }, new ApiCreatedResponse(o)); - } - } - - - /// - /// Delete TagGroupMap - /// Required roles: BizAdminFull, DispatchFull, InventoryFull, TechFull, AccountingFull - /// - /// - /// Ok - [HttpDelete("{id}")] - public async Task DeleteTagGroupMap([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.TagGroupMap.SingleOrDefaultAsync(m => m.Id == id); - if (dbObj == null) - { - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - } - - if (!Authorized.IsAuthorizedToDelete(HttpContext.Items, AyaType.TagGroupMap, dbObj.OwnerId)) - { - return StatusCode(401, new ApiNotAuthorizedResponse()); - } - - //Instantiate the business object handler - TagGroupMapBiz biz = new TagGroupMapBiz(ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items)); - - if (!biz.Delete(dbObj)) - { - return BadRequest(new ApiErrorResponse(biz.Errors)); - } - - await ct.SaveChangesAsync(); - - //BIZLOG: Not going to log this for now, it's too common an operation and would require bringing in more info. If decide to implement should log the parent object with text of tag instead - - return NoContent(); - } - - - - - - private bool TagGroupMapExists(long id) - { - return ct.TagGroupMap.Any(e => e.Id == id); - } - - - - //------------ - - - - - - }//eoc -} \ No newline at end of file diff --git a/server/AyaNova/Controllers/TagMapController.cs b/server/AyaNova/Controllers/TagMapController.cs deleted file mode 100644 index 5c6cad5d..00000000 --- a/server/AyaNova/Controllers/TagMapController.cs +++ /dev/null @@ -1,264 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Routing; -using Microsoft.AspNetCore.Authorization; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; -using AyaNova.Models; -using AyaNova.Api.ControllerHelpers; -using AyaNova.Biz; - - -namespace AyaNova.Api.Controllers -{ - - /// - /// TagMap controller - /// - [ApiVersion("8.0")] - [Route("api/v{version:apiVersion}/[controller]")] - [Produces("application/json")] - [Authorize] - public class TagMapController : Controller - { - private readonly AyContext ct; - private readonly ILogger log; - private readonly ApiServerState serverState; - - - /// - /// ctor - /// - /// - /// - /// - public TagMapController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) - { - ct = dbcontext; - log = logger; - serverState = apiServerState; - } - - - /// - /// Get TagMap object - /// - /// Required roles: Same roles as tagged object - /// - /// - /// A TagMap - [HttpGet("{id}")] - public async Task GetTagMap([FromRoute] long id) - { - if (!serverState.IsOpen) - { - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - } - - if (!Authorized.IsAuthorizedToReadFullRecord(HttpContext.Items, AyaType.TagMap)) - { - return StatusCode(401, new ApiNotAuthorizedResponse()); - } - - if (!ModelState.IsValid) - { - return BadRequest(new ApiErrorResponse(ModelState)); - } - - //Instantiate the business object handler - TagMapBiz biz = new TagMapBiz(ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items)); - - var o = await biz.GetAsync(id); - - if (o == null) - { - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - } - - //Check rights to parent tagged object - if (!Authorized.IsAuthorizedToReadFullRecord(HttpContext.Items, o.TagToObjectType)) - { - return StatusCode(401, new ApiNotAuthorizedResponse()); - } - - - return Ok(new ApiOkResponse(o)); - } - - - /// - /// Post TagMap - Map a single Tag to an object / Id - /// Required roles: Same roles as tagged object - /// - /// - /// TagMapInfo - /// object - [HttpPost] - public async Task PostTagMap([FromBody] TagMapInfo inObj) - { - if (!serverState.IsOpen) - { - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - } - - //If a user has change roles, or editOwnRoles then they can create, true is passed for isOwner since they are creating so by definition the owner - if (!Authorized.IsAuthorizedToCreate(HttpContext.Items, AyaType.TagMap)) - { - return StatusCode(401, new ApiNotAuthorizedResponse()); - } - - //Rights to parent taggable object? - if (!Authorized.IsAuthorizedToCreate(HttpContext.Items, inObj.TagToObjectType)) - { - return StatusCode(401, new ApiNotAuthorizedResponse()); - } - - if (!ModelState.IsValid) - { - return BadRequest(new ApiErrorResponse(ModelState)); - } - - //Instantiate the business object handler - TagMapBiz biz = new TagMapBiz(ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items)); - - //Create and validate - TagMap o = await biz.CreateAsync(inObj); - - if (o == null) - { - //error return - return BadRequest(new ApiErrorResponse(biz.Errors)); - } - else - { - //save and success return - await ct.SaveChangesAsync(); - - //BIZLOG: Not going to log this for now, it's too common an operation and would require bringing in more info. If decide to implement should log the parent object with text of tag instead - //and don't forget about import from v7 as well - - return CreatedAtAction("GetTagMap", new { id = o.Id }, new ApiCreatedResponse(o)); - } - } - - - /// - /// Delete TagMap - /// Required roles: Same roles as tagged object - /// - /// - /// Ok - [HttpDelete("{id}")] - public async Task DeleteTagMap([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.TagMap.SingleOrDefaultAsync(m => m.Id == id); - if (dbObj == null) - { - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - } - - if (!Authorized.IsAuthorizedToDelete(HttpContext.Items, AyaType.TagMap, dbObj.OwnerId)) - { - return StatusCode(401, new ApiNotAuthorizedResponse()); - } - - //Rights to parent tagged object? - if (!Authorized.IsAuthorizedToDelete(HttpContext.Items, dbObj.TagToObjectType, dbObj.OwnerId)) - { - return StatusCode(401, new ApiNotAuthorizedResponse()); - } - - //Instantiate the business object handler - TagMapBiz biz = new TagMapBiz(ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items)); - - if (!biz.Delete(dbObj)) - { - return BadRequest(new ApiErrorResponse(biz.Errors)); - } - - await ct.SaveChangesAsync(); - - //BIZLOG: Not going to log this for now, it's too common an operation and would require bringing in more info. If decide to implement should log the parent object with text of tag instead - - return NoContent(); - } - - - - - - - /// - /// Get Tag pick list - /// - /// Required roles: Follows parent (tagged object) roles - /// - /// - /// Name / Id collection of tags on object - [HttpGet("TagsOnObject")] - public async Task TagsOnObjectList([FromBody] TypeAndIdInfo inObj) - { - if (!serverState.IsOpen) - { - return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); - } - - if (!Authorized.IsAuthorizedToReadFullRecord(HttpContext.Items, AyaType.Tag))//Note: anyone can read a tag, but that might change in future so keeping this code in - { - return StatusCode(401, new ApiNotAuthorizedResponse()); - } - - if (!ModelState.IsValid) - { - return BadRequest(new ApiErrorResponse(ModelState)); - } - - - //Check rights to parent tagged object - if (!Authorized.IsAuthorizedToReadFullRecord(HttpContext.Items, inObj.ObjectType)) - { - return StatusCode(401, new ApiNotAuthorizedResponse()); - } - - - //Instantiate the business object handler - TagMapBiz biz = new TagMapBiz(ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items)); - - - var l = await biz.GetTagsOnObjectListAsync(new AyaTypeId(inObj.ObjectType, inObj.ObjectId)); - return Ok(new ApiOkResponse(l)); - } - - - - - - - private bool TagMapExists(long id) - { - return ct.TagMap.Any(e => e.Id == id); - } - - - - //------------ - - - - - - }//eoc -} \ No newline at end of file diff --git a/server/AyaNova/biz/AyaEvent.cs b/server/AyaNova/biz/AyaEvent.cs index 8275fff1..05ce08d6 100644 --- a/server/AyaNova/biz/AyaEvent.cs +++ b/server/AyaNova/biz/AyaEvent.cs @@ -21,8 +21,7 @@ namespace AyaNova.Biz LicenseFetch=7, LicenseTrialRequest=8, ServerStateChange=9, - SeedDatabase=10, - TagMassUntag=11 + SeedDatabase=10 //NEW ITEMS REQUIRE LOCALE KEYS AND UPDATE EventLogProcessor code that prefetches required keys diff --git a/server/AyaNova/biz/AyaType.cs b/server/AyaNova/biz/AyaType.cs index cd47c34c..005b855a 100644 --- a/server/AyaNova/biz/AyaType.cs +++ b/server/AyaNova/biz/AyaType.cs @@ -12,25 +12,25 @@ namespace AyaNova.Biz NoType = 0, Global = 1, - [Attachable, Taggable] + [Attachable] Widget = 2, - [Attachable, Taggable] + [Attachable] User = 3, ServerState = 4, License = 5, LogFile = 6, - Tag = 7, - TagMap = 8, + DEPRECATED_REUSELATER_7 = 7, + DEPRECATED_REUSELATER_8 = 8, JobOperations = 9, AyaNova7Import = 10, TrialSeeder = 11, Metrics = 12, Locale = 13, UserOptions = 14, - TagGroup = 15, - TagGroupMap = 16, + DEPRECATED_REUSELATER_15 = 15, + DEPRECATED_REUSELATER_16 = 16, FileAttachment = 17, DataFilter = 18 diff --git a/server/AyaNova/biz/BizObjectExistsInDatabase.cs b/server/AyaNova/biz/BizObjectExistsInDatabase.cs index d9c1e91b..5cacbe1d 100644 --- a/server/AyaNova/biz/BizObjectExistsInDatabase.cs +++ b/server/AyaNova/biz/BizObjectExistsInDatabase.cs @@ -38,11 +38,7 @@ namespace AyaNova.Biz case AyaType.User: return ct.User.Any(m => m.Id == id); case AyaType.Widget: - return ct.Widget.Any(m => m.Id == id); - case AyaType.Tag: - return ct.Tag.Any(m => m.Id == id); - case AyaType.TagGroup: - return ct.TagGroup.Any(m => m.Id == id); + return ct.Widget.Any(m => m.Id == id); case AyaType.FileAttachment: return ct.FileAttachment.Any(m => m.Id == id); case AyaType.DataFilter: diff --git a/server/AyaNova/biz/BizObjectFactory.cs b/server/AyaNova/biz/BizObjectFactory.cs index 189f8695..c4317eb4 100644 --- a/server/AyaNova/biz/BizObjectFactory.cs +++ b/server/AyaNova/biz/BizObjectFactory.cs @@ -26,11 +26,7 @@ namespace AyaNova.Biz case AyaType.User: return new UserBiz(dbcontext, userId, ServerBootConfig.AYANOVA_DEFAULT_LANGUAGE_ID, roles); case AyaType.Widget: - return new WidgetBiz(dbcontext, userId, ServerBootConfig.AYANOVA_DEFAULT_LANGUAGE_ID, roles); - case AyaType.Tag: - return new TagBiz(dbcontext, userId, ServerBootConfig.AYANOVA_DEFAULT_LANGUAGE_ID, roles); - case AyaType.TagMap: - return new TagMapBiz(dbcontext, userId, roles); + return new WidgetBiz(dbcontext, userId, ServerBootConfig.AYANOVA_DEFAULT_LANGUAGE_ID, roles); case AyaType.JobOperations: return new JobOperationsBiz(dbcontext, userId, roles); case AyaType.AyaNova7Import: diff --git a/server/AyaNova/biz/BizObjectNameFetcher.cs b/server/AyaNova/biz/BizObjectNameFetcher.cs index 6a113d1a..ac639bf2 100644 --- a/server/AyaNova/biz/BizObjectNameFetcher.cs +++ b/server/AyaNova/biz/BizObjectNameFetcher.cs @@ -44,10 +44,7 @@ namespace AyaNova.Biz // return ct.User.AsNoTracking().Where(m => m.Id == id).Select(m => m.Name).FirstOrDefault(); // case AyaType.Widget: // return ct.Widget.AsNoTracking().Where(m => m.Id == id).Select(m => m.Name).FirstOrDefault(); - // case AyaType.Tag: - // return ct.Tag.AsNoTracking().Where(m => m.Id == id).Select(m => m.Name).FirstOrDefault(); - // case AyaType.TagGroup: - // return ct.TagGroup.AsNoTracking().Where(m => m.Id == id).Select(m => m.Name).FirstOrDefault(); + // case AyaType.FileAttachment: // return ct.FileAttachment.AsNoTracking().Where(m => m.Id == id).Select(m => m.DisplayFileName).FirstOrDefault(); diff --git a/server/AyaNova/biz/BizObjectNameFetcherDirect.cs b/server/AyaNova/biz/BizObjectNameFetcherDirect.cs index 42befc62..039679e0 100644 --- a/server/AyaNova/biz/BizObjectNameFetcherDirect.cs +++ b/server/AyaNova/biz/BizObjectNameFetcherDirect.cs @@ -37,12 +37,7 @@ namespace AyaNova.Biz case AyaType.Widget: TABLE = "awidget"; break; - case AyaType.Tag: - TABLE = "atag"; - break; - case AyaType.TagGroup: - TABLE = "ataggroup"; - break; + case AyaType.FileAttachment: TABLE = "afileattachment"; COLUMN = "displayfilename"; diff --git a/server/AyaNova/biz/BizRoles.cs b/server/AyaNova/biz/BizRoles.cs index fddad9f5..db6db221 100644 --- a/server/AyaNova/biz/BizRoles.cs +++ b/server/AyaNova/biz/BizRoles.cs @@ -92,46 +92,8 @@ namespace AyaNova.Biz ReadFullRecord = AuthorizationRoles.OpsAdminFull | AuthorizationRoles.OpsAdminLimited }); - //////////////////////////////////////////////////////////// - //TAG - //Full roles can make new tags and can edit or delete existing tags - roles.Add(AyaType.Tag, new BizRoleSet() - { - Change = AuthorizationRoles.BizAdminFull | AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryFull | AuthorizationRoles.TechFull | AuthorizationRoles.AccountingFull, - EditOwn = AuthorizationRoles.NoRole, - ReadFullRecord = AuthorizationRoles.AnyRole - }); - - //////////////////////////////////////////////////////////// - //TAGMAP - //Any roles can tag objects and remove tags as per their rights to the taggable object type in question - roles.Add(AyaType.TagMap, new BizRoleSet() - { - Change = AuthorizationRoles.AnyRole, - EditOwn = AuthorizationRoles.NoRole, - ReadFullRecord = AuthorizationRoles.AnyRole - }); - - //////////////////////////////////////////////////////////// - //TAGGROUP - MIRROR TAGS - //Full roles can make new tags and can edit or delete existing tags - roles.Add(AyaType.TagGroup, new BizRoleSet() - { - Change = AuthorizationRoles.BizAdminFull | AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryFull | AuthorizationRoles.TechFull | AuthorizationRoles.AccountingFull, - EditOwn = AuthorizationRoles.NoRole, - ReadFullRecord = AuthorizationRoles.AnyRole - }); - - //////////////////////////////////////////////////////////// - //TAGGROUPMAP - MIRROR TAGMAP - //Full roles can make new taggroupmaps and can edit or delete existing taggroupmaps - roles.Add(AyaType.TagGroupMap, new BizRoleSet() - { - Change = AuthorizationRoles.BizAdminFull | AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryFull | AuthorizationRoles.TechFull | AuthorizationRoles.AccountingFull, - EditOwn = AuthorizationRoles.NoRole, - ReadFullRecord = AuthorizationRoles.AnyRole - }); - + + //////////////////////////////////////////////////////////// //OPERATIONS / JOBS diff --git a/server/AyaNova/biz/ImportAyaNova7Biz.cs b/server/AyaNova/biz/ImportAyaNova7Biz.cs index 7615c9e3..9891cfb3 100644 --- a/server/AyaNova/biz/ImportAyaNova7Biz.cs +++ b/server/AyaNova/biz/ImportAyaNova7Biz.cs @@ -97,36 +97,38 @@ namespace AyaNova.Biz await DoImport("GZTW.AyaNova.BLL.User", "eventlog", AyaType.User, job.GId, importMap, importFileName, zipEntries); - //IMPORT UNIT MODEL CATEGORIES AS TAGS - await DoImport("GZTW.AyaNova.BLL.UnitModelCategory", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); +//TODO: these need to be done differently and after the main objects are imported or in parallel with them as there is no +//separate tag type object anymore +//I guess cache the list of each v7 string and id type and then use that to tag objects as they are import4ed that use them - //IMPORT Unit service type AS TAGS - await DoImport("GZTW.AyaNova.BLL.UnitServiceType", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); + // //IMPORT UNIT MODEL CATEGORIES AS TAGS + // await DoImport("GZTW.AyaNova.BLL.UnitModelCategory", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); - //IMPORT Workorder Item Type AS TAGS - await DoImport("GZTW.AyaNova.BLL.WorkorderItemType", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); + // //IMPORT Unit service type AS TAGS + // await DoImport("GZTW.AyaNova.BLL.UnitServiceType", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); - //IMPORT Client group AS TAGS - await DoImport("GZTW.AyaNova.BLL.ClientGroup", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); + // //IMPORT Workorder Item Type AS TAGS + // await DoImport("GZTW.AyaNova.BLL.WorkorderItemType", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); - //IMPORT Workorder category AS TAGS - await DoImport("GZTW.AyaNova.BLL.WorkorderCategory", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); + // //IMPORT Client group AS TAGS + // await DoImport("GZTW.AyaNova.BLL.ClientGroup", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); - //IMPORT Part Category AS TAGS - await DoImport("GZTW.AyaNova.BLL.PartCategory", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); + // //IMPORT Workorder category AS TAGS + // await DoImport("GZTW.AyaNova.BLL.WorkorderCategory", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); - //IMPORT Dispatch zones AS TAGS - await DoImport("GZTW.AyaNova.BLL.DispatchZone", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); + // //IMPORT Part Category AS TAGS + // await DoImport("GZTW.AyaNova.BLL.PartCategory", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); - //IMPORT Scheduleable User Groups AS TAGS - await DoImport("GZTW.AyaNova.BLL.ScheduleableUserGroup", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); - //Now can set users to correct tag for scheduleable user group - await DoImport("GZTW.AyaNova.BLL.ScheduleableUserGroup", "scheduleableusergrouptags", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); + // //IMPORT Dispatch zones AS TAGS + // await DoImport("GZTW.AyaNova.BLL.DispatchZone", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); + // //IMPORT Scheduleable User Groups AS TAGS + // await DoImport("GZTW.AyaNova.BLL.ScheduleableUserGroup", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); + // //Now can set users to correct tag for scheduleable user group + // await DoImport("GZTW.AyaNova.BLL.ScheduleableUserGroup", "scheduleableusergrouptags", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); - - //IMPORT REGIONS AS TAGS - await DoImport("GZTW.AyaNova.BLL.Region", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); + // //IMPORT REGIONS AS TAGS + // await DoImport("GZTW.AyaNova.BLL.Region", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries); //IMPORT LOCALES await DoImport("GZTW.AyaNova.BLL.Locale", "main", AyaType.Locale, job.GId, importMap, importFileName, zipEntries); diff --git a/server/AyaNova/biz/Search.cs b/server/AyaNova/biz/Search.cs index b26b05ca..b15e747e 100644 --- a/server/AyaNova/biz/Search.cs +++ b/server/AyaNova/biz/Search.cs @@ -65,7 +65,7 @@ namespace AyaNova.Biz public string Phrase { get; set; } public bool NameOnly { get; set; } public AyaType TypeOnly { get; set; } - public List Tags { get; set; } + // public List Tags { get; set; } //Note: maxresults of 0 will get all results public int MaxResults { get; set; } @@ -73,7 +73,7 @@ namespace AyaNova.Biz { NameOnly = false; TypeOnly = AyaType.NoType; - Tags = new List(); + // Tags = new List(); MaxResults = 500; } @@ -85,9 +85,9 @@ namespace AyaNova.Biz if (!string.IsNullOrWhiteSpace(this.Phrase)) return true; - //has tags? - if (this.Tags.Count > 0) - return true; + // //has tags? + // if (this.Tags.Count > 0) + // return true; return false; } @@ -213,97 +213,97 @@ namespace AyaNova.Biz //IF TAGS SPECIFIED //BUGBUG: If no valid tags provided, i.e. a single tag of type or id 0 then can skip - if (searchParameters.Tags.Count > 0) - { - //get a count of the search tags (used by both paths below) - var SearchTagCount = searchParameters.Tags.Count; + // if (searchParameters.Tags.Count > 0) + // { + // //get a count of the search tags (used by both paths below) + // var SearchTagCount = searchParameters.Tags.Count; - if (string.IsNullOrWhiteSpace(searchParameters.Phrase)) - { + // if (string.IsNullOrWhiteSpace(searchParameters.Phrase)) + // { - #region TAGS ONLY SEARCH (NO PHRASE) ALL FULL MATCHES ARE INCLUSIVE - Dictionary TagCounts = new Dictionary(); + // #region TAGS ONLY SEARCH (NO PHRASE) ALL FULL MATCHES ARE INCLUSIVE + // Dictionary TagCounts = new Dictionary(); - //QUERY FOR ALL TAGMAPS THAT MATCH OBJECT TYPE AND ID FOR EVERY TAG SPECIFIED (UNION) - //var tagmatches= await ct.TagMap.Where(m => ).Select(m => m.Id).ToListAsync(); - //ct.TagMap.Where(n => n.Tags.Count(t => tags.Contains(t.DisplayName)) == tags.Count) + // //QUERY FOR ALL TAGMAPS THAT MATCH OBJECT TYPE AND ID FOR EVERY TAG SPECIFIED (UNION) + // //var tagmatches= await ct.TagMap.Where(m => ).Select(m => m.Id).ToListAsync(); + // //ct.TagMap.Where(n => n.Tags.Count(t => tags.Contains(t.DisplayName)) == tags.Count) - //algorithm: - //1) get counts for each tag specified from tagmap, if any are zero then none match and can bail early - foreach (long SearchTagId in searchParameters.Tags) - { - var MatchTagCount = await ct.TagMap.Where(m => m.TagId == SearchTagId).LongCountAsync(); - //zero tags matching here at any point means no results for the entire search and we can bail - if (MatchTagCount == 0) - { - //return empty resultlist - return ReturnObject; - } + // //algorithm: + // //1) get counts for each tag specified from tagmap, if any are zero then none match and can bail early + // foreach (long SearchTagId in searchParameters.Tags) + // { + // var MatchTagCount = await ct.TagMap.Where(m => m.TagId == SearchTagId).LongCountAsync(); + // //zero tags matching here at any point means no results for the entire search and we can bail + // if (MatchTagCount == 0) + // { + // //return empty resultlist + // return ReturnObject; + // } - //Save the matching count - TagCounts.Add(SearchTagId, MatchTagCount); - } + // //Save the matching count + // TagCounts.Add(SearchTagId, MatchTagCount); + // } - //2) find smallest count match so we are working with the shortest list first - var ShortestMatchingTag = TagCounts.OrderBy(x => x.Value).First().Key; + // //2) find smallest count match so we are working with the shortest list first + // var ShortestMatchingTag = TagCounts.OrderBy(x => x.Value).First().Key; - //3) Generate the shortlist of items that match the shortest tag list - var ShortList = await ct.TagMap.Where(x => x.TagId == ShortestMatchingTag).ToListAsync(); + // //3) Generate the shortlist of items that match the shortest tag list + // var ShortList = await ct.TagMap.Where(x => x.TagId == ShortestMatchingTag).ToListAsync(); - //4) Iterate the shortlist and see if each item matches all other tags specified if it does then put it into the matching objects list for return + // //4) Iterate the shortlist and see if each item matches all other tags specified if it does then put it into the matching objects list for return - //Iterate shortlist - foreach (TagMap t in ShortList) - { - var matchCount = 1; - //Iterate requested tags - foreach (long TagId in searchParameters.Tags) - { - //skipping already matched shortest tag - if (TagId != ShortestMatchingTag) - { - //Ok, does this object have this tag? - bool HasTag = await ct.TagMap.Where(x => x.TagToObjectId == t.TagToObjectId && x.TagToObjectType == t.TagToObjectType && x.TagId == TagId).AnyAsync(); - if (HasTag) - matchCount++; - } - } - //does it match all tags? - if (matchCount == SearchTagCount) - { - //yes, add it to the results - MatchingObjects.Add(new AyaTypeId(t.TagToObjectType, t.TagToObjectId)); - } - } - #endregion + // //Iterate shortlist + // foreach (TagMap t in ShortList) + // { + // var matchCount = 1; + // //Iterate requested tags + // foreach (long TagId in searchParameters.Tags) + // { + // //skipping already matched shortest tag + // if (TagId != ShortestMatchingTag) + // { + // //Ok, does this object have this tag? + // bool HasTag = await ct.TagMap.Where(x => x.TagToObjectId == t.TagToObjectId && x.TagToObjectType == t.TagToObjectType && x.TagId == TagId).AnyAsync(); + // if (HasTag) + // matchCount++; + // } + // } + // //does it match all tags? + // if (matchCount == SearchTagCount) + // { + // //yes, add it to the results + // MatchingObjects.Add(new AyaTypeId(t.TagToObjectType, t.TagToObjectId)); + // } + // } + // #endregion - } - else - { - #region TAGS PLUS PHRASE SEARCH WITH NON MATCHING TAGS EXCLUSIVE - //list to hold temporary matches - List TagMatchingObjects = new List(); + // } + // else + // { + // #region TAGS PLUS PHRASE SEARCH WITH NON MATCHING TAGS EXCLUSIVE + // //list to hold temporary matches + // List TagMatchingObjects = new List(); - //LOOP THROUGH MATCHING OBJECTS LIST - foreach (AyaTypeId i in MatchingObjects) - { - var matchCount = await ct.TagMap.Where(x => x.TagToObjectId == i.ObjectId && x.TagToObjectType == i.ObjectType && searchParameters.Tags.Contains(x.TagId)).LongCountAsync(); - if (matchCount == SearchTagCount) - { - TagMatchingObjects.Add(i); - } + // //LOOP THROUGH MATCHING OBJECTS LIST + // foreach (AyaTypeId i in MatchingObjects) + // { + // var matchCount = await ct.TagMap.Where(x => x.TagToObjectId == i.ObjectId && x.TagToObjectType == i.ObjectType && searchParameters.Tags.Contains(x.TagId)).LongCountAsync(); + // if (matchCount == SearchTagCount) + // { + // TagMatchingObjects.Add(i); + // } - } + // } - //Ok here we have all the MatchingObjects that had all the tags in the TagMatchingObjects list so that's actually now our defacto return list - MatchingObjects = TagMatchingObjects; + // //Ok here we have all the MatchingObjects that had all the tags in the TagMatchingObjects list so that's actually now our defacto return list + // MatchingObjects = TagMatchingObjects; - #endregion + // #endregion - } - } + // } + // } //REMOVE ANY ITEMS THAT USER IS NOT PERMITTED TO READ //If it's a name only search then all is allowed @@ -403,7 +403,7 @@ namespace AyaNova.Biz //AyContext ct = ServiceProviderProvider.DBContext; #if (DEBUG) - if (objectType == AyaType.TagMap || objectType == AyaType.JobOperations || objectType == AyaType.Locale) + if ( objectType == AyaType.JobOperations || objectType == AyaType.Locale) { throw new System.NotSupportedException($"Search::ProcessKeywords - Invalid type presented {objectType}"); } diff --git a/server/AyaNova/biz/TagBiz.cs b/server/AyaNova/biz/TagBiz.cs deleted file mode 100644 index aed73259..00000000 --- a/server/AyaNova/biz/TagBiz.cs +++ /dev/null @@ -1,497 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.JsonPatch; -using EnumsNET; -using AyaNova.Util; -using AyaNova.Api.ControllerHelpers; -using AyaNova.Biz; -using AyaNova.Models; -using Newtonsoft.Json.Linq; -using System.Collections.Generic; - -namespace AyaNova.Biz -{ - - internal class TagBiz : BizObject, IImportAyaNova7Object - { - - public bool SeedOrImportRelaxedRulesMode { get; set; } - - internal TagBiz(AyContext dbcontext, long currentUserId, long userLocaleId, AuthorizationRoles userRoles) - { - ct = dbcontext; - UserId = currentUserId; - UserLocaleId = userLocaleId; - CurrentUserRoles = userRoles; - BizType = AyaType.Tag; - SeedOrImportRelaxedRulesMode = false;//default - } - - internal static TagBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext) - { - return new TagBiz(ct, UserIdFromContext.Id(httpContext.Items), UserLocaleIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items)); - } - - //////////////////////////////////////////////////////////////////////////////////////////////// - //EXISTS - internal async Task ExistsAsync(long id) - { - return await ct.Tag.AnyAsync(e => e.Id == id); - } - - //////////////////////////////////////////////////////////////////////////////////////////////// - /// GET - internal async Task GetAsync(long fetchId) - { - //This is simple so nothing more here, but often will be copying to a different output object or some other ops - return await ct.Tag.SingleOrDefaultAsync(m => m.Id == fetchId); - } - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //CREATE - internal async Task CreateAsync(string inObj) - { - inObj = CleanTagName(inObj); - Validate(inObj, true); - if (HasErrors) - return null; - else - { - //do stuff with Tag - Tag outObj = new Tag() - { - Name = inObj, - OwnerId = UserId - }; - - - await ct.Tag.AddAsync(outObj); - - await ct.SaveChangesAsync(); - - //Handle child and associated items: - - //EVENT LOG - EventLogProcessor.LogEventToDatabase(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct); - - //SEARCH INDEXING - Search.ProcessNewObjectKeywords(UserLocaleId, outObj.Id, BizType, outObj.Name, outObj.Name); - - return outObj; - } - } - - private static string CleanTagName(string inObj) - { - //Must be lowercase per rules - //This may be naive when we get international customers but for now supporting utf-8 and it appears it's safe to do this with unicode - inObj = inObj.ToLowerInvariant(); - //No spaces in tags, replace with dashes - inObj = inObj.Replace(" ", "-"); - //Remove multiple dash sequences - inObj = System.Text.RegularExpressions.Regex.Replace(inObj, "-+", "-"); - //Ensure doesn't start or end with a dash - inObj = inObj.Trim('-'); - //No longer than 255 characters - inObj = StringUtil.MaxLength(inObj, 255); - return inObj; - } - - - - - - //get picklist (paged) - //Unlike most picklists, this one only checks for starts with and wildcards are not supported / treated as part of tag name - internal async Task> GetPickListAsync(IUrlHelper Url, string routeName, PagingOptions pagingOptions, string q) - { - pagingOptions.Offset = pagingOptions.Offset ?? PagingOptions.DefaultOffset; - pagingOptions.Limit = pagingOptions.Limit ?? PagingOptions.DefaultLimit; - - NameIdItem[] items; - int totalRecordCount = 0; - - if (!string.IsNullOrWhiteSpace(q)) - { - //tags are allow saved this way so search this way too - q = q.ToLowerInvariant(); - - items = await ct.Tag - //There is some debate on this for efficiency - //I chose this method because I think it escapes potential wildcards in the string automatically - //and I don't want people using wildcards with this, only starts with is supported - //https://stackoverflow.com/questions/45708715/entity-framework-ef-functions-like-vs-string-contains - .Where(m => m.Name.StartsWith(q)) - // .Where(m => EF.Functions.ILike(m.Name, q)) - .OrderBy(m => m.Name) - .Skip(pagingOptions.Offset.Value) - .Take(pagingOptions.Limit.Value) - .Select(m => new NameIdItem() - { - Id = m.Id, - Name = m.Name - }).ToArrayAsync(); - - totalRecordCount = await ct.Tag.Where(m => m.Name.StartsWith(q)).CountAsync(); - } - else - { - items = await ct.Tag - .OrderBy(m => m.Name) - .Skip(pagingOptions.Offset.Value) - .Take(pagingOptions.Limit.Value) - .Select(m => new NameIdItem() - { - Id = m.Id, - Name = m.Name - }).ToArrayAsync(); - - totalRecordCount = await ct.Tag.CountAsync(); - } - - - - var pageLinks = new PaginationLinkBuilder(Url, routeName, null, pagingOptions, totalRecordCount).PagingLinksObject(); - - ApiPagedResponse pr = new ApiPagedResponse(items, pageLinks); - return pr; - } - - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //UPDATE - // - - //put - internal bool Put(Tag dbObj, Tag inObj) - { - //preserve the owner ID if none was specified - if (inObj.OwnerId == 0) - inObj.OwnerId = dbObj.OwnerId; - - //Ensure it follows the rules - inObj.Name = CleanTagName(inObj.Name); - - //Replace the db object with the PUT object - CopyObject.Copy(inObj, dbObj, "Id"); - //Set "original" value of concurrency token to input token - //this will allow EF to check it out - ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = inObj.ConcurrencyToken; - - Validate(dbObj.Name, false); - if (HasErrors) - return false; - - //Log modification - EventLogProcessor.LogEventToDatabase(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); - - //Update keywords - Search.ProcessUpdatedObjectKeywords( UserLocaleId, dbObj.Id, BizType, dbObj.Name, dbObj.Name); - - - return true; - } - - //patch - internal bool Patch(Tag dbObj, JsonPatchDocument objectPatch, uint concurrencyToken) - { - //Validate Patch is allowed - if (!ValidateJsonPatch.Validate(this, objectPatch)) return false; - - //Do the patching - objectPatch.ApplyTo(dbObj); - ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = concurrencyToken; - //Ensure it follows the rules - dbObj.Name = CleanTagName(dbObj.Name); - Validate(dbObj.Name, false); - if (HasErrors) - return false; - - //Log modification - EventLogProcessor.LogEventToDatabase(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); - - //Update keywords - Search.ProcessUpdatedObjectKeywords( UserLocaleId, dbObj.Id, BizType, dbObj.Name, dbObj.Name); - - - return true; - } - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //DELETE - // - - internal bool Delete(Tag dbObj) - { - //Determine if the object can be deleted, do the deletion and related objects - - ValidateCanDelete(dbObj); - if (HasErrors) - return false; - ct.Tag.Remove(dbObj); - ct.SaveChanges(); - - //Delete sibling objects - - //Event log process delete - EventLogProcessor.DeleteObject(UserId, BizType, dbObj.Id, dbObj.Name, ct); - ct.SaveChanges(); - - //Delete search index - Search.ProcessDeletedObjectKeywords(dbObj.Id, BizType); - - return true; - } - - - - //////////////////////////////////////////////////////////////////////////////////////////////// - // 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}"); - //Log - EventLogProcessor.LogEventToDatabase(new Event(UserId, dbObj.Id, BizType, AyaEvent.TagMassUntag), ct); - - return true; - } - - //////////////////////////////////////////////////////////////////////////////////////////////// - //VALIDATION - // - - //Can save or update? - private void Validate(string inObj, bool isNew) - { - //run validation and biz rules - - //Name required - if (string.IsNullOrWhiteSpace(inObj)) - AddError(ValidationErrorType.RequiredPropertyEmpty, "Name"); - - //Name must be less than 255 characters - if (inObj.Length > 255) - AddError(ValidationErrorType.LengthExceeded, "Name", "255 char max"); - - //Name must be unique - if (ct.Tag.Where(m => m.Name == inObj).FirstOrDefault() != null) - AddError(ValidationErrorType.NotUnique, "Name"); - - return; - } - - - //Can delete? - private void ValidateCanDelete(Tag inObj) - { - //whatever needs to be checked to delete this object - - //See if any tagmaps exist with this tag in which case it's not deleteable - if (ct.TagMap.Any(e => e.TagId == inObj.Id)) - { - AddError(ValidationErrorType.ReferentialIntegrity, "object", "Can't be deleted while has relations"); - } - - if (ct.TagGroupMap.Any(e => e.TagId == inObj.Id)) - { - AddError(ValidationErrorType.ReferentialIntegrity, "TagGroup", "Can't be deleted while has TagGroup relations"); - } - - } - - - - - ///////////////////////////////////////////////////////////////////// - /// IMPORT v7 implementation - public async Task ImportV7Async(JObject j, List importMap, Guid jobId) - { - //NO TASK TYPE, IT'S ALL THE SAME, KEEPING THIS FOR POSSIBLE FUTURE PURPOSES LIKE APPENDING OBJECT TYPE OR SOMETHING - string SourceType = j["V7_TYPE"].Value(); - switch (SourceType) - { - case "GZTW.AyaNova.BLL.Region": - case "GZTW.AyaNova.BLL.UnitModelCategory": - case "GZTW.AyaNova.BLL.UnitServiceType": - case "GZTW.AyaNova.BLL.WorkorderItemType": - case "GZTW.AyaNova.BLL.ClientGroup": - case "GZTW.AyaNova.BLL.WorkorderCategory": - case "GZTW.AyaNova.BLL.PartCategory": - case "GZTW.AyaNova.BLL.DispatchZone": - case "GZTW.AyaNova.BLL.ScheduleableUserGroup": - { - switch (j["IMPORT_TASK"].Value()) - { - case "main": - { - #region main import task - var NewTagName = j["Name"].Value(); - - var ShortTypeName = string.Empty; - switch (SourceType) - { - case "GZTW.AyaNova.BLL.Region": - ShortTypeName = "rgn"; - break; - case "GZTW.AyaNova.BLL.UnitModelCategory": - ShortTypeName = "unitmdlctgry"; - break; - case "GZTW.AyaNova.BLL.UnitServiceType": - ShortTypeName = "unitsvtyp"; - break; - case "GZTW.AyaNova.BLL.WorkorderItemType": - ShortTypeName = "woitemtyp"; - break; - case "GZTW.AyaNova.BLL.ClientGroup": - ShortTypeName = "clntgrp"; - break; - case "GZTW.AyaNova.BLL.WorkorderCategory": - ShortTypeName = "woctgry"; - break; - case "GZTW.AyaNova.BLL.PartCategory": - ShortTypeName = "prtctgry"; - break; - case "GZTW.AyaNova.BLL.DispatchZone": - ShortTypeName = "dspchzn"; - break; - case "GZTW.AyaNova.BLL.ScheduleableUserGroup": - ShortTypeName = "schdusrgrp"; - break; - } - - - NewTagName += "." + ShortTypeName; - var OldV7Id = new Guid(j["ID"].Value()); - - //Ensure it follows the rules - NewTagName = CleanTagName(NewTagName); - - //There might already be a tag of the same name since so many different types of V7 objects are becoming tags - //Weighed the pros and cons of uniquifying by object type versus just using the same name for different object types: - //it seems to me at this point that people might desire the same exact name because if they used it that way they probably - //intended it that way, so decision is to check if it already exists and then use that ID in the importMap instead - //for matching other objects imported to tags - - //Already present? - var ExistingTag = ct.Tag.Where(m => m.Name == NewTagName).FirstOrDefault(); - if (ExistingTag != null) - { - //map it to the existing tag of same name - var mapItem = new ImportAyaNova7MapItem(OldV7Id, AyaType.Tag, ExistingTag.Id); - } - else - { - - Tag o = await CreateAsync(NewTagName); - if (HasErrors) - { - //If there are any validation errors, log in joblog and move on - JobsBiz.LogJob(jobId, $"TagBiz::ImportV7Async -> import object \"{NewTagName}\" of type \"{SourceType}\" source id {OldV7Id.ToString()} failed validation and was not imported: {GetErrorsAsString()} ", ct); - return false; - } - else - { - await ct.SaveChangesAsync(); - var mapItem = new ImportAyaNova7MapItem(OldV7Id, AyaType.Tag, o.Id); - importMap.Add(mapItem); - ImportAyaNova7Biz.LogEventCreatedModifiedEvents(j, importMap, AyaType.Tag, ct); - } - } - #endregion - } - break; - case "scheduleableusergrouptags": - { - #region attribute sched user group tags - /* - { - "ID": "871e77b2-979a-4f26-930b-46f7c05fc19f", - "Created": "08/30/2018 08:12 AM", - "Modified": "08/30/2018 08:13 AM", - "Creator": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed", - "Modifier": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed", - "Name": "Yet another test group", - "Active": true, - "Description": "More testing yay!", - "ScheduleableUsers": [ - { - "Created": "08/30/2018 08:13 AM", - "Creator": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed", - "Modified": "08/30/2018 08:13 AM", - "Modifier": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed", - "ID": "676475be-8301-47d0-bd54-af9dbd1fe7eb", - "ScheduleableUserID": "1d859264-3f32-462a-9b0c-a67dddfdf4d3", - "ScheduleableUserGroupID": "871e77b2-979a-4f26-930b-46f7c05fc19f" - }, - { - "Created": "08/30/2018 08:13 AM", - "Creator": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed", - "Modified": "08/30/2018 08:13 AM", - "Modifier": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed", - "ID": "173499c3-a616-42a0-b08c-74008f8fa352", - "ScheduleableUserID": "42b282bb-100b-4b31-aa14-5c831d7cda66", - "ScheduleableUserGroupID": "871e77b2-979a-4f26-930b-46f7c05fc19f" - }, - { - "Created": "08/30/2018 08:13 AM", - "Creator": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed", - "Modified": "08/30/2018 08:13 AM", - "Modifier": "2ecc77fc-69e2-4a7e-b88d-bd0ecaf36aed", - "ID": "19c9b3d6-eeb2-44ac-be4e-6ec93d15b02a", - "ScheduleableUserID": "e6ff9bc6-a550-4242-8c41-857f740e2841", - "ScheduleableUserGroupID": "871e77b2-979a-4f26-930b-46f7c05fc19f" - } - ] - } - */ - var V7Id = new Guid(j["ID"].Value()); - var RavenTagId = importMap.Where(m => m.V7ObjectId == V7Id).First().NewObjectAyaTypeId.ObjectId; - - foreach (JToken t in j["ScheduleableUsers"]) - { - var techId = new Guid(t["ScheduleableUserID"].Value()); - var RavenUserId = importMap.Where(m => m.V7ObjectId == techId).First().NewObjectAyaTypeId.ObjectId; - var Creator = importMap.Where(m => m.V7ObjectId == new Guid(t["Creator"].Value())).First().NewObjectAyaTypeId.ObjectId; - - TagMap tm = new TagMap(); - tm.TagToObjectId = RavenUserId; - tm.TagToObjectType = AyaType.User; - tm.TagId = RavenTagId; - tm.OwnerId = Creator; - ct.TagMap.Add(tm); - } - ct.SaveChanges(); - - #endregion - } - break; - } - - } - break; - - - } - - //this is the equivalent of returning void for a Task signature with nothing to return - return true; - } - - - ///////////////////////////////////////////////////////////////////// - - }//eoc - - // -}//eons - diff --git a/server/AyaNova/biz/TagGroupBiz.cs b/server/AyaNova/biz/TagGroupBiz.cs deleted file mode 100644 index c545705e..00000000 --- a/server/AyaNova/biz/TagGroupBiz.cs +++ /dev/null @@ -1,340 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.JsonPatch; -using EnumsNET; -using AyaNova.Util; -using AyaNova.Api.ControllerHelpers; -using AyaNova.Biz; -using AyaNova.Models; -using Newtonsoft.Json.Linq; -using System.Collections.Generic; - -namespace AyaNova.Biz -{ - - internal class TagGroupBiz : BizObject - { - // private readonly AyContext ct; - // public readonly long userId; - // private readonly AuthorizationRoles userRoles; - - public bool V7ValidationImportMode { get; set; } - - internal TagGroupBiz(AyContext dbcontext, long currentUserId, long userLocaleId, AuthorizationRoles userRoles) - { - ct = dbcontext; - UserId = currentUserId; - UserLocaleId = userLocaleId; - CurrentUserRoles = userRoles; - BizType = AyaType.TagGroup; - V7ValidationImportMode = false;//default - } - - internal static TagGroupBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext) - { - return new TagGroupBiz(ct, UserIdFromContext.Id(httpContext.Items), UserLocaleIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items)); - } - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //EXISTS - internal async Task ExistsAsync(long id) - { - return await ct.TagGroup.AnyAsync(e => e.Id == id); - } - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //CREATE - internal async Task CreateAsync(string inObj) - { - inObj = CleanTagGroupName(inObj); - Validate(inObj, true); - if (HasErrors) - return null; - else - { - //do stuff with TagGroup - TagGroup outObj = new TagGroup() - { - Name = inObj, - OwnerId = UserId - }; - await ct.TagGroup.AddAsync(outObj); - - //EVENT LOG - EventLogProcessor.LogEventToDatabase(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct); - - //SEARCH INDEXING - Search.ProcessNewObjectKeywords( UserLocaleId, outObj.Id, BizType, outObj.Name, outObj.Name); - - return outObj; - } - } - - private static string CleanTagGroupName(string inObj) - { - //Must be lowercase per rules - //This may be naive when we get international customers but for now supporting utf-8 and it appears it's safe to do this with unicode - inObj = inObj.ToLowerInvariant(); - //No spaces in TagGroups, replace with dashes - inObj = inObj.Replace(" ", "-"); - //Remove multiple dash sequences - inObj = System.Text.RegularExpressions.Regex.Replace(inObj, "-+", "-"); - //Ensure doesn't start or end with a dash - inObj = inObj.Trim('-'); - //No longer than 255 characters - inObj = StringUtil.MaxLength(inObj, 255); - return inObj; - } - - //////////////////////////////////////////////////////////////////////////////////////////////// - /// GET - - //Get one - internal async Task GetAsync(long fetchId) - { - //This is simple so nothing more here, but often will be copying to a different output object or some other ops - return await ct.TagGroup.SingleOrDefaultAsync(m => m.Id == fetchId); - } - - - - //get picklist (paged) - //Unlike most picklists, this one only checks for starts with and wildcards are not supported / treated as part of TagGroup name - internal async Task> GetPickListAsync(IUrlHelper Url, string routeName, PagingOptions pagingOptions, string q) - { - pagingOptions.Offset = pagingOptions.Offset ?? PagingOptions.DefaultOffset; - pagingOptions.Limit = pagingOptions.Limit ?? PagingOptions.DefaultLimit; - - NameIdItem[] items; - int totalRecordCount = 0; - - if (!string.IsNullOrWhiteSpace(q)) - { - //TagGroups are allow saved this way so search this way too - q = q.ToLowerInvariant(); - - items = await ct.TagGroup - //There is some debate on this for efficiency - //I chose this method because I think it escapes potential wildcards in the string automatically - //and I don't want people using wildcards with this, only starts with is supported - //https://stackoverflow.com/questions/45708715/entity-framework-ef-functions-like-vs-string-contains - .Where(m => m.Name.StartsWith(q)) - // .Where(m => EF.Functions.ILike(m.Name, q)) - .OrderBy(m => m.Name) - .Skip(pagingOptions.Offset.Value) - .Take(pagingOptions.Limit.Value) - .Select(m => new NameIdItem() - { - Id = m.Id, - Name = m.Name - }).ToArrayAsync(); - - totalRecordCount = await ct.TagGroup.Where(m => m.Name.StartsWith(q)).CountAsync(); - } - else - { - items = await ct.TagGroup - .OrderBy(m => m.Name) - .Skip(pagingOptions.Offset.Value) - .Take(pagingOptions.Limit.Value) - .Select(m => new NameIdItem() - { - Id = m.Id, - Name = m.Name - }).ToArrayAsync(); - - totalRecordCount = await ct.TagGroup.CountAsync(); - } - - - - var pageLinks = new PaginationLinkBuilder(Url, routeName, null, pagingOptions, totalRecordCount).PagingLinksObject(); - - ApiPagedResponse pr = new ApiPagedResponse(items, pageLinks); - return pr; - } - - - //get picklist (simple non-paged) - internal async Task> GetTagsInGroupPickListAsync(long tagGroupId) - { - //first, get an array of the tagId's in this group - var tagGroupTags = await ct.TagGroupMap.Where(m => m.TagGroupId == tagGroupId).Select(m => m.TagId).ToArrayAsync(); - - List l = new List(); - l = await ct.Tag - .Where(m => tagGroupTags.Contains(m.Id)) - .OrderBy(m => m.Name) - .Select(m => new NameIdItem() - { - Id = m.Id, - Name = m.Name - }).ToListAsync(); - - return l; - - } - - //////////////////////////////////////////////////////////////////////////////////////////////// - //UPDATE - // - - //put - internal bool Put(TagGroup dbObj, TagGroup inObj) - { - //preserve the owner ID if none was specified - if (inObj.OwnerId == 0) - inObj.OwnerId = dbObj.OwnerId; - - //Ensure it follows the rules - inObj.Name = CleanTagGroupName(inObj.Name); - - //Replace the db object with the PUT object - CopyObject.Copy(inObj, dbObj, "Id"); - //Set "original" value of concurrency token to input token - //this will allow EF to check it out - ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = inObj.ConcurrencyToken; - - Validate(dbObj.Name, false); - if (HasErrors) - return false; - - //Log modification - EventLogProcessor.LogEventToDatabase(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); - - //Update keywords - Search.ProcessUpdatedObjectKeywords( UserLocaleId, dbObj.Id, BizType, dbObj.Name, dbObj.Name); - - return true; - } - - //patch - internal bool Patch(TagGroup dbObj, JsonPatchDocument objectPatch, uint concurrencyToken) - { - //Validate Patch is allowed - if (!ValidateJsonPatch.Validate(this, objectPatch)) return false; - - //Do the patching - objectPatch.ApplyTo(dbObj); - ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = concurrencyToken; - //Ensure it follows the rules - dbObj.Name = CleanTagGroupName(dbObj.Name); - Validate(dbObj.Name, false); - if (HasErrors) - return false; - - //Log modification - EventLogProcessor.LogEventToDatabase(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); - - //Update keywords - Search.ProcessUpdatedObjectKeywords( UserLocaleId, dbObj.Id, BizType, dbObj.Name, dbObj.Name); - - return true; - } - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //DELETE - // - - internal bool Delete(TagGroup dbObj) - { - //Determine if the object can be deleted, do the deletion tentatively - - ValidateCanDelete(dbObj); - if (HasErrors) - return false; - ct.Database.ExecuteSqlCommand($"delete from ataggroupmap where taggroupid = {dbObj.Id}"); - ct.Database.ExecuteSqlCommand($"delete from ataggroup where id = {dbObj.Id}"); - - //Event log process delete - EventLogProcessor.DeleteObject(UserId, BizType, dbObj.Id, dbObj.Name, ct); - ct.SaveChanges(); - - //Delete search index - Search.ProcessDeletedObjectKeywords(dbObj.Id, BizType); - - return true; - } - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //TagObject - internal async Task> TagObject(TagMapGroupInfo inObj) - { - var ReturnObject = new List(); - var TagGroupTags = await GetTagsInGroupPickListAsync(inObj.TagGroupId); - if (TagGroupTags.Count == 0) return ReturnObject; - - //Tag each one separately via TagMap which handles cases where object is already tagged with that tag etc - var MapBiz = new TagMapBiz(ct, UserId, CurrentUserRoles); - foreach (NameIdItem TagInGroup in TagGroupTags) - { - var TagMapItem = await MapBiz.CreateAsync(new TagMapInfo { TagId = TagInGroup.Id, TagToObjectId = inObj.TagToObjectId, TagToObjectType = inObj.TagToObjectType }); - ReturnObject.Add(TagInGroup); - } - await ct.SaveChangesAsync(); - - //BIZLOG: Not going to log this for now, it's too common an operation and would require bringing in more info. If decide to implement should log the parent object with text of tag instead - //and don't forget about import from v7 as well - - return ReturnObject; - - } - - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //VALIDATION - // - - //Can save or update? - private void Validate(string inObj, bool isNew) - { - //run validation and biz rules - - //Name required - if (string.IsNullOrWhiteSpace(inObj)) - AddError(ValidationErrorType.RequiredPropertyEmpty, "Name"); - - //Name must be less than 255 characters - if (inObj.Length > 255) - AddError(ValidationErrorType.LengthExceeded, "Name", "255 char max"); - - //Name must be unique - if (ct.TagGroup.Where(m => m.Name == inObj).FirstOrDefault() != null) - AddError(ValidationErrorType.NotUnique, "Name"); - - return; - } - - - //Can delete? - private void ValidateCanDelete(TagGroup inObj) - { - //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, "TagGroup", "Can't be deleted while has tags mapped"); - // } - - } - - - - - - ///////////////////////////////////////////////////////////////////// - - }//eoc - - // -}//eons - diff --git a/server/AyaNova/biz/TagGroupMapBiz.cs b/server/AyaNova/biz/TagGroupMapBiz.cs deleted file mode 100644 index 6608a303..00000000 --- a/server/AyaNova/biz/TagGroupMapBiz.cs +++ /dev/null @@ -1,139 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.JsonPatch; -using EnumsNET; -using AyaNova.Util; -using AyaNova.Api.ControllerHelpers; -using AyaNova.Biz; -using AyaNova.Models; -using System.Collections.Generic; - - -namespace AyaNova.Biz -{ - - - internal class TagGroupMapBiz : BizObject - { - - - internal TagGroupMapBiz(AyContext dbcontext, long currentUserId, AuthorizationRoles userRoles) - { - ct = dbcontext; - UserId = currentUserId; - CurrentUserRoles = userRoles; - BizType = AyaType.TagGroupMap; - } - - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //CREATE - internal async Task CreateAsync(TagGroupMapInfo inObj) - { - - //Is this taggroup mapping already present? - var Existing = await ct.TagGroupMap.Where(m => m.TagId == inObj.TagId && m.TagGroupId == inObj.TagGroupId).FirstOrDefaultAsync(); - if (Existing != null) - { - //yup so just return it, don't make a new one - return Existing; - } - - - Validate(inObj, true); - if (HasErrors) - return null; - else - { - //do stuff with TagGroupMap - TagGroupMap outObj = new TagGroupMap() - { - TagId = inObj.TagId, - TagGroupId = inObj.TagGroupId, - OwnerId = UserId - }; - - - await ct.TagGroupMap.AddAsync(outObj); - return outObj; - } - } - - //////////////////////////////////////////////////////////////////////////////////////////////// - /// GET - - //Get one - internal async Task GetAsync(long fetchId) - { - //This is simple so nothing more here, but often will be copying to a different output object or some other ops - return await ct.TagGroupMap.SingleOrDefaultAsync(m => m.Id == fetchId); - } - - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //DELETE - // - - internal bool Delete(TagGroupMap dbObj) - { - //Determine if the object can be deleted, do the deletion tentatively - - ValidateCanDelete(dbObj); - if (HasErrors) - return false; - ct.TagGroupMap.Remove(dbObj); - return true; - } - - - - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //VALIDATION - // - - //Can save or update? - private void Validate(TagGroupMapInfo inObj, bool isNew) - { - //run validation and biz rules - - // //Name required - // if (string.IsNullOrWhiteSpace(inObj)) - // AddError(ValidationErrorType.RequiredPropertyEmpty, "Name"); - - // //Name must be less than 255 characters - // if (inObj.Length > 255) - // AddError(ValidationErrorType.LengthExceeded, "Name", "255 char max"); - - return; - } - - - //Can delete? - private void ValidateCanDelete(TagGroupMap inObj) - { - //whatever needs to be check to delete this object - - //See if any TagGroupMaps exist with this tag in which case it's not deleteable - // if (ct.TagGroupMap.Any(e => e.TagGroupMapId == inObj.Id)) - // { - // AddError(ValidationErrorType.ReferentialIntegrity, "object", "Can't be deleted while has relations"); - // } - - } - - - ///////////////////////////////////////////////////////////////////// - - - - }//eoc - - -}//eons - diff --git a/server/AyaNova/biz/TagMapBiz.cs b/server/AyaNova/biz/TagMapBiz.cs deleted file mode 100644 index 696fcefa..00000000 --- a/server/AyaNova/biz/TagMapBiz.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.JsonPatch; -using EnumsNET; -using AyaNova.Util; -using AyaNova.Api.ControllerHelpers; -using AyaNova.Biz; -using AyaNova.Models; -using System.Collections.Generic; - - -namespace AyaNova.Biz -{ - - - internal class TagMapBiz : BizObject - { - - internal TagMapBiz(AyContext dbcontext, long currentUserId, AuthorizationRoles userRoles) - { - ct = dbcontext; - UserId = currentUserId; - CurrentUserRoles = userRoles; - BizType = AyaType.TagMap; - } - - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //CREATE - internal async Task CreateAsync(TagMapInfo inObj) - { - //Is this tag already present? - var Existing = await ct.TagMap.Where(m => m.TagId == inObj.TagId && m.TagToObjectId == inObj.TagToObjectId && m.TagToObjectType == inObj.TagToObjectType).FirstOrDefaultAsync(); - if (Existing != null) - { - //yup so just return it, don't make a new one - return Existing; - } - - Validate(inObj, true); - if (HasErrors) - return null; - else - { - //do stuff with TagMap - TagMap outObj = new TagMap() - { - TagId = inObj.TagId, - TagToObjectId = inObj.TagToObjectId, - TagToObjectType = inObj.TagToObjectType, - OwnerId = UserId - }; - - - await ct.TagMap.AddAsync(outObj); - return outObj; - } - } - - //////////////////////////////////////////////////////////////////////////////////////////////// - /// GET - - //Get one - internal async Task GetAsync(long fetchId) - { - //This is simple so nothing more here, but often will be copying to a different output object or some other ops - return await ct.TagMap.SingleOrDefaultAsync(m => m.Id == fetchId); - } - - - internal async Task> GetTagsOnObjectListAsync(AyaTypeId tid) - { - /* - - NOTES: This will be a bit of a "hot" path as every fetch of any main object will involve this - for now, just make it work and later can improve performance - - Also is sort going to be adequate, it's supposed to be based on invariant culture - - */ - - List l = new List(); - - //Get the list of tags on the object - var tagmapsOnObject = await ct.TagMap - .Where(m => m.TagToObjectId == tid.ObjectId && m.TagToObjectType == tid.ObjectType) - .Select(m => m.TagId) - .ToListAsync(); - - foreach (long tagId in tagmapsOnObject) - { - var tagFromDb = await ct.Tag.SingleOrDefaultAsync(m => m.Id == tagId); - if (tagFromDb != null) - { - l.Add(new NameIdItem() { Id = tagFromDb.Id, Name = tagFromDb.Name }); - } - } - - //Return the list sorted alphabetically - //Note if this is commonly required then maybe make a helper / extension for it - return (l.OrderBy(o => o.Name).ToList()); - } - - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //DELETE - // - - internal bool Delete(TagMap dbObj) - { - //Determine if the object can be deleted, do the deletion tentatively - - ValidateCanDelete(dbObj); - if (HasErrors) - return false; - ct.TagMap.Remove(dbObj); - return true; - } - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //DELETE ALL TAGMAPS FOR OBJECT - // - - static internal bool DeleteAllForObject(AyaTypeId parentObj, 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 - ct.Database.ExecuteSqlCommand($"delete from atagmap where tagtoobjectid={parentObj.ObjectId} and tagtoobjecttype={parentObj.ObjectTypeAsInt}"); - return true; - } - - - //////////////////////////////////////////////////////////////////////////////////////////////// - //VALIDATION - // - - //Can save or update? - private void Validate(TagMapInfo inObj, bool isNew) - { - //run validation and biz rules - - - - - // //Name required - // if (string.IsNullOrWhiteSpace(inObj)) - // AddError(ValidationErrorType.RequiredPropertyEmpty, "Name"); - - // //Name must be less than 255 characters - // if (inObj.Length > 255) - // AddError(ValidationErrorType.LengthExceeded, "Name", "255 char max"); - - return; - } - - - //Can delete? - private void ValidateCanDelete(TagMap inObj) - { - //whatever needs to be check to delete this object - - //See if any tagmaps exist with this tag in which case it's not deleteable - // if (ct.TagMap.Any(e => e.TagMapId == inObj.Id)) - // { - // AddError(ValidationErrorType.ReferentialIntegrity, "object", "Can't be deleted while has relations"); - // } - - } - - - ///////////////////////////////////////////////////////////////////// - - - - }//eoc - - -}//eons - diff --git a/server/AyaNova/biz/TaggableAttribute.cs b/server/AyaNova/biz/TaggableAttribute.cs deleted file mode 100644 index c2803f7c..00000000 --- a/server/AyaNova/biz/TaggableAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace AyaNova.Biz -{ - /// - /// Marker attribute indicating that an object supports tagging - /// Used in - /// - [AttributeUsage(AttributeTargets.All)] - public class TaggableAttribute : Attribute - { - //No code required, it's just a marker - //https://docs.microsoft.com/en-us/dotnet/standard/attributes/writing-custom-attributes - } -}//eons diff --git a/server/AyaNova/biz/UserBiz.cs b/server/AyaNova/biz/UserBiz.cs index 248871fa..3ac228df 100644 --- a/server/AyaNova/biz/UserBiz.cs +++ b/server/AyaNova/biz/UserBiz.cs @@ -321,9 +321,9 @@ namespace AyaNova.Biz //Delete search index Search.ProcessDeletedObjectKeywords(dbObj.Id, BizType); - //TAGS - TagMapBiz.DeleteAllForObject(new AyaTypeId(BizType, dbObj.Id), ct); - ct.SaveChanges(); + // //TAGS + // TagMapBiz.DeleteAllForObject(new AyaTypeId(BizType, dbObj.Id), ct); + // ct.SaveChanges(); return true; } diff --git a/server/AyaNova/biz/WidgetBiz.cs b/server/AyaNova/biz/WidgetBiz.cs index 8c7d5407..88a1bf35 100644 --- a/server/AyaNova/biz/WidgetBiz.cs +++ b/server/AyaNova/biz/WidgetBiz.cs @@ -346,9 +346,9 @@ namespace AyaNova.Biz //Delete search index Search.ProcessDeletedObjectKeywords(dbObj.Id, BizType); - //TAGS - TagMapBiz.DeleteAllForObject(new AyaTypeId(BizType, dbObj.Id), ct); - ct.SaveChanges(); + // //TAGS + // TagMapBiz.DeleteAllForObject(new AyaTypeId(BizType, dbObj.Id), ct); + // ct.SaveChanges(); return true; } diff --git a/server/AyaNova/models/AyContext.cs b/server/AyaNova/models/AyContext.cs index 923a8ac4..dee52be8 100644 --- a/server/AyaNova/models/AyContext.cs +++ b/server/AyaNova/models/AyContext.cs @@ -15,11 +15,7 @@ namespace AyaNova.Models public virtual DbSet UserOptions { get; set; } public virtual DbSet License { get; set; } public virtual DbSet Widget { get; set; } - public virtual DbSet FileAttachment { get; set; } - public virtual DbSet Tag { get; set; } - public virtual DbSet TagMap { get; set; } - public virtual DbSet TagGroup { get; set; } - public virtual DbSet TagGroupMap { get; set; } + public virtual DbSet FileAttachment { get; set; } public virtual DbSet OpsJob { get; set; } public virtual DbSet OpsJobLog { get; set; } public virtual DbSet Locale { get; set; } diff --git a/server/AyaNova/models/Tag.cs b/server/AyaNova/models/Tag.cs deleted file mode 100644 index 269b8fa8..00000000 --- a/server/AyaNova/models/Tag.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using AyaNova.Biz; - -using System.ComponentModel.DataAnnotations; - -namespace AyaNova.Models -{ - - public partial class Tag - { - public long Id { get; set; } - public uint ConcurrencyToken { get; set; } - - [Required] - public long OwnerId { get; set; } - [Required, MaxLength(255)] - public string Name { get; set; }//max 255 characters ascii set - - } -} diff --git a/server/AyaNova/models/TagGroup.cs b/server/AyaNova/models/TagGroup.cs deleted file mode 100644 index f5d8f5e1..00000000 --- a/server/AyaNova/models/TagGroup.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using AyaNova.Biz; - -using System.ComponentModel.DataAnnotations; - -namespace AyaNova.Models -{ - - public partial class TagGroup - { - public long Id { get; set; } - public uint ConcurrencyToken { get; set; } - - [Required] - public long OwnerId { get; set; } - [Required, MaxLength(255)] - public string Name { get; set; }//max 255 characters ascii set - - } -} diff --git a/server/AyaNova/models/TagGroupMap.cs b/server/AyaNova/models/TagGroupMap.cs deleted file mode 100644 index fd639933..00000000 --- a/server/AyaNova/models/TagGroupMap.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using AyaNova.Biz; - -using System.ComponentModel.DataAnnotations; - -namespace AyaNova.Models -{ - - public partial class TagGroupMap - { - public long Id { get; set; } - public uint ConcurrencyToken { get; set; } - [Required] - public long OwnerId { get; set; } - - [Required] - public long TagId { get; set; } - [Required] - public long TagGroupId { get; set; } - - } -} diff --git a/server/AyaNova/models/TagMap.cs b/server/AyaNova/models/TagMap.cs deleted file mode 100644 index 38e0691e..00000000 --- a/server/AyaNova/models/TagMap.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using AyaNova.Biz; - -using System.ComponentModel.DataAnnotations; - -namespace AyaNova.Models -{ - - public partial class TagMap - { - public long Id { get; set; } - public uint ConcurrencyToken { get; set; } - [Required] - public long OwnerId { get; set; } - - [Required] - public long TagId { get; set; } - [Required] - public long TagToObjectId { get; set; } - [Required] - public AyaType TagToObjectType { get; set; } - - } -} diff --git a/server/AyaNova/models/dto/TagGroupMapInfo.cs b/server/AyaNova/models/dto/TagGroupMapInfo.cs deleted file mode 100644 index d01bfb4e..00000000 --- a/server/AyaNova/models/dto/TagGroupMapInfo.cs +++ /dev/null @@ -1,13 +0,0 @@ -using AyaNova.Biz; - -namespace AyaNova.Models -{ - - public class TagGroupMapInfo - { - public long TagId { get; set; } - public long TagGroupId { get; set; } - } - - -} diff --git a/server/AyaNova/models/dto/TagMapGroupInfo.cs b/server/AyaNova/models/dto/TagMapGroupInfo.cs deleted file mode 100644 index 9d60479d..00000000 --- a/server/AyaNova/models/dto/TagMapGroupInfo.cs +++ /dev/null @@ -1,15 +0,0 @@ -using AyaNova.Biz; - -namespace AyaNova.Models -{ - - //Used by TagGroup controller to map a group of tags to an object - public class TagMapGroupInfo - { - public long TagGroupId { get; set; } - public long TagToObjectId { get; set; } - public AyaType TagToObjectType { get; set; } - } - - -} diff --git a/server/AyaNova/models/dto/TagMapInfo.cs b/server/AyaNova/models/dto/TagMapInfo.cs deleted file mode 100644 index 9a14472d..00000000 --- a/server/AyaNova/models/dto/TagMapInfo.cs +++ /dev/null @@ -1,14 +0,0 @@ -using AyaNova.Biz; - -namespace AyaNova.Models -{ - //Used by Tag controller to map a tag to an object - public class TagMapInfo - { - public long TagId { get; set; } - public long TagToObjectId { get; set; } - public AyaType TagToObjectType { get; set; } - } - - -} diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs index 2324bcae..25836550 100644 --- a/server/AyaNova/util/AySchema.cs +++ b/server/AyaNova/util/AySchema.cs @@ -239,31 +239,31 @@ namespace AyaNova.Util } - ////////////////////////////////////////////////// - //TAG tables - if (currentSchema < 6) - { - LogUpdateMessage(log); - // LOOKAT: Should taggroupmap have an index that enforces no taggroup can have the same tag more than once? Same for objects being tagged? - exec("CREATE TABLE atag (id BIGSERIAL PRIMARY KEY, ownerid bigint not null, name varchar(255) not null)"); + // ////////////////////////////////////////////////// + // //TAG tables + // if (currentSchema < 6) + // { + // LogUpdateMessage(log); + // // LOOKAT: Should taggroupmap have an index that enforces no taggroup can have the same tag more than once? Same for objects being tagged? + // exec("CREATE TABLE atag (id BIGSERIAL PRIMARY KEY, ownerid bigint not null, name varchar(255) not null)"); - //LOOKAT: isn't this useless without the ID? Need to see if it's being used after unit testing - exec("CREATE UNIQUE INDEX atag_name_idx ON atag (name);"); + // //LOOKAT: isn't this useless without the ID? Need to see if it's being used after unit testing + // exec("CREATE UNIQUE INDEX atag_name_idx ON atag (name);"); - exec("CREATE TABLE atagmap (id BIGSERIAL PRIMARY KEY, ownerid bigint not null," + - "tagid bigint not null REFERENCES atag (id), tagtoobjectid bigint not null, tagtoobjecttype integer not null)"); + // exec("CREATE TABLE atagmap (id BIGSERIAL PRIMARY KEY, ownerid bigint not null," + + // "tagid bigint not null REFERENCES atag (id), tagtoobjectid bigint not null, tagtoobjecttype integer not null)"); - //Taggroup - exec("CREATE TABLE ataggroup (id BIGSERIAL PRIMARY KEY, ownerid bigint not null, name varchar(255) not null)"); - exec("CREATE TABLE ataggroupmap (id BIGSERIAL PRIMARY KEY, ownerid bigint not null, tagid bigint not null REFERENCES atag (id), taggroupid bigint not null)"); + // //Taggroup + // exec("CREATE TABLE ataggroup (id BIGSERIAL PRIMARY KEY, ownerid bigint not null, name varchar(255) not null)"); + // exec("CREATE TABLE ataggroupmap (id BIGSERIAL PRIMARY KEY, ownerid bigint not null, tagid bigint not null REFERENCES atag (id), taggroupid bigint not null)"); - setSchemaLevel(++currentSchema); - } + // setSchemaLevel(++currentSchema); + // } ////////////////////////////////////////////////// // OPS LRO tables - if (currentSchema < 7) + if (currentSchema < 6) { LogUpdateMessage(log); @@ -279,7 +279,7 @@ namespace AyaNova.Util //LICENSE table new columns //LOOKAT: DO I need this anymore??? //answer: no because it relates to ops stuff in other tables and logging, not to the license itself (except maybe dbid?) - if (currentSchema < 8) + if (currentSchema < 7) { LogUpdateMessage(log); @@ -295,7 +295,7 @@ namespace AyaNova.Util ////////////////////////////////////////////////// //DATAFILTER table - if (currentSchema < 9) + if (currentSchema < 8) { LogUpdateMessage(log); diff --git a/server/AyaNova/util/DbUtil.cs b/server/AyaNova/util/DbUtil.cs index 2c451bd0..c67313f0 100644 --- a/server/AyaNova/util/DbUtil.cs +++ b/server/AyaNova/util/DbUtil.cs @@ -275,8 +275,7 @@ namespace AyaNova.Util //THIS METHOD IS ONLY CALLED BY SEEDER //SO ONLY REMOVE DATA THAT IS SEEDED //I.E. Normal user business data, not infrastructure data like license or localized text etc - EraseTable("atagmap", conn); - EraseTable("atag", conn); + EraseTable("afileattachment", conn); EraseTable("awidget", conn); EraseTable("aevent", conn); diff --git a/test/raven-integration/AyaType/AyaType.cs b/test/raven-integration/AyaType/AyaType.cs index 2dcac422..17a2d86e 100644 --- a/test/raven-integration/AyaType/AyaType.cs +++ b/test/raven-integration/AyaType/AyaType.cs @@ -25,7 +25,7 @@ namespace raven_integration //Number 2 is widget and list is zero based so confirm: a.ObjectResponse["data"][2]["id"].Value().Should().Be(2); - a.ObjectResponse["data"][2]["name"].Value().Should().Be("Widget [Attachable] [Taggable]"); + a.ObjectResponse["data"][2]["name"].Value().Should().Be("Widget [Attachable]"); }