using System; using System.Collections.Generic; using System.Threading.Tasks; using LCU.API.Collections.RepoApi.Configuration; using LCU.API.Collections.RepoApi.Exceptions; using LCU.API.Collections.RepoApi.Extensions; using LCU.API.Collections.RepoApi.Models; using LCU.API.Collections.RepoApi.Models.Filters; using LCU.API.Collections.RepoApi.Models.Requests; using LCU.API.Collections.RepoApi.Models.Responses; using LCU.API.Collections.RepoApi.Services; using LCU.Shared.Collections.RepoApiLib.Exceptions; using LCU.Shared.Collections.RepoApiLib.Models; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.FeatureManagement.Mvc; using Serilog; namespace LCU.API.Collections.RepoApi.Controllers { [Route("api/[controller]")] [ApiController] [FeatureGate(FeatureFlags.EnableControllers)] public class RepoAccountController : RepoControllerBase { private readonly IRepoAccountService _repoAccountService; private readonly IRepoLetterService _repoLetterService; private readonly IRepoStatusChangeService _repoStatusChangeService; public RepoAccountController( IRepoAccountService repoAccountService, IRepoLetterService repoLetterService, IRepoStatusChangeService repoStatusChangeService, IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor) { _repoAccountService = repoAccountService; _repoLetterService = repoLetterService; _repoStatusChangeService = repoStatusChangeService; } // GET: api/RepoAccount [HttpGet(Name = "GetAllRepoAccounts")] [ProducesResponseType(typeof(PagedResponse), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(500)] public async Task Get([FromQuery] PageFilter filter) { try { var searchResult = await _repoAccountService.ListAll(filter); var result = new PagedResponse(searchResult, filter, this.Url, Request); return Ok(result); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name} at {GetInvokerAsyncMethodName()}"); return StatusCode(StatusCodes.Status500InternalServerError); } } // GET: api/RepoAccount/5 [HttpGet("{id}", Name = "GetRepoAccountById")] [ProducesResponseType(typeof(RepoAccount), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(500)] public async Task GetById(int id) { try { if (id <= 0) { return BadRequest("Invalid ID"); } var result = await _repoAccountService.Get(id); return Ok(result); } catch (NotFoundException nfe) { return NotFound(nfe.Message); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name} at {GetInvokerAsyncMethodName()}"); return StatusCode(StatusCodes.Status500InternalServerError); } } // GET: api/RepoAccount/5/statusChanges [HttpGet("{id}/statusChanges", Name = "GetRepoAccountStatusChanges")] [ProducesResponseType(typeof(RepoStatusChange), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(500)] public async Task GetStatusChangesByRepoId(int id) { try { if (id <= 0) { return BadRequest("Invalid ID"); } var result = await _repoStatusChangeService.ListByAccount(id); return Ok(result); } catch (NotFoundException nfe) { return NotFound(nfe.Message); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name} at {GetInvokerAsyncMethodName()}"); return StatusCode(StatusCodes.Status500InternalServerError); } } // GET: api/RepoAccount/5/repoLetters [HttpGet("{id}/repoLetters", Name = "GetLettersByRepoId")] [ProducesResponseType(typeof(RepoLetter), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(500)] public async Task GetLettersByRepoId(int id) { try { if (id <= 0) { return BadRequest("Invalid ID"); } var result = await _repoLetterService.ListByAccountIdAsync(id); return Ok(result); } catch (NotFoundException nfe) { return NotFound(nfe.Message); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name} at {GetInvokerAsyncMethodName()}"); return StatusCode(StatusCodes.Status500InternalServerError); } } // GET: api/RepoAccount/Search/searchPhrase [HttpGet("Search/{searchPhrase}", Name = "SearchRepoAccounts")] [ProducesResponseType(typeof(RepoAccount), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(500)] public async Task SearchRepoAccounts(string searchPhrase) { var maxResults = 100; try { if (string.IsNullOrWhiteSpace(searchPhrase)) { return BadRequest("Search Phrase Cannot Be Empty"); } if (searchPhrase.Trim().Length < 3) { return BadRequest("Search Phrase Must Be At Least Three (3) Characters Long"); } var result = await _repoAccountService.SearchRepoAccounts(searchPhrase, maxResults); return Ok(result); } catch (MaxItemException ex) { return StatusCode(StatusCodes.Status413PayloadTooLarge, $"Too Many Search Results. (Max: {maxResults}) (Found: {ex.ItemCount})"); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name} at {GetInvokerAsyncMethodName()}"); return StatusCode(StatusCodes.Status500InternalServerError); } } // GET: api/RepoAccount/AccountNo/5 [HttpGet("AccountNo/{accountNo}", Name = "GetRepoAccountByAccountNo")] [ProducesResponseType(typeof(RepoAccount), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(500)] public async Task GetByAccountNo(string accountNo) { try { if (string.IsNullOrWhiteSpace(accountNo)) { return BadRequest("Invalid ID"); } var result = await _repoAccountService.GetByAccountNo(accountNo); return Ok(result); } catch (NotFoundException nfe) { return NotFound(nfe.Message); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name} at {GetInvokerAsyncMethodName()}"); return StatusCode(StatusCodes.Status500InternalServerError); } } // POST: api/RepoAccount [HttpPost] [ProducesResponseType(typeof(RepoAccount), 201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task Post([FromBody] RepoAccount repoAccount) { try { if (!ModelState.IsValid) { return BadRequest(ModelState.GetErrorMessages()); } var result = await _repoAccountService.SaveAsync(repoAccount); return Ok(result); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name} at {GetInvokerAsyncMethodName()}"); return StatusCode(StatusCodes.Status500InternalServerError); } } // PUT: api/RepoAccount/5 [HttpPut("{id}")] [ProducesResponseType(typeof(RepoAccount), 200)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] public async Task Put(int id, [FromBody] RepoAccount repoAccount) { try { if (id <= 0 || id != repoAccount.RepoId) { return BadRequest("Invalid ID"); } if (!ModelState.IsValid) { return BadRequest(ModelState); } var currentUser = CreateUserFromAuth(); var result = await _repoAccountService.UpdateAsync(repoAccount, currentUser); return Ok(result); } catch (MaxItemException mie) { return BadRequest(mie.Message); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name} at {GetInvokerAsyncMethodName()}"); return StatusCode(StatusCodes.Status500InternalServerError); } } // PUT: api/RepoAccount/Insecure/5 [HttpPut("Insecure/{id}", Name = "Update Account Insecure Batch")] [ProducesResponseType(typeof(RepoAccount), 200)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task PutBatch(int id, [FromBody] RepoAccount repoAccount) { try { if (id <= 0 || id != repoAccount.RepoId) { return BadRequest("Invalid ID"); } if (!ModelState.IsValid) { return BadRequest(ModelState); } var currentUser = new AppUser() { FirstName = "System", LastName = "User" }; var result = await _repoAccountService.UpdateAsync(repoAccount, currentUser); return Ok(result); } catch (MaxItemException mie) { return BadRequest(mie.Message); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name} at {GetInvokerAsyncMethodName()}"); return StatusCode(StatusCodes.Status500InternalServerError); } } // POST: api/Filter [HttpPost("Filter")] [ProducesResponseType(typeof(PagedResponse), 201)] [ProducesResponseType(typeof(List), 400)] [ProducesResponseType(500)] public async Task Filter([FromQuery] PageFilter pageFilter, [FromBody] RepoAccountPostFilter repoAccountFilter) { try { var searchResult = await _repoAccountService.ListAll(pageFilter, repoAccountFilter); var result = new PagedResponse(searchResult, pageFilter, this.Url, Request, "Filter"); return Ok(result); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name} at {GetInvokerAsyncMethodName()}"); return StatusCode(StatusCodes.Status500InternalServerError); } } [HttpDelete("Delete/{AccountId}")] [ProducesResponseType(200)] [ProducesResponseType(500)] [ProducesResponseType(400)] public async Task DeleteAccountById([FromRoute] int accountId) { try { await _repoAccountService.DeleteAsync(accountId); }catch(Exception ex) { Log.Error(ex, $"Failure in {GetType().Name} at {GetInvokerAsyncMethodName()}"); return StatusCode(StatusCodes.Status500InternalServerError); } return Ok($"Delete of Account with Id: {accountId} Successful"); } } }