using Microsoft.AspNetCore.Mvc; using vendorApproverBackend.Entities; using vendorApproverBackend.Enums; using vendorApproverBackend.Services; using vendorApproverBackend.Requests; using Microsoft.AspNetCore.Authorization; using System.Security.Claims; namespace vendorApproverBackend.Controllers { [ApiController] [Route("api/[controller]")] [Authorize(Roles = "ADMIN,EMPLOYEE,VENDOR,FINANCIAL,MANAGER,PERFERMANCE_MANAGER")] public class VendorRequestLetterController : ControllerBase { private readonly VendorRequestLetterService _service; private readonly UserService _userService; public VendorRequestLetterController(UserService userService, VendorRequestLetterService service) { _service = service; _userService = userService; } [HttpPost("/add-vendor-request-letter")] public async Task Create(VendorRequestLetterCreate dto) { var username = User.FindFirstValue(ClaimTypes.Name); if (string.IsNullOrEmpty(username)) { return Unauthorized("Username claim not found in token."); } var user = await _userService.FindByUsernameWithVendorAsync(username); if (user == null) { return NotFound("User not found."); } Vendor vendor = user.Vendor; if (vendor == null) { return NotFound("current user is not a vendor"); } var result = await _service.AddLetter(dto, vendor.Id, user.Id); return result != null ? Ok(result) : NotFound(); } [HttpPut("/update-vendor-request-letter/{letterId}")] public async Task Update(long letterId, VendorRequestLetter letter) { var result = await _service.UpdateLetter(letterId, letter); return result != null ? Ok(result) : NotFound(); } [HttpPatch("update-letter-status/{letterId}")] public async Task UpdateStatus(long letterId, [FromQuery] LetterRequestStatus status) { var result = await _service.UpdateLetterStatus(letterId, status); return result != null ? Ok(result) : NotFound(); } [HttpDelete("delete-letter/{letterId}")] public async Task Delete(long letterId) { await _service.DeleteLetter(letterId); return NoContent(); } [HttpPatch("toggle-assign-to-manager/{letterId}")] public async Task ToggleManager(long letterId) { var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; if (userIdClaim == null) return Unauthorized(); var result = await _service.ToggleManagerAssignment(letterId, long.Parse(userIdClaim)); return result != null ? Ok(result) : NotFound(); } [HttpGet("get-letter-by-id/{letterId}")] public async Task GetById(long letterId) { var result = await _service.GetById(letterId); return result != null ? Ok(result) : NotFound(); } [HttpGet("all-letters")] public async Task GetAll( [FromQuery] int page = 0, [FromQuery] int size = 5, [FromQuery] long? vendorId = null, [FromQuery] LetterRequestStatus? status = null, [FromQuery] LetterProductStatus? productStatus = null, [FromQuery] bool? assignedToManager = null) { return Ok(await _service.GetAll(page, size, vendorId, status, productStatus, assignedToManager)); } [HttpGet("get-my-letters")] public async Task GetAllMyLetters( [FromQuery] int page = 0, [FromQuery] int size = 5, [FromQuery] LetterRequestStatus? status = null, [FromQuery] LetterProductStatus? productStatus = null, [FromQuery] bool? assignedToManager = null) { var username = User.FindFirstValue(ClaimTypes.Name); if (string.IsNullOrEmpty(username)) { return Unauthorized("Username claim not found in token."); } var user = await _userService.FindByUsernameWithVendorAsync(username); if (user == null) { return NotFound("User not found."); } if (user.Vendor == null) { return NotFound("User is not vendor."); } return Ok(await _service.GetMyLetters(page, size, user.Vendor.Id, status, productStatus, assignedToManager)); } // --- Product Endpoints --- [HttpPost("add-letter-product/{letterId}")] public async Task AddProduct(long letterId, CreateLetterProductDto dto) => Ok(await _service.AddProductToLetter(letterId, dto)); [HttpPut("update-letter-product/{productId}")] public async Task UpdateProduct(long productId, [FromBody] UpdateProductRequestLetter request) { var result = await _service.UpdateProduct(productId, request); return result != null ? Ok(result) : NotFound(); } [HttpPatch("update-letter-product-status/{id}/status")] public async Task UpdateProductStatus( long id, [FromQuery] LetterProductStatus status, [FromQuery] string? rejectionReason = null) { var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; if (userIdClaim == null) return Unauthorized(); var result = await _service.UpdateProductStatus(id, status, rejectionReason, long.Parse(userIdClaim)); if (result == null) { return NotFound($"Product with ID {id} not found."); } return Ok(result); } [HttpDelete("delete-letter-product/{id}")] public async Task DeleteProduct(long id) { await _service.RemoveProduct(id); return NoContent(); } } }