diff --git a/server/AyaNova/Controllers/WorkOrderItemPriorityController.cs b/server/AyaNova/Controllers/WorkOrderItemPriorityController.cs new file mode 100644 index 00000000..be5de3d2 --- /dev/null +++ b/server/AyaNova/Controllers/WorkOrderItemPriorityController.cs @@ -0,0 +1,175 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Routing; +using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.Logging; +using AyaNova.Models; +using AyaNova.Api.ControllerHelpers; +using AyaNova.Biz; +using Microsoft.EntityFrameworkCore; +using System.Linq; +using EnumsNET; + +namespace AyaNova.Api.Controllers +{ + [ApiController] + [ApiVersion("8.0")] + [Route("api/v{version:apiVersion}/work-order-item-priority")] + [Produces("application/json")] + [Authorize] + public class WorkOrderItemPriorityController : ControllerBase + { + private readonly AyContext ct; + private readonly ILogger log; + private readonly ApiServerState serverState; + + /// + /// ctor + /// + /// + /// + /// + public WorkOrderItemPriorityController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) + { + ct = dbcontext; + log = logger; + serverState = apiServerState; + } + + /// + /// Create WorkOrderItemPriority + /// + /// + /// From route path + /// + [HttpPost] + public async Task PostWorkOrderItemPriority([FromBody] WorkOrderItemPriority newObject, ApiVersion apiVersion) + { + if (!serverState.IsOpen) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + WorkOrderItemPriorityBiz biz = WorkOrderItemPriorityBiz.GetBiz(ct, HttpContext); + if (!Authorized.HasCreateRole(HttpContext.Items, biz.BizType)) + return StatusCode(403, new ApiNotAuthorizedResponse()); + if (!ModelState.IsValid) + return BadRequest(new ApiErrorResponse(ModelState)); + WorkOrderItemPriority o = await biz.CreateAsync(newObject); + if (o == null) + return BadRequest(new ApiErrorResponse(biz.Errors)); + else + return CreatedAtAction(nameof(WorkOrderItemPriorityController.GetWorkOrderItemPriority), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o)); + } + + /// + /// Duplicate WorkOrderItemPriority + /// + /// + /// Source object id + /// From route path + /// WorkOrderItemPriority + [HttpPost("duplicate/{id}")] + public async Task DuplicateWorkOrderItemPriority([FromRoute] long id, ApiVersion apiVersion) + { + if (!serverState.IsOpen) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + WorkOrderItemPriorityBiz biz = WorkOrderItemPriorityBiz.GetBiz(ct, HttpContext); + if (!Authorized.HasCreateRole(HttpContext.Items, biz.BizType)) + return StatusCode(403, new ApiNotAuthorizedResponse()); + if (!ModelState.IsValid) + return BadRequest(new ApiErrorResponse(ModelState)); + WorkOrderItemPriority o = await biz.DuplicateAsync(id); + if (o == null) + return BadRequest(new ApiErrorResponse(biz.Errors)); + else + return CreatedAtAction(nameof(WorkOrderItemPriorityController.GetWorkOrderItemPriority), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o)); + } + + /// + /// Get WorkOrderItemPriority + /// + /// + /// WorkOrderItemPriority + [HttpGet("{id}")] + public async Task GetWorkOrderItemPriority([FromRoute] long id) + { + if (!serverState.IsOpen) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + WorkOrderItemPriorityBiz biz = WorkOrderItemPriorityBiz.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); + if (o == null) return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); + return Ok(ApiOkResponse.Response(o)); + } + + /// + /// Update WorkOrderItemPriority + /// + /// + /// + [HttpPut] + public async Task PutWorkOrderItemPriority([FromBody] WorkOrderItemPriority updatedObject) + { + if (!serverState.IsOpen) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + if (!ModelState.IsValid) + return BadRequest(new ApiErrorResponse(ModelState)); + WorkOrderItemPriorityBiz biz = WorkOrderItemPriorityBiz.GetBiz(ct, HttpContext); + if (!Authorized.HasModifyRole(HttpContext.Items, biz.BizType)) + return StatusCode(403, new ApiNotAuthorizedResponse()); + var o = await biz.PutAsync(updatedObject);//In future may need to return entire object, for now just concurrency token + if (o == null) + { + if (biz.Errors.Exists(z => z.Code == ApiErrorCode.CONCURRENCY_CONFLICT)) + return StatusCode(409, new ApiErrorResponse(biz.Errors)); + else + return BadRequest(new ApiErrorResponse(biz.Errors)); + } + return Ok(ApiOkResponse.Response(new { Concurrency = o.Concurrency })); ; + } + + /// + /// Delete WorkOrderItemPriority + /// + /// + /// NoContent + [HttpDelete("{id}")] + public async Task DeleteWorkOrderItemPriority([FromRoute] long id) + { + if (!serverState.IsOpen) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + if (!ModelState.IsValid) + return BadRequest(new ApiErrorResponse(ModelState)); + WorkOrderItemPriorityBiz biz = WorkOrderItemPriorityBiz.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(); + } + + + + /// + /// Get Priority list + /// + /// List in alphabetical order of all WorkOrderItem priority items + [HttpGet("list")] + public async Task PriorityList() + { + if (!serverState.IsOpen) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + if (!Authorized.HasSelectRole(HttpContext.Items, AyaType.WorkOrderItemPriority)) + return StatusCode(403, new ApiNotAuthorizedResponse()); + var allStates = await ct.WorkOrderItemPriority.AsNoTracking().OrderBy(z => z.Name).ToListAsync(); + + return Ok(ApiOkResponse.Response(allStates)); + } + + //------------ + + + }//eoc +}//eons \ No newline at end of file diff --git a/server/AyaNova/DataList/WorkOrderItemPriorityDataList.cs b/server/AyaNova/DataList/WorkOrderItemPriorityDataList.cs new file mode 100644 index 00000000..e8a32e85 --- /dev/null +++ b/server/AyaNova/DataList/WorkOrderItemPriorityDataList.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using AyaNova.Biz; +namespace AyaNova.DataList +{ + internal class WorkOrderItemPriorityDataList : DataListProcessingBase + { + public WorkOrderItemPriorityDataList() + { + DefaultListAType = AyaType.WorkOrderItemPriority; + SQLFrom = "from aworkorderitempriority"; + var RoleSet = BizRoles.GetRoleSet(DefaultListAType); + AllowedRoles = RoleSet.ReadFullRecord | RoleSet.Change; + DefaultColumns = new List() { "WorkOrderItemPriorityName", "Active" }; + DefaultSortBy = new Dictionary() { { "WorkOrderItemPriorityName", "+" } }; + FieldDefinitions = new List(); + + FieldDefinitions.Add(new DataListFieldDefinition + { + TKey = "WorkOrderItemPriorityName", + FieldKey = "WorkOrderItemPriorityName", + AType = (int)AyaType.WorkOrderItemPriority, + UiFieldDataType = (int)UiFieldDataType.Text, + SqlIdColumnName = "aworkorderstatus.id", + SqlValueColumnName = "aworkorderstatus.name", + SqlColorColumnName = "aworkorderstatus.color", + IsRowId = true + }); + + + FieldDefinitions.Add(new DataListFieldDefinition + { + TKey = "Active", + FieldKey = "Active", + UiFieldDataType = (int)UiFieldDataType.Bool, + SqlValueColumnName = "aworkorderstatus.active" + }); + + + + + } + }//eoc +}//eons \ No newline at end of file diff --git a/server/AyaNova/DataList/WorkOrderItemStatusDataList.cs b/server/AyaNova/DataList/WorkOrderItemStatusDataList.cs index f90e918e..8eb77a18 100644 --- a/server/AyaNova/DataList/WorkOrderItemStatusDataList.cs +++ b/server/AyaNova/DataList/WorkOrderItemStatusDataList.cs @@ -7,7 +7,7 @@ namespace AyaNova.DataList public WorkOrderItemStatusDataList() { DefaultListAType = AyaType.WorkOrderItemStatus; - SQLFrom = "from aworkorderstatus"; + SQLFrom = "from aworkorderitemstatus"; var RoleSet = BizRoles.GetRoleSet(DefaultListAType); AllowedRoles = RoleSet.ReadFullRecord | RoleSet.Change; DefaultColumns = new List() { "WorkOrderItemStatusName", "WorkOrderItemStatusNotes", "Active" }; @@ -42,21 +42,7 @@ namespace AyaNova.DataList SqlValueColumnName = "aworkorderstatus.active" }); - FieldDefinitions.Add(new DataListFieldDefinition - { - TKey = "WorkOrderItemStatusCompleted", - FieldKey = "WorkOrderItemStatusCompleted", - UiFieldDataType = (int)UiFieldDataType.Bool, - SqlValueColumnName = "aworkorderstatus.completed" - }); - - FieldDefinitions.Add(new DataListFieldDefinition - { - TKey = "WorkOrderItemStatusLocked", - FieldKey = "WorkOrderItemStatusLocked", - UiFieldDataType = (int)UiFieldDataType.Bool, - SqlValueColumnName = "aworkorderstatus.locked" - }); + } diff --git a/server/AyaNova/biz/WorkOrderItemPriorityBiz.cs b/server/AyaNova/biz/WorkOrderItemPriorityBiz.cs new file mode 100644 index 00000000..23033103 --- /dev/null +++ b/server/AyaNova/biz/WorkOrderItemPriorityBiz.cs @@ -0,0 +1,249 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using AyaNova.Util; +using AyaNova.Api.ControllerHelpers; +using AyaNova.Models; + +namespace AyaNova.Biz +{ + internal class WorkOrderItemPriorityBiz : BizObject, ISearchAbleObject + { + internal WorkOrderItemPriorityBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles) + { + ct = dbcontext; + UserId = currentUserId; + UserTranslationId = userTranslationId; + CurrentUserRoles = UserRoles; + BizType = AyaType.WorkOrderItemPriority; + } + + internal static WorkOrderItemPriorityBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext = null) + { + if (httpContext != null) + return new WorkOrderItemPriorityBiz(ct, UserIdFromContext.Id(httpContext.Items), UserTranslationIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items)); + else + return new WorkOrderItemPriorityBiz(ct, 1, ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID, AuthorizationRoles.BizAdminFull); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //EXISTS + internal async Task ExistsAsync(long id) + { + return await ct.WorkOrderItemPriority.AnyAsync(z => z.Id == id); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //CREATE + // + internal async Task CreateAsync(WorkOrderItemPriority newObject) + { + await ValidateAsync(newObject, null); + if (HasErrors) + return null; + else + { + await ct.WorkOrderItemPriority.AddAsync(newObject); + await ct.SaveChangesAsync(); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct); + await SearchIndexAsync(newObject, true); + return newObject; + } + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //DUPLICATE + // + internal async Task DuplicateAsync(long id) + { + var dbObject = await GetAsync(id, false); + if (dbObject == null) + { + AddError(ApiErrorCode.NOT_FOUND, "id"); + return null; + } + WorkOrderItemPriority newObject = new WorkOrderItemPriority(); + CopyObject.Copy(dbObject, newObject); + string newUniqueName = string.Empty; + bool NotUnique = true; + long l = 1; + do + { + newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObject.Name, l++, 255); + NotUnique = await ct.WorkOrderItemPriority.AnyAsync(m => m.Name == newUniqueName); + } while (NotUnique); + newObject.Name = newUniqueName; + newObject.Id = 0; + newObject.Concurrency = 0; + await ct.WorkOrderItemPriority.AddAsync(newObject); + await ct.SaveChangesAsync(); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct); + await SearchIndexAsync(newObject, true); + return newObject; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //GET + // + internal async Task GetAsync(long id, bool logTheGetEvent = true) + { + var ret = await ct.WorkOrderItemPriority.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id); + if (logTheGetEvent && ret != null) + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, id, BizType, AyaEvent.Retrieved), ct); + return ret; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //UPDATE + // + internal async Task PutAsync(WorkOrderItemPriority putObject) + { + var dbObject = await GetAsync(putObject.Id, false); + if (dbObject == null) + { + AddError(ApiErrorCode.NOT_FOUND, "id"); + return null; + } + if (dbObject.Concurrency != putObject.Concurrency) + { + AddError(ApiErrorCode.CONCURRENCY_CONFLICT); + return null; + } + + + await ValidateAsync(putObject, dbObject); + if (HasErrors) return null; + ct.Replace(dbObject, putObject); + try + { + await ct.SaveChangesAsync(); + } + catch (DbUpdateConcurrencyException) + { + if (!await ExistsAsync(putObject.Id)) + AddError(ApiErrorCode.NOT_FOUND); + else + AddError(ApiErrorCode.CONCURRENCY_CONFLICT); + return null; + } + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct); + await SearchIndexAsync(putObject, false); + return putObject; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //DELETE + // + internal async Task DeleteAsync(long id) + { + using (var transaction = await ct.Database.BeginTransactionAsync()) + { + try + { + var dbObject = await GetAsync(id, false); + if (dbObject == null) + { + AddError(ApiErrorCode.NOT_FOUND); + return false; + } + await ValidateCanDeleteAsync(dbObject); + if (HasErrors) + return false; + ct.WorkOrderItemPriority.Remove(dbObject); + await ct.SaveChangesAsync(); + + //Log event + await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + await transaction.CommitAsync(); + } + catch + { + //Just re-throw for now, let exception handler deal, but in future may want to deal with this more here + throw; + } + return true; + } + } + + + + //////////////////////////////////////////////////////////////////////////////////////////////// + //SEARCH + // + private async Task SearchIndexAsync(WorkOrderItemPriority obj, bool isNew) + { + var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, BizType); + DigestSearchText(obj, SearchParams); + if (isNew) + await Search.ProcessNewObjectKeywordsAsync(SearchParams); + else + await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams); + } + + public async Task GetSearchResultSummary(long id) + { + var obj = await GetAsync(id, false); + var SearchParams = new Search.SearchIndexProcessObjectParameters(); + DigestSearchText(obj, SearchParams); + return SearchParams; + } + + public void DigestSearchText(WorkOrderItemPriority obj, Search.SearchIndexProcessObjectParameters searchParams) + { + if (obj != null) + searchParams.AddText(obj.Name); + } + + + + //////////////////////////////////////////////////////////////////////////////////////////////// + //VALIDATION + // + + private async Task ValidateAsync(WorkOrderItemPriority proposedObj, WorkOrderItemPriority currentObj) + { + + bool isNew = currentObj == null; + + //Name required + if (string.IsNullOrWhiteSpace(proposedObj.Name)) + AddError(ApiErrorCode.VALIDATION_REQUIRED, "Name"); + + + + //If name is otherwise OK, check that name is unique + if (!PropertyHasErrors("Name")) + { + //Use Any command is efficient way to check existance, it doesn't return the record, just a true or false + if (await ct.WorkOrderItemPriority.AnyAsync(m => m.Name == proposedObj.Name && m.Id != proposedObj.Id)) + { + AddError(ApiErrorCode.VALIDATION_NOT_UNIQUE, "Name"); + } + } + + } + + private async Task ValidateCanDeleteAsync(WorkOrderItemPriority inObj) + { + //MIGRATE_OUTSTANDING - check workorder records once wo is coded here + await Task.CompletedTask; + //Referential integrity + //FOREIGN KEY CHECKS + if (await ct.WorkOrderItem.AnyAsync(m => m.WorkorderItemPriorityId == inObj.Id)) + AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("WorkOrderItem")); + } + + + + + + + + ///////////////////////////////////////////////////////////////////// + + }//eoc + + +}//eons +