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 { [ApiController] [ApiVersion("8.0")] [Route("api/v{version:apiVersion}/workorders")] [Produces("application/json")] [Authorize] public class WorkOrderController : ControllerBase { private readonly AyContext ct; private readonly ILogger log; private readonly ApiServerState serverState; /// /// ctor /// /// /// /// public WorkOrderController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) { ct = dbcontext; log = logger; serverState = apiServerState; } #region WorkOrder top level routes /// /// Create WorkOrder "header" /// /// WorkOrder top level only, no descendents are evaluated /// From route path /// WorkOrder "header" object [HttpPost] public async Task PostWorkOrder([FromBody] WorkOrder newObject, ApiVersion apiVersion) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); WorkOrderBiz biz = WorkOrderBiz.GetBiz(ct, HttpContext); if (!Authorized.HasCreateRole(HttpContext.Items, biz.BizType)) return StatusCode(403, new ApiNotAuthorizedResponse()); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); WorkOrder o = await biz.CreateAsync(newObject); if (o == null) return BadRequest(new ApiErrorResponse(biz.Errors)); else return CreatedAtAction(nameof(WorkOrderController.GetWorkOrder), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o)); } /// /// Duplicate WorkOrder /// (Wiki and Attachments are not duplicated) /// /// Source object id /// From route path /// Full WorkOrder object including all descendents [HttpPost("duplicate/{id}")] public async Task DuplicateWorkOrder([FromRoute] long id, ApiVersion apiVersion) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); WorkOrderBiz biz = WorkOrderBiz.GetBiz(ct, HttpContext); if (!Authorized.HasCreateRole(HttpContext.Items, biz.BizType)) return StatusCode(403, new ApiNotAuthorizedResponse()); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); WorkOrder o = await biz.DuplicateAsync(id); if (o == null) return BadRequest(new ApiErrorResponse(biz.Errors)); else return CreatedAtAction(nameof(WorkOrderController.GetWorkOrder), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o)); } /// /// Get full WorkOrder object /// /// /// Entire WorkOrder object including all descendents [HttpGet("{id}")] public async Task GetWorkOrder([FromRoute] long id) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); WorkOrderBiz biz = WorkOrderBiz.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, !Authorized.HasModifyRole(HttpContext.Items, biz.BizType))); } /// /// Put (update) WorkOrder /// This route does not evaluate nor update nor return the entire WorkOrder object graph /// only the "header" or top level /// Descendent objects must be updated via their individual routes seperately /// /// WorkOrder id /// WorkOrder top level only, no descendents are evaluated /// New concurrency token [HttpPut("{id}")] public async Task PutWorkOrder([FromRoute] long id, [FromBody] WorkOrder updatedObject) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); WorkOrderBiz biz = WorkOrderBiz.GetBiz(ct, HttpContext); if (!Authorized.HasModifyRole(HttpContext.Items, biz.BizType)) return StatusCode(403, new ApiNotAuthorizedResponse()); var o = await biz.PutAsync(id, updatedObject); if (o == null) { if (biz.Errors.Exists(m => m.Code == ApiErrorCode.CONCURRENCY_CONFLICT)) return StatusCode(409, new ApiErrorResponse(biz.Errors)); else return BadRequest(new ApiErrorResponse(biz.Errors)); } return Ok(ApiOkResponse.Response(new { ConcurrencyToken = o.ConcurrencyToken }, true)); } //TODO: will need to traverse, don't need it now for PROPOSAL testing so not coding it yet // /// // /// Delete WorkOrder // /// // /// // /// Ok // [HttpDelete("{id}")] // public async Task DeleteWorkOrder([FromRoute] long id) // { // if (!serverState.IsOpen) // return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); // if (!ModelState.IsValid) // return BadRequest(new ApiErrorResponse(ModelState)); // //Instantiate the business object handler // WorkOrderBiz biz = WorkOrderBiz.GetBiz(ct, HttpContext); // var o = await biz.GetAsync(id, false); // if (o == null) // return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); // if (!Authorized.HasDeleteRole(HttpContext.Items, biz.BizType)) // return StatusCode(403, new ApiNotAuthorizedResponse()); // if (!await biz.DeleteAsync(o)) // return BadRequest(new ApiErrorResponse(biz.Errors)); // return NoContent(); // } #endregion WorkOrderTopLevel routes #region WorkOrderItem /// /// Create WorkOrderItem /// /// WorkOrderItem level only no descendents /// /// WorkOrderItem object (no descendents) [HttpPost("items")] public async Task PostWorkOrderItem([FromBody] WorkOrderItem newObject, ApiVersion apiVersion) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); WorkOrderBiz biz = WorkOrderBiz.GetBiz(ct, HttpContext); if (!Authorized.HasCreateRole(HttpContext.Items, AyaType.WorkOrderItem)) return StatusCode(403, new ApiNotAuthorizedResponse()); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); WorkOrderItem o = await biz.CreateItemAsync(newObject); if (o == null) return BadRequest(new ApiErrorResponse(biz.Errors)); else return CreatedAtAction(nameof(WorkOrderController.GetWorkOrderItem), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o)); } /// /// Get WorkOrderItem object /// /// /// A single WorkOrderItem [HttpGet("items/{WorkOrderItemId}")] public async Task GetWorkOrderItem([FromRoute] long WorkOrderItemId) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); WorkOrderBiz biz = WorkOrderBiz.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.GetItemAsync(WorkOrderItemId); if (o == null) return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); return Ok(ApiOkResponse.Response(o, !Authorized.HasModifyRole(HttpContext.Items, AyaType.WorkOrderItem))); } // /// // /// Put (update) WorkOrderItem // /// // /// // /// // /// // [HttpPut("items/{WorkOrderItemId}")] // public async Task PutWorkOrderItem([FromRoute] long id, [FromBody] WorkOrderItem updatedObject) // { // if (!serverState.IsOpen) // return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); // if (!ModelState.IsValid) // return BadRequest(new ApiErrorResponse(ModelState)); // //Instantiate the business object handler // WorkOrderBiz biz = WorkOrderBiz.GetBiz(ct, HttpContext); // var o = await biz.GetAsync(id, false); // if (o == null) // return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); // if (!Authorized.HasModifyRole(HttpContext.Items, biz.BizType)) // return StatusCode(403, new ApiNotAuthorizedResponse()); // // try // // { // // if (!await biz.PutAsync(o, updatedObject)) // // 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(ApiOkResponse.Response(new { ConcurrencyToken = o.ConcurrencyToken }, true)); // return StatusCode(501); // } // /// // /// Delete WorkOrderItem // /// // /// // /// Ok-no content // [HttpDelete("items/{WorkOrderItemId}")] // public async Task DeleteWorkOrderItem([FromRoute] long workOrderItemId) // { // //NOTE: we don't need the workorder id in the route because the workorder item must contain the workorder id anyway // //WorkOrder/{woid}/WorkOrderItems <- all workorderitems, post to add new, put to update all as a collection // //WorkOrder/{WorkOrderId}/WorkOrderItems // if (!serverState.IsOpen) // return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); // if (!ModelState.IsValid) // return BadRequest(new ApiErrorResponse(ModelState)); // //Instantiate the business object handler // WorkOrderBiz biz = WorkOrderBiz.GetBiz(ct, HttpContext); // if (!Authorized.HasDeleteRole(HttpContext.Items, biz.BizType)) // return StatusCode(403, new ApiNotAuthorizedResponse()); // //******************************************************************************* // //NOTE: I'm thinking there should be no db access in controller // //let the biz object return not found if necessary // //******************************************************************************* // // var o = await biz.GetAsync(workOrderId, false); // // if (o == null) // // return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); // // //Make sure the item exists first before getting into it // // if (!o.WorkOrderItems.Exists(m => m.Id == workOrderItemId)) // // return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); // //stubbed out for now just to see routes // // if (!await biz.DeleteItemsAsync(o)) // // return BadRequest(new ApiErrorResponse(biz.Errors)); // // return NoContent(); // return StatusCode(501); // } #endregion workorderitem #region WorkOrderItemLabor /// /// Create WorkOrderItemLabor /// /// WorkOrderItemLabor level only no descendents /// /// WorkOrderItemLabor object (no descendents) [HttpPost("items/labors")] public async Task PostWorkOrderItemLabor([FromBody] WorkOrderItemLabor newObject, ApiVersion apiVersion) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); WorkOrderBiz biz = WorkOrderBiz.GetBiz(ct, HttpContext); if (!Authorized.HasCreateRole(HttpContext.Items, AyaType.WorkOrderItemLabor)) return StatusCode(403, new ApiNotAuthorizedResponse()); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); WorkOrderItemLabor o = await biz.CreateLaborAsync(newObject); if (o == null) return BadRequest(new ApiErrorResponse(biz.Errors)); else return CreatedAtAction(nameof(WorkOrderController.GetWorkOrderItemLabor), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o)); } /// /// Get WorkOrderItemLabor object /// /// /// A single WorkOrderItemLabor [HttpGet("items/labors/{WorkOrderItemLaborId}")] public async Task GetWorkOrderItemLabor([FromRoute] long WorkOrderItemLaborId) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); WorkOrderBiz biz = WorkOrderBiz.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.GetLaborAsync(WorkOrderItemLaborId); if (o == null) return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); return Ok(ApiOkResponse.Response(o, !Authorized.HasModifyRole(HttpContext.Items, AyaType.WorkOrderItemLabor))); } #endregion WorkOrderItemLabor #region WorkOrderItemPart /// /// Create WorkOrderItemPart /// /// WorkOrderItemPart level only no descendents /// /// WorkOrderItemPart object (no descendents) [HttpPost("items/parts")] public async Task PostWorkOrderItemPart([FromBody] WorkOrderItemPart newObject, ApiVersion apiVersion) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); WorkOrderBiz biz = WorkOrderBiz.GetBiz(ct, HttpContext); if (!Authorized.HasCreateRole(HttpContext.Items, AyaType.WorkOrderItemPart)) return StatusCode(403, new ApiNotAuthorizedResponse()); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); WorkOrderItemPart o = await biz.CreatePartAsync(newObject); if (o == null) return BadRequest(new ApiErrorResponse(biz.Errors)); else return CreatedAtAction(nameof(WorkOrderController.GetWorkOrderItemPart), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o)); } /// /// Get WorkOrderItemPart object /// /// /// A single WorkOrderItemPart [HttpGet("items/parts/{WorkOrderItemPartId}")] public async Task GetWorkOrderItemPart([FromRoute] long WorkOrderItemPartId) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); WorkOrderBiz biz = WorkOrderBiz.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.GetPartAsync(WorkOrderItemPartId); if (o == null) return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); return Ok(ApiOkResponse.Response(o, !Authorized.HasModifyRole(HttpContext.Items, AyaType.WorkOrderItemPart))); } #endregion WorkOrderItemPart //------------ }//eoc }//eons