using Microsoft.AspNetCore.Mvc; using vendorApproverBackend.Entities; using vendorApproverBackend.Services; using vendorApproverBackend.Dtos; using vendorApproverBackend.Requests; using vendorApproverBackend.Enums; using vendorApproverBackend.Responses; using Microsoft.AspNetCore.Authorization; using System.Security.Claims; namespace vendorApproverBackend.Controllers { [ApiController] [Route("api/[controller]")] [Authorize(Roles = "ADMIN,EMPLOYEE,VENDOR,FINANCIAL,RENWE_APPROVER,MANAGER,PERFERMANCE_MANAGER")] public class RequestRenewController : ControllerBase { private readonly RequestRenewService _service; private readonly UserService _userService; public RequestRenewController(RequestRenewService service, UserService userService) { _service = service; _userService = userService; } [HttpPost("vendor-submit-request/{certificateId}")] public async Task Initiate(long certificateId, [FromBody] InitiateRequesRenewtDto dto) { var username = User.FindFirstValue(ClaimTypes.Name); if (string.IsNullOrEmpty(username)) { return Unauthorized("Username claim not found in token."); } var user = await _userService.FindByUsernameAsync(username); try { // Now passing the dto to the service var result = await _service.InitiateRequestRenewAsync(certificateId, dto, user); return Ok(result); } catch (Exception ex) { return StatusCode(500, $"Internal error: {ex.Message}"); } } /* [HttpPost("vendor-submit-request/{certificateId}")] public async Task Initiate(long certificateId) { var username = User.FindFirstValue(ClaimTypes.Name); if (string.IsNullOrEmpty(username)) { return Unauthorized("Username claim not found in token."); } var user = await _userService.FindByUsernameAsync(username); try { var result = await _service.InitiateRequestRenewAsync(certificateId, user); return Ok(result); } catch (Exception ex) { return StatusCode(500, $"Internal error: {ex.Message}"); } } */ [HttpPost("vendor-submit-change-request/{certificateId}")] public async Task InitiateChange(long certificateId, [FromBody] InitiateChangeRequestDto dto) { var username = User.FindFirstValue(ClaimTypes.Name); if (string.IsNullOrEmpty(username)) { return Unauthorized("Username claim not found in token."); } var user = await _userService.FindByUsernameAsync(username); try { var result = await _service.InitiateChangeRequestAsync(certificateId, dto, user); return Ok(result); } catch (Exception ex) { // Log the error as needed return StatusCode(500, $"Internal error: {ex.Message}"); } } [HttpPut("update/{requestId}")] [Consumes("multipart/form-data")] public async Task UpdateRenewRequest(long requestId, [FromForm] RequestRenewForm form) { try { var result = await _service.UpdateAndFinalizeRenewAsync(requestId, form); if (result == null) return NotFound($"RequestRenew with ID {requestId} not found."); return Ok(result); } catch (Exception ex) { return StatusCode(500, $"Internal error: {ex.Message}"); } } /* [HttpPost("add/{certificateId}")] [Consumes("multipart/form-data")] // Tells Swagger this is a file upload form public async Task Add(long certificateId, [FromForm] RequestRenewForm form) { try { var result = await _service.AddRequestRenewAsync( certificateId, form.RenewalDate, form.InspectionRequired, form.Comments, form.SignatureName, form.SignatureData, form.ExpiredFile, form.ExpiredRemark, form.RefOrdersFile, form.RefOrdersRemark, form.ApprovedDesignFile, form.ApprovedDesignRemark, form.UpdateTdsFile, form.UpdateTdsRemark, form.PerformanceLetterFiles, form.IsExpiredOver2Years, form.RequiresFactoryAudit); return Ok(result); } catch (Exception ex) { return StatusCode(500, $"Internal error: {ex.Message}"); } } [HttpPut("update/{renewRequestId}")] [Consumes("multipart/form-data")] public async Task Update(long renewRequestId, [FromForm] RequestRenewForm form) { try { var result = await _service.UpdateRequestRenewAsync( renewRequestId, form.RenewalDate, form.InspectionRequired, form.Comments, form.SignatureName, form.SignatureData, form.ExpiredFile, form.ExpiredRemark, form.RefOrdersFile, form.RefOrdersRemark, form.ApprovedDesignFile, form.ApprovedDesignRemark, form.UpdateTdsFile, form.UpdateTdsRemark, form.PerformanceLetterFiles, form.IsExpiredOver2Years, form.RequiresFactoryAudit ); if (result == null) return NotFound($"RequestRenew with ID {renewRequestId} not found."); return Ok(result); } catch (Exception ex) { return StatusCode(500, $"Internal error: {ex.Message}"); } } */ [HttpGet("get-request-renew-details-by-id/{requestReneweId}")] public async Task GetDetails(long requestReneweId) { var result = await _service.GetRequestRenewDetailsByIdAsync(requestReneweId); if (result == null) return NotFound(new { message = "Renewal request not found" }); return Ok(result); } [HttpPatch("/update-request-renew-step/{renewRequestId}")] public async Task UpdateStep( [FromRoute] long renewRequestId, [FromQuery] RenewalStep renewalStep) { try { var updatedRequest = await _service.UpdateRenewalStepAsync(renewRequestId, renewalStep); if (updatedRequest == null) { return NotFound(new { message = $"RequestRenew with ID {renewRequestId} not found." }); } return Ok(updatedRequest); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } [HttpGet("get-by-id/{id}")] public async Task GetById(long id) { var result = await _service.GetByIdAsync(id); return result != null ? Ok(result) : NotFound(); } [HttpPatch("update-status/{id}")] public async Task UpdateStatus(long id, [FromQuery] RequestRenewStatus status) { var success = await _service.UpdateStatusAsync(id, status); return success ? Ok() : NotFound(); } [HttpGet("certificate-requests/{certificateId}")] public async Task GetByCertificate(long certificateId, [FromQuery] RequestRenewStatus? status) { var list = await _service.GetByCertificateAsync(certificateId, status); return Ok(list); } /* [HttpPost("assign/{renewRequestId}")] public async Task AssignRequest( [FromRoute] long renewRequestId, [FromQuery] string azureEmail, [FromQuery] string azureDisplayedName) { try { var updatedRequest = await _service.AssignRequestRenewAsync(renewRequestId, azureEmail, azureDisplayedName); return Ok(updatedRequest); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } */ [HttpPost("assign-to-performance-evaluator/{renewRequestId}/{userId}")] public async Task AssignToPerformanceEvaluator([FromRoute] long renewRequestId, [FromRoute] long userId) { try { var result = await _service.AssignToPerformanceEvaluatorAsync(renewRequestId, userId); return Ok(result); } catch (KeyNotFoundException ex) { // Returns 404 for "User not found" or "Request not found" return NotFound(new { message = ex.Message }); } catch (InvalidOperationException ex) { // Returns 406 for "User has no type PERFORMANCE_EVALUATOR" return StatusCode(406, new { message = ex.Message }); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } [HttpGet("all")] public async Task>> GetAllRequests( [FromQuery] int page = 0, [FromQuery] int size = 5, [FromQuery] long? certificationId = null, [FromQuery] long? assignedToId = null, [FromQuery] RequestRenewStatus? status = null) { try { var result = await _service.GetAllPagedAsync(page, size, certificationId, assignedToId, status); return Ok(result); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } [HttpPost("add-part2-evaluation/{renewRequestId}")] public async Task UpdatePart2Evaluation( [FromRoute] long renewRequestId, [FromBody] UpdatePart2EvaluationDto dto) { if (dto == null) return BadRequest("Evaluation data is required."); try { var result = await _service.UpdatePart2EvaluationAsync(renewRequestId, dto); if (result == null) return NotFound($"RequestRenew with ID {renewRequestId} not found."); return Ok(result); } catch (Exception ex) { return StatusCode(500, $"Internal server error: {ex.Message}"); } } [HttpPatch("update-part2-evaluation/{evaluationId}")] public async Task PatchPart2Evaluation( [FromRoute] long evaluationId, [FromBody] PatchPart2EvaluationDto dto) { try { var updatedEvaluation = await _service.PatchPart2EvaluationAsync(evaluationId, dto); if (updatedEvaluation == null) return NotFound(new { message = $"Evaluation with ID {evaluationId} not found." }); return Ok(updatedEvaluation); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } [HttpPost("add-part3-decision/{renewRequestId}")] [Consumes("multipart/form-data")] // Explicitly state we expect form data public async Task UpdatePart3Decision( [FromRoute] long renewRequestId, [FromForm] RenewalDecisionRequest requestDto) { try { var updatedRequest = await _service.UpdatePart3DecisionAsync(renewRequestId, requestDto); if (updatedRequest == null) { return NotFound(new { message = $"Renewal Request {renewRequestId} not found." }); } return Ok(updatedRequest); } catch (Exception ex) { return StatusCode(500, new { message = "Error processing decision", details = ex.Message }); } } [HttpPatch("update-part3-decision/{decisionId}")] [Consumes("multipart/form-data")] public async Task PatchPart3Decision( [FromRoute] long decisionId, [FromForm] PatchPart3DecisionDto dto) { try { var updatedDecision = await _service.PatchPart3DecisionAsync(decisionId, dto); if (updatedDecision == null) { return NotFound(new { message = $"Decision record with ID {decisionId} not found." }); } return Ok(updatedDecision); } catch (Exception ex) { return StatusCode(500, new { message = "Error updating decision", details = ex.Message }); } } [HttpPost("add-final-decision/{renewRequestId}")] [Consumes("multipart/form-data")] public async Task UpdateFinalDecision( [FromRoute] long renewRequestId, [FromForm] FinalDecisionRequest requestDto) { try { var updatedRequest = await _service.UpdateFinalDecisionAsync(renewRequestId, requestDto); if (updatedRequest == null) { return NotFound(new { message = $"Renewal Request {renewRequestId} not found." }); } return Ok(updatedRequest); } catch (Exception ex) { return StatusCode(500, new { message = "Error processing final decision", details = ex.Message }); } } [HttpPatch("update-final-decision/{finalDecisionId}")] [Consumes("multipart/form-data")] public async Task PatchFinalDecision( [FromRoute] long finalDecisionId, [FromForm] FinalDecisionRequest dto) { try { // Call the service method you provided var updatedDecision = await _service.PatchFinalDecisionAsync(finalDecisionId, dto); if (updatedDecision == null) { return NotFound(new { message = $"Final Decision record with ID {finalDecisionId} not found." }); } return Ok(updatedDecision); } catch (Exception ex) { return StatusCode(500, new { message = "An error occurred while updating the final decision.", details = ex.Message }); } } // 1. Create Clarification for a Renew Request [HttpPost("add-clarification/{renewRequestId}")] public async Task AddClarification(long renewRequestId, [FromBody] RenewalClarificationRequest dto) { var result = await _service.AddClarificationToRenewAsync(renewRequestId, dto); if (result == null) return NotFound(); return Ok(result); } // 2. Patch Clarification (Vendor Uploads Files here) [HttpPatch("update-clarification/{clarificationId}")] [Consumes("multipart/form-data")] public async Task PatchClarification(long clarificationId, [FromForm] VendorResponseRequest dto) { try { var result = await _service.PatchClarificationAsync(clarificationId, dto); if (result == null) return NotFound(); return Ok(result); } catch (Exception ex) { return StatusCode(500, ex.Message); } } [HttpPost("add-payment/{renewRequestId}")] public async Task AddPayment(long renewRequestId, [FromBody] RenewalPaymentRequest dto) { var result = await _service.AddPaymentToRenewAsync(renewRequestId, dto); if (result == null) return NotFound(new { message = "Renewal Request not found" }); return Ok(result); } // 2. Update a specific payment record by its own ID [HttpPatch("update-payment/{paymentId}")] public async Task PatchPayment(long paymentId, [FromBody] RenewalPaymentRequest dto) { try { var result = await _service.PatchPaymentAsync(paymentId, dto); if (result == null) return NotFound(new { message = "Payment record not found" }); return Ok(result); } catch (Exception ex) { return StatusCode(500, new { error = ex.Message }); } } } }