diff --git a/devdocs/todo.txt b/devdocs/todo.txt index 2ebb9afa..60b88feb 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -1125,4 +1125,5 @@ BUILD 8.0.0 rc2 CHANGES OF NOTE Added integration back end feature for integration of external applications with AyaNova 8 Added front end administrative UI for viewing and controlling integrated applications and their logs Fixed potential lockout situation in AyaNova front end with force change known password code +Expanded roles allowed to fetch license to support integration of external applications diff --git a/server/AyaNova/Controllers/IntegrationController.cs b/server/AyaNova/Controllers/IntegrationController.cs index 788d7301..8443bc13 100644 --- a/server/AyaNova/Controllers/IntegrationController.cs +++ b/server/AyaNova/Controllers/IntegrationController.cs @@ -19,10 +19,10 @@ namespace AyaNova.Api.Controllers [Authorize] public class IntegrationController : ControllerBase { - /* - todo: needs routes for logging and fetching log to view, also mapping collection stuff perhaps?? - - */ + /* + todo: needs routes for logging and fetching log to view, also mapping collection stuff perhaps?? + + */ private readonly AyContext ct; private readonly ILogger log; private readonly ApiServerState serverState; @@ -63,7 +63,7 @@ namespace AyaNova.Api.Controllers return CreatedAtAction(nameof(IntegrationController.GetIntegration), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o)); } - + /// /// Get Integration /// @@ -79,11 +79,34 @@ namespace AyaNova.Api.Controllers return StatusCode(403, new ApiNotAuthorizedResponse()); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); - var o = await biz.GetAsync(integrationAppId, true, true); + var o = await biz.GetAsync(integrationAppId, true); if (o == null) return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); return Ok(ApiOkResponse.Response(o)); } + /// + /// Get Integration by DB Id + /// + /// + /// Integration + [HttpGet("by-dbid/{id}")] + public async Task GetIntegrationByDbId([FromRoute] long id) + { + if (!serverState.IsOpen) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + IntegrationBiz biz = IntegrationBiz.GetBiz(ct, HttpContext); + if (!Authorized.HasReadFullRole(HttpContext.Items, biz.BizType)) + return StatusCode(403, new ApiNotAuthorizedResponse()); + if (!ModelState.IsValid) + return BadRequest(new ApiErrorResponse(ModelState)); + var o = await biz.GetAsync(id, true); + if (o == null) return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); + return Ok(ApiOkResponse.Response(o)); + } + + + + /// /// Update Integration /// @@ -99,7 +122,7 @@ namespace AyaNova.Api.Controllers IntegrationBiz biz = IntegrationBiz.GetBiz(ct, HttpContext); if (!Authorized.HasModifyRole(HttpContext.Items, biz.BizType)) return StatusCode(403, new ApiNotAuthorizedResponse()); - var o = await biz.PutAsync(updatedObject); + var o = await biz.PutAsync(updatedObject); if (o == null) { if (biz.Errors.Exists(z => z.Code == ApiErrorCode.CONCURRENCY_CONFLICT)) @@ -130,6 +153,49 @@ namespace AyaNova.Api.Controllers return NoContent(); } + /// + /// Delete Integration + /// + /// + /// NoContent + [HttpDelete("by-dbid/{id}")] + public async Task DeleteIntegrationByDbId([FromRoute] long id) + { + if (!serverState.IsOpen) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + if (!ModelState.IsValid) + return BadRequest(new ApiErrorResponse(ModelState)); + IntegrationBiz biz = IntegrationBiz.GetBiz(ct, HttpContext); + if (!Authorized.HasDeleteRole(HttpContext.Items, biz.BizType)) + return StatusCode(403, new ApiNotAuthorizedResponse()); + if (!await biz.DeleteAsync(id)) + return BadRequest(new ApiErrorResponse(biz.Errors)); + return NoContent(); + } + + + + + + /// + /// Check Integration existance + /// + /// + /// Integration + [HttpGet("exists/{integrationAppId}")] + public async Task GetIntegrationExistance([FromRoute] Guid integrationAppId) + { + if (!serverState.IsOpen) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + IntegrationBiz biz = IntegrationBiz.GetBiz(ct, HttpContext); + if (!Authorized.HasReadFullRole(HttpContext.Items, biz.BizType)) + return StatusCode(403, new ApiNotAuthorizedResponse()); + if (!ModelState.IsValid) + return BadRequest(new ApiErrorResponse(ModelState)); + + return Ok(ApiOkResponse.Response(await biz.ExistsByIntegrationAppIdAsync(integrationAppId))); + } + diff --git a/server/AyaNova/biz/AyaType.cs b/server/AyaNova/biz/AyaType.cs index 4f8f0b4d..6575dfb9 100644 --- a/server/AyaNova/biz/AyaType.cs +++ b/server/AyaNova/biz/AyaType.cs @@ -191,6 +191,8 @@ namespace AyaNova.Biz //and need TRANSLATION KEYS because any type could show in the event log at the client end + //AND QBI mirrors this too + } diff --git a/server/AyaNova/biz/BizRoles.cs b/server/AyaNova/biz/BizRoles.cs index a2a31c02..e3a160ae 100644 --- a/server/AyaNova/biz/BizRoles.cs +++ b/server/AyaNova/biz/BizRoles.cs @@ -700,7 +700,14 @@ namespace AyaNova.Biz roles.Add(AyaType.License, new BizRoleSet() { Change = AuthorizationRoles.BizAdmin, - ReadFullRecord = AuthorizationRoles.BizAdminRestricted + ReadFullRecord = AuthorizationRoles.BizAdminRestricted //Biz admin restricted plus all users who can use integration object because *our* integrations such as QBI require license check + | AuthorizationRoles.BizAdmin + | AuthorizationRoles.Service + | AuthorizationRoles.Inventory + | AuthorizationRoles.Accounting + | AuthorizationRoles.Tech + | AuthorizationRoles.Sales + | AuthorizationRoles.OpsAdmin }); //////////////////////////////////////////////////////////// @@ -1095,12 +1102,13 @@ namespace AyaNova.Biz //GENERATE CLIENT COMPATIBLE JSON FROM ROLES OUTPUT TO DEBUG LOG //And seperately, set the JSON variable so can copy from debug variable "value" property for lastRoles here to compare - - /* + + /* + string json = Newtonsoft.Json.JsonConvert.SerializeObject(roles, Newtonsoft.Json.Formatting.None); System.Diagnostics.Debugger.Log(1, "JSONFRAGMENTFORCLIENT", "BizRoles.cs -> biz-role-rights.js Client roles JSON fragment:\n\n"); System.Diagnostics.Debugger.Log(1, "JSONFRAGMENTFORCLIENT", json + "\n\n"); - var lastRoles = "{\"Customer\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"CustomerNote\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"CustomerNotifySubscription\":{\"Change\":10,\"ReadFullRecord\":65797,\"Select\":131071},\"Contract\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"HeadOffice\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"LoanUnit\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"Part\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventory\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartWarehouse\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartAssembly\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PurchaseOrder\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryRequest\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryRestock\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryDataList\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryRequestDataList\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"Project\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"ServiceRate\":{\"Change\":74,\"ReadFullRecord\":33037,\"Select\":131071},\"TravelRate\":{\"Change\":74,\"ReadFullRecord\":33037,\"Select\":131071},\"TaxCode\":{\"Change\":66,\"ReadFullRecord\":98573,\"Select\":131071},\"Unit\":{\"Change\":330,\"ReadFullRecord\":98309,\"Select\":131071},\"UnitModel\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"UnitMeterReading\":{\"Change\":330,\"ReadFullRecord\":98309,\"Select\":131071},\"Vendor\":{\"Change\":106,\"ReadFullRecord\":98565,\"Select\":131071},\"TaskGroup\":{\"Change\":10,\"ReadFullRecord\":131071,\"Select\":131071},\"WorkOrderStatus\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"WorkOrderItemStatus\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"WorkOrderItemPriority\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"WorkOrder\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItem\":{\"Change\":330,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemExpense\":{\"Change\":458,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemLabor\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemLoan\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemPart\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemPartRequest\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemScheduledUser\":{\"Change\":330,\"ReadFullRecord\":99973,\"Select\":131071},\"WorkOrderItemTask\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemTravel\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemUnit\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemOutsideService\":{\"Change\":330,\"ReadFullRecord\":98437,\"Select\":131071},\"Quote\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItem\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemExpense\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemLabor\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemLoan\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemPart\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemScheduledUser\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemTask\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemTravel\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemUnit\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemOutsideService\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteStatus\":{\"Change\":32842,\"ReadFullRecord\":131071,\"Select\":131071},\"PM\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItem\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemExpense\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemLabor\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemLoan\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemPart\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemScheduledUser\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemTask\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemTravel\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemUnit\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemOutsideService\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"Global\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"GlobalOps\":{\"Change\":16384,\"ReadFullRecord\":8192,\"Select\":0},\"User\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":131071},\"UserOptions\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"ServerState\":{\"Change\":16384,\"ReadFullRecord\":131071,\"Select\":0},\"License\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"TrialSeeder\":{\"Change\":16386,\"ReadFullRecord\":8193,\"Select\":0},\"LogFile\":{\"Change\":0,\"ReadFullRecord\":24576,\"Select\":0},\"Backup\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"FileAttachment\":{\"Change\":2,\"ReadFullRecord\":3,\"Select\":0},\"ServerJob\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"OpsNotificationSettings\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"ServerMetrics\":{\"Change\":16384,\"ReadFullRecord\":24576,\"Select\":0},\"Translation\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":131071},\"DataListSavedFilter\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"FormUserOptions\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"FormCustom\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"PickListTemplate\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"BizMetrics\":{\"Change\":2,\"ReadFullRecord\":98369,\"Select\":0},\"Notification\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"NotifySubscription\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"Report\":{\"Change\":3,\"ReadFullRecord\":131071,\"Select\":131071},\"CustomerServiceRequest\":{\"Change\":4106,\"ReadFullRecord\":2309,\"Select\":131071},\"Memo\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Reminder\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Review\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Integration\":{\"Change\":49514,\"ReadFullRecord\":49514,\"Select\":49514}}"; + var lastRoles = "{\"Customer\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"CustomerNote\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"CustomerNotifySubscription\":{\"Change\":10,\"ReadFullRecord\":65797,\"Select\":131071},\"Contract\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"HeadOffice\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"LoanUnit\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"Part\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventory\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartWarehouse\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartAssembly\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PurchaseOrder\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryRequest\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryRestock\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryDataList\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryRequestDataList\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"Project\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"ServiceRate\":{\"Change\":74,\"ReadFullRecord\":33037,\"Select\":131071},\"TravelRate\":{\"Change\":74,\"ReadFullRecord\":33037,\"Select\":131071},\"TaxCode\":{\"Change\":66,\"ReadFullRecord\":98573,\"Select\":131071},\"Unit\":{\"Change\":330,\"ReadFullRecord\":98309,\"Select\":131071},\"UnitModel\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"UnitMeterReading\":{\"Change\":330,\"ReadFullRecord\":98309,\"Select\":131071},\"Vendor\":{\"Change\":106,\"ReadFullRecord\":98565,\"Select\":131071},\"TaskGroup\":{\"Change\":10,\"ReadFullRecord\":131071,\"Select\":131071},\"WorkOrderStatus\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"WorkOrderItemStatus\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"WorkOrderItemPriority\":{\"Change\":74,\"ReadFullRecord\":98565,\"Select\":131071},\"WorkOrder\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItem\":{\"Change\":330,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemExpense\":{\"Change\":458,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemLabor\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemLoan\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemPart\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemPartRequest\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemScheduledUser\":{\"Change\":330,\"ReadFullRecord\":99973,\"Select\":131071},\"WorkOrderItemTask\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemTravel\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemUnit\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemOutsideService\":{\"Change\":330,\"ReadFullRecord\":98437,\"Select\":131071},\"Quote\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItem\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemExpense\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemLabor\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemLoan\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemPart\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemScheduledUser\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemTask\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemTravel\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemUnit\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemOutsideService\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteStatus\":{\"Change\":32842,\"ReadFullRecord\":131071,\"Select\":131071},\"PM\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItem\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemExpense\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemLabor\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemLoan\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemPart\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemScheduledUser\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemTask\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemTravel\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemUnit\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemOutsideService\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"Global\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"GlobalOps\":{\"Change\":16384,\"ReadFullRecord\":8192,\"Select\":0},\"User\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":131071},\"UserOptions\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"ServerState\":{\"Change\":16384,\"ReadFullRecord\":131071,\"Select\":0},\"License\":{\"Change\":2,\"ReadFullRecord\":49515,\"Select\":0},\"TrialSeeder\":{\"Change\":16386,\"ReadFullRecord\":8193,\"Select\":0},\"LogFile\":{\"Change\":0,\"ReadFullRecord\":24576,\"Select\":0},\"Backup\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"FileAttachment\":{\"Change\":2,\"ReadFullRecord\":3,\"Select\":0},\"ServerJob\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"OpsNotificationSettings\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"ServerMetrics\":{\"Change\":16384,\"ReadFullRecord\":24576,\"Select\":0},\"Translation\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":131071},\"DataListSavedFilter\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"FormUserOptions\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"FormCustom\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"PickListTemplate\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"BizMetrics\":{\"Change\":2,\"ReadFullRecord\":98369,\"Select\":0},\"Notification\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"NotifySubscription\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"Report\":{\"Change\":3,\"ReadFullRecord\":131071,\"Select\":131071},\"CustomerServiceRequest\":{\"Change\":4106,\"ReadFullRecord\":2309,\"Select\":131071},\"Memo\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Reminder\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Review\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Integration\":{\"Change\":49514,\"ReadFullRecord\":49514,\"Select\":49514}}"; Dictionary lastRolesDeserialized = Newtonsoft.Json.JsonConvert.DeserializeObject>(lastRoles); if (lastRolesDeserialized.Count != roles.Count) { @@ -1109,8 +1117,7 @@ namespace AyaNova.Biz ((ILogger)AyaNova.Util.ApplicationLogging.CreateLogger("BizRoles.cs")).LogWarning("BizRoles::Constructor - roles were modified from last snapshot for client!!!"); } } - - */ +*/ #endif diff --git a/server/AyaNova/biz/IntegrationBiz.cs b/server/AyaNova/biz/IntegrationBiz.cs index aa580d6f..91107f24 100644 --- a/server/AyaNova/biz/IntegrationBiz.cs +++ b/server/AyaNova/biz/IntegrationBiz.cs @@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore; using AyaNova.Util; using AyaNova.Api.ControllerHelpers; using AyaNova.Models; +using System.Linq; namespace AyaNova.Biz { @@ -39,6 +40,20 @@ namespace AyaNova.Biz return await ct.Integration.AnyAsync(z => z.Id == id); } + internal async Task ExistsByIntegrationAppIdAsync(Guid IntegrationAppId) + { + return await ct.Integration.AnyAsync(z => z.IntegrationAppId == IntegrationAppId); + } + + + /////////////////////////////////////////////////////// + //APPID FROM dbID + internal async Task AppIdFromDbIdAsync(long id) + { + return await ct.Integration.AsNoTracking().Where(z => z.Id == id).Select(z => z.IntegrationAppId).SingleOrDefaultAsync(); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// //CREATE // @@ -49,10 +64,10 @@ namespace AyaNova.Biz return null; else { - + await ct.Integration.AddAsync(newObject); await ct.SaveChangesAsync(); - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct); return newObject; } } @@ -60,12 +75,19 @@ namespace AyaNova.Biz //////////////////////////////////////////////////////////////////////////////////////////////// //GET - // - internal async Task GetAsync(Guid IntegrationAppId, bool logTheGetEvent = true, bool populatePartNames = false) + // + + internal async Task GetAsync(long id, bool logTheGetEvent = true) + { + return await GetAsync(await AppIdFromDbIdAsync(id), logTheGetEvent); + } + + + internal async Task GetAsync(Guid IntegrationAppId, bool logTheGetEvent = true) { var ret = await ct.Integration.AsNoTracking().Include(z => z.Items).SingleOrDefaultAsync(m => m.IntegrationAppId == IntegrationAppId); if (logTheGetEvent && ret != null) - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, ret.Id, BizType, AyaEvent.Retrieved), ct); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, ret.Id, BizType, AyaEvent.Retrieved), ct); return ret; } @@ -89,7 +111,7 @@ namespace AyaNova.Biz return null; } - + await ValidateAsync(putObject, dbObject); if (HasErrors) return null; ct.Replace(dbObject, putObject); @@ -106,14 +128,20 @@ namespace AyaNova.Biz return null; } await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct); - - + + return putObject; } //////////////////////////////////////////////////////////////////////////////////////////////// //DELETE // + + internal async Task DeleteAsync(long id) + { + return await DeleteAsync(await AppIdFromDbIdAsync(id)); + } + internal async Task DeleteAsync(Guid IntegrationAppId) { using (var transaction = await ct.Database.BeginTransactionAsync()) @@ -127,7 +155,7 @@ namespace AyaNova.Biz ValidateCanDelete(dbObject); if (HasErrors) return false; - + ct.Integration.Remove(dbObject); await ct.SaveChangesAsync(); @@ -141,7 +169,7 @@ namespace AyaNova.Biz - + //////////////////////////////////////////////////////////////////////////////////////////////// //VALIDATION @@ -166,11 +194,11 @@ namespace AyaNova.Biz } } - //Name required + //Name required if (proposedObj.IntegrationAppId == Guid.Empty) AddError(ApiErrorCode.VALIDATION_REQUIRED, "IntegrationAppId"); - //If name is otherwise OK, check that name is unique + //If name is otherwise OK, check that name is unique if (!PropertyHasErrors("IntegrationAppId")) { //Use Any command is efficient way to check existance, it doesn't return the record, just a true or false @@ -178,7 +206,7 @@ namespace AyaNova.Biz { AddError(ApiErrorCode.VALIDATION_NOT_UNIQUE, "IntegrationAppId"); } - } + } } @@ -188,7 +216,7 @@ namespace AyaNova.Biz } - + ///////////////////////////////////////////////////////////////////// diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs index 7672b9bb..52f81d4b 100644 --- a/server/AyaNova/util/AySchema.cs +++ b/server/AyaNova/util/AySchema.cs @@ -22,7 +22,7 @@ namespace AyaNova.Util //!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImportingAsync WHEN NEW TABLES ADDED!!!! private const int DESIRED_SCHEMA_LEVEL = 4; - internal const long EXPECTED_COLUMN_COUNT = 1375; + internal const long EXPECTED_COLUMN_COUNT = 1376; internal const long EXPECTED_INDEX_COUNT = 161; internal const long EXPECTED_CHECK_CONSTRAINTS = 561; internal const long EXPECTED_FOREIGN_KEY_CONSTRAINTS = 204; @@ -31,7 +31,7 @@ namespace AyaNova.Util //!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImportingAsync WHEN NEW TABLES ADDED!!!! - ///////////////////////////////////////// C1375:I161:CC561:FC204:V11:R2 + ///////////////////////////////////////// (C1376:I161:CC561:FC204:V11:R2) /* @@ -1339,7 +1339,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); //INTEGRATIONITEM await ExecQueryAsync("CREATE TABLE aintegrationitem (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, integrationid BIGINT NOT NULL REFERENCES aintegration ON DELETE CASCADE, " - + "atype INTEGER NOT NULL, objectid BIGINT NOT NULL, integrationitemid TEXT NOT NULL, lastsync TIMESTAMPTZ, integrationitemdata TEXT " + + "atype INTEGER NOT NULL, objectid BIGINT NOT NULL, integrationitemid TEXT NOT NULL, integrationitemname TEXT, lastsync TIMESTAMPTZ, integrationitemdata TEXT " + ")"); //INTEGRATIONLOG