using Microsoft.AspNetCore.Mvc; using vendorApproverBackend.Requests; using vendorApproverBackend.Services; using vendorApproverBackend.Enums; using Microsoft.AspNetCore.Authorization; using System.Security.Claims; using vendorApproverBackend.Interfaces; namespace vendorApproverBackend.Controllers { [ApiController] [Route("api/[controller]")] public class VisitRequestController : ControllerBase { private readonly VisitRequestService _visitRequestService; private readonly ILogger _logger; private readonly UserService _userService; private readonly INotificationService _notificationService; public VisitRequestController(VisitRequestService visitRequestService, ILogger logger, UserService userService, INotificationService notificationService) { _visitRequestService = visitRequestService; _logger = logger; _userService = userService; _notificationService = notificationService; } [HttpPost("add/{prequalificationRequestId}")] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize(Roles = "ADMIN,EMPLOYEE,VENDOR,FINANCIAL,PERFERMANCE_MANAGER")] public async Task AddVisitRequest(long prequalificationRequestId, [FromBody] AddVisitRequest request) { var username = User.FindFirstValue(ClaimTypes.Name); if (string.IsNullOrEmpty(username)) { return Unauthorized("Username claim not found in token."); } var currentUser = await _userService.FindByUsernameAsync(username); if (currentUser == null) { return NotFound(" current User not found."); } if (!ModelState.IsValid) { return BadRequest(ModelState); } try { var newVisitRequest = await _visitRequestService.AddNewVisitRequestAsync(prequalificationRequestId, request, currentUser.Id); return CreatedAtAction(nameof(FindVisitRequestByPrequalificationRequestId), new { prequalificationRequestId = prequalificationRequestId }, newVisitRequest); } catch (Exception ex) when (ex.Message.Contains("not found")) { _logger.LogWarning(ex, "PrequalificationRequest not found for ID: {Id}", prequalificationRequestId); return NotFound($"PrequalificationRequest with ID {prequalificationRequestId} not found."); } catch (InvalidOperationException ex) { _logger.LogError(ex, "Attempted to add a second VisitRequest for PrequalificationRequest ID: {Id}", prequalificationRequestId); return BadRequest(new { error = ex.Message }); } catch (Exception ex) { _logger.LogError(ex, "Error adding VisitRequest for PrequalificationRequest ID: {Id}", prequalificationRequestId); return StatusCode(StatusCodes.Status500InternalServerError, "An unexpected error occurred."); } } [HttpPut("update/{visitRequestId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize(Roles = "ADMIN,EMPLOYEE,VENDOR,FINANCIAL,PERFERMANCE_MANAGER")] public async Task UpdateVisitRequest(long visitRequestId, [FromBody] UpdateVisitRequest request) { if (!ModelState.IsValid) { return BadRequest(ModelState); } try { var updatedVisitRequest = await _visitRequestService.UpdateVisitRequestAsync(visitRequestId, request); if (updatedVisitRequest == null) { _logger.LogWarning("VisitRequest with ID {Id} not found for update.", visitRequestId); return NotFound($"VisitRequest with ID {visitRequestId} not found."); } return Ok(updatedVisitRequest); } catch (Exception ex) { _logger.LogError(ex, "Error updating VisitRequest with ID: {Id}", visitRequestId); return StatusCode(StatusCodes.Status500InternalServerError, "An unexpected error occurred."); } } [HttpGet("get-by-id/{visitRequestId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize(Roles = "ADMIN,EMPLOYEE,VENDOR,FINANCIAL,PERFERMANCE_MANAGER")] public async Task FindVisitRequestById(long visitRequestId) { var visitRequest = await _visitRequestService.FindByIdAsync(visitRequestId); if (visitRequest == null) { return NotFound($"VisitRequest with ID {visitRequestId} not found."); } return Ok(visitRequest); } [HttpGet("get_file_by_id/{prequalificationRequestId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize(Roles = "ADMIN,EMPLOYEE,VENDOR,FINANCIAL,PERFERMANCE_MANAGER")] public async Task FindVisitRequestByPrequalificationRequestId(long prequalificationRequestId) { var visitRequest = await _visitRequestService.FindByPrequalificationRequestIdAsync(prequalificationRequestId); if (visitRequest == null) { return NotFound($"VisitRequest for PrequalificationRequest ID {prequalificationRequestId} not found."); } return Ok(visitRequest); } [HttpPatch("Visit-request-action/{visitRequestId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize(Roles = "ADMIN,EMPLOYEE,VENDOR,FINANCIAL,PERFERMANCE_MANAGER")] public async Task AcceptRejectVisitRequest(long visitRequestId, [FromBody] VisitRequestActionRequest request) { if (!ModelState.IsValid) { return BadRequest(ModelState); } try { var updatedVisitRequest = await _visitRequestService.HandleVisitRequestActionAsync(visitRequestId, request); if (updatedVisitRequest == null) { _logger.LogWarning("VisitRequest with ID {Id} not found for action.", visitRequestId); return NotFound($"VisitRequest with ID {visitRequestId} not found."); } return Ok(updatedVisitRequest); } catch (Exception ex) { _logger.LogError(ex, "Error processing action for VisitRequest ID: {Id}", visitRequestId); return StatusCode(StatusCodes.Status500InternalServerError, new { error = "An unexpected error occurred while processing the request." }); } } [HttpGet("get-all-paginator")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task GetVisitRequests( [FromQuery] int page = 0, [FromQuery] int size = 5, [FromQuery] long? requestId = null, [FromQuery] RequestStatus? status = null) { if (page < 0 || size <= 0) { return BadRequest("Page must be non-negative and Size must be positive."); } var pagedResult = await _visitRequestService.GetVisitRequestsByCriteriaAsync( page, size, requestId, status); return Ok(pagedResult); } } }