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 { /// /// /// [ApiController] [ApiVersion("8.0")] [Route("api/v{version:apiVersion}/[controller]")] [Produces("application/json")] [Authorize] public class FormCustomController : ControllerBase { private readonly AyContext ct; private readonly ILogger log; private readonly ApiServerState serverState; /// /// ctor /// /// /// /// public FormCustomController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) { ct = dbcontext; log = logger; serverState = apiServerState; } /// /// Get form customizations for Client form display /// Returns 304 not modified if concurrency token provided and unchanged /// /// Required roles: /// Any /// /// /// The official form key used by AyaNova /// A prior concurrency token used to check if there are any changes without using up bandwidth sending unnecessary data /// A single FormCustom or nothing and a header 304 not modified [HttpGet("{formkey}")] public async Task GetFormCustom([FromRoute] string formkey, [FromQuery] uint? concurrencyToken) { if (serverState.IsClosed) return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); //Instantiate the business object handler FormCustomBiz biz = FormCustomBiz.GetBiz(ct, HttpContext); //Just have to be authenticated for this one 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(formkey); if (o == null) return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); //If concurrency token specified then check if ours is newer if (concurrencyToken != null) { if (o.ConcurrencyToken == concurrencyToken) { //returns a code 304 (NOT MODIFIED) return StatusCode(304); } } return Ok(ApiOkResponse.Response(o, !Authorized.HasModifyRole(HttpContext.Items, biz.BizType))); } /// /// Get available types allowed for Custom fields /// Used to build UI for customizing a form /// These values are a subset of the AyaDataTypes values /// which can be fetched from the EnumPickList route /// /// Required roles: /// BizAdminFull only has rights to customize forms /// /// /// A list of valid values for custom field types [HttpGet("AvailableCustomTypes")] public ActionResult GetAvailableCustomTypes() { if (serverState.IsClosed) return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); if (!Authorized.HasReadFullRole(HttpContext.Items, AyaType.FormCustom)) return StatusCode(403, new ApiNotAuthorizedResponse()); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); return Ok(ApiOkResponse.Response(CustomFieldType.ValidCustomFieldTypes, true)); } /// /// Get a list of all customizable form keys /// Used to build UI for customizing a form /// /// Required roles: /// BizAdminFull only has rights to customize forms /// /// /// A list of string formKey values valid for customization [HttpGet("AvailableCustomizableFormKeys")] public ActionResult GetAvailableCustomizableFormKeys() { if (serverState.IsClosed) return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); if (!Authorized.HasReadFullRole(HttpContext.Items, AyaType.FormCustom)) return StatusCode(403, new ApiNotAuthorizedResponse()); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); return Ok(ApiOkResponse.Response(AyaObjectFieldDefinitions.AyaObjectFieldDefinitionKeys, true)); } /// /// Put (update) FormCustom /// /// Required roles: BizAdminFull /// /// /// /// /// [HttpPut("{formkey}")] public async Task PutFormCustom([FromRoute] string formkey, [FromBody] FormCustom inObj) { 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 FormCustomBiz biz = FormCustomBiz.GetBiz(ct, HttpContext); var o = await biz.GetNoLogAsync(formkey); if (o == null) return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); if (!Authorized.HasModifyRole(HttpContext.Items, biz.BizType)) return StatusCode(403, new ApiNotAuthorizedResponse()); try { if (!biz.Put(o, inObj)) return BadRequest(new ApiErrorResponse(biz.Errors)); } catch (DbUpdateConcurrencyException) { if (!await biz.ExistsAsync(formkey)) 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)); } // /// // /// Post FormCustom // /// // /// Required roles: BizAdminFull // /// // /// // /// Automatically filled from route path, no need to specify in body // /// // [HttpPost] // public async Task PostFormCustom([FromBody] FormCustom inObj, ApiVersion apiVersion) // { // if (!serverState.IsOpen) // return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); // //Instantiate the business object handler // FormCustomBiz biz = FormCustomBiz.GetBiz(ct, HttpContext); // //check rights // if (!Authorized.HasCreateRole(HttpContext.Items, biz.BizType)) // return StatusCode(403, new ApiNotAuthorizedResponse()); // if (!ModelState.IsValid) // return BadRequest(new ApiErrorResponse(ModelState)); // //Create and validate // FormCustom o = await biz.CreateAsync(inObj); // if (o == null) // return BadRequest(new ApiErrorResponse(biz.Errors)); // else // return CreatedAtAction(nameof(FormCustomController.GetFormCustom), new { formkey = o.FormKey, version = apiVersion.ToString() }, new ApiCreatedResponse(o)); // } //------------ }//eoc }//eons