using LCU.Library.Internal.IncentiveApiModels.Entities; using LCU.Library.Internal.IncentiveApiModels.Common; using LCU.Library.Internal.IncentiveApiModels.Requests; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.FeatureManagement.Mvc; using LCU.API.Internal.Operations.IncentiveApi.Services; using LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer; using LCU.API.Internal.Operations.IncentiveApi.Models.GoalDispersal; using LCU.API.Internal.Operations.IncentiveApi.Authorization; using LCU.API.Internal.Operations.IncentiveApi.Configuration; using LCU.API.Internal.Operations.IncentiveApiLib.Services; using LCU.API.Internal.Operations.IncentiveApiLib.Persistence; namespace LCU.API.Internal.Operations.IncentiveApi.Controllers; [FeatureGate(FeatureFlags.EnableControllers)] [ApiController] [Route("api/[controller]")] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] public class GoalController : ControllerBase { private readonly IGoalService _goalService; private readonly IGoalDispersalService _goalDispersalService; private readonly IUserService _userService; private readonly ICurrentUserService _currentUser; public GoalController(IGoalService goalService, IGoalDispersalService goalDispersalService, ICurrentUserService currentUser, IUserService userService) { _goalService = goalService; _currentUser = currentUser; _userService = userService; _goalDispersalService = goalDispersalService; } [HttpGet("", Name = "GetGoals")] public async Task GetGoals([FromQuery] int fromMonth, [FromQuery] int fromYear, [FromQuery] int toMonth, [FromQuery] int toYear, [FromQuery] int departmentId, [FromQuery] bool includePersonnel = true) { try { var monthRange = new MonthRange(fromYear, fromMonth, toYear, toMonth); var query = new GoalSearchRequest() { DateRange = monthRange, departmentId = departmentId, IncludePersonnel = includePersonnel }; var result = await _goalService.GetGoalsAsync(query); return Ok(result); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name}"); return StatusCode(StatusCodes.Status500InternalServerError); } } [HttpGet("department/", Name = "GetAllDepartmentsGoals")] public async Task GetAllDepartmentsGoals([FromQuery] int year) { try { var searchYear = year > 0 ? year : DateTime.Now.Year; var result = await _goalService.GetAllAnnualDepartmentGoalsAsync(searchYear); return Ok(result); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name}"); return StatusCode(StatusCodes.Status500InternalServerError); } } [HttpGet("department/{departmentId}", Name = "GetDepartmentGoals")] public async Task GetDepartmentGoals(int departmentId, [FromQuery] int year) { try { var searchYear = year > 0 ? year : DateTime.Now.Year; var result = await _goalService.GetAnnualDepartmentGoalsAsync(departmentId, searchYear); return Ok(result); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name}"); return StatusCode(StatusCodes.Status500InternalServerError); } } [HttpGet("personnel/{departmentId}", Name = "GetPersonnelGoals")] public async Task GetPersonnelGoals(int departmentId, [FromQuery] int month, [FromQuery] int year, [FromQuery] bool includeAllPersonnel = false) { try { var searchYear = year > 0 ? year : DateTime.Now.Year; var searchMonth = month > 0 ? month : DateTime.Now.Month; var searchRequest = new DepartmentPersonnelSearchRequest() { DepartmentId = departmentId, Month = searchMonth, Year = searchYear, IncludeAllPersonnel = includeAllPersonnel }; var result = await _goalService.GetMonthlyPersonnelGoalsAsync(searchRequest); return Ok(result); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name}"); return StatusCode(StatusCodes.Status500InternalServerError); } } [HttpPost("personnel/{departmentId}/disperse", Name = "DisperseByExtrapolation")] public async Task GetPersonnelGoals(int departmentId, [FromBody] ExtrapolateGoalDispersalRequest request) { try { var result = await _goalDispersalService.DisperseGoalsByExtrapolatingLastMonth(departmentId, request.Month, request.Year); return Ok(result); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name}"); return StatusCode(StatusCodes.Status500InternalServerError); } } [HttpGet("me", Name = "GetCurrentUserGoals")] [RequirePermission("VIEW_DASHBOARD")] public async Task GetCurrentUserGoals([FromQuery] int fromMonth, [FromQuery] int fromYear, [FromQuery] int toMonth, [FromQuery] int toYear) { try { var monthRange = new MonthRange(fromYear, fromMonth, toYear, toMonth); var appUser = _currentUser.GetCurrentUser(); if (appUser?.Email == null) { return Unauthorized("No AD User Found."); } var employee = await _userService.GetUserByAdEmailAsync(appUser.Email); if (employee == null) { return NoContent(); } var result = await _goalService.GetEmployeeGoalsForMonthRangeAsync(employee, monthRange); return Ok(result); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name}"); return StatusCode(StatusCodes.Status500InternalServerError); } } [HttpGet("me/departments", Name = "GetCurrentUserDepartmentsGoals")] [RequirePermission("VIEW_DASHBOARD,VIEW_PERFORMANCE_FOR_DEPARTMENT")] public async Task GetCurrentUserDepartmentsGoals([FromQuery] int fromMonth, [FromQuery] int fromYear, [FromQuery] int toMonth, [FromQuery] int toYear) { try { var monthRange = new MonthRange(fromYear, fromMonth, toYear, toMonth); var appUser = _currentUser.GetCurrentUser(); if (appUser?.Email == null) { return Unauthorized("No AD User Found."); } var employee = await _userService.GetUserByAdEmailAsync(appUser.Email); if (employee == null) { return NoContent(); } var result = await _goalService.GetEmployeeDepartmentsGoalsForMonthRangeAsync(employee, monthRange); return Ok(result); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name}"); return StatusCode(StatusCodes.Status500InternalServerError); } } [HttpPost] public async Task SetGoalForAudienceAndTimePeriod(GoalChange goalChange) { try { if (!ModelState.IsValid) { return BadRequest(ModelState); } var result = await _goalService.SaveGoalAsync(goalChange); return Created($"{result.Select(x => x.Id)}", result); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name}."); return StatusCode(StatusCodes.Status500InternalServerError); } } [HttpPost("multi")] public async Task SetGoalsForAudienceAndTimePeriod(List goalChanges) { try { if (!ModelState.IsValid) { return BadRequest(ModelState); } var result = await _goalService.SaveGoalRangeAsync(goalChanges); return Created($"{result.Count}", result); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name}."); return StatusCode(StatusCodes.Status500InternalServerError); } } [HttpPost("DisperseAll")] public async Task DisperseAll(GoalDispersalRequest request) { try { await _goalDispersalService.ExecuteMonthStartDispersal(request); return Ok(); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name}."); return StatusCode(StatusCodes.Status500InternalServerError); } } [HttpPost("personnel/CustomWeightedDispersal")] public async Task CustomWeightedDispersal([FromBody] CustomWeightedDispersalRequest request) { try { var result = await _goalDispersalService.CustomWeightedDispersal(request); return Ok(result); } catch (Exception ex) { Log.Error(ex, $"Failure in {GetType().Name}."); return StatusCode(StatusCodes.Status500InternalServerError); } } }