2026-07-24 17:35:34 -03:00
using Api.SeaHavenIndustries.DTOs ;
2026-08-13 14:49:56 -03:00
using Api.SeaHavenIndustries.Helper ;
2026-07-24 17:35:34 -03:00
using Data.SeaHavenIndustries ;
using Microsoft.AspNetCore.Authorization ;
using Microsoft.AspNetCore.Mvc ;
2026-08-13 14:49:56 -03:00
using Microsoft.Extensions.Logging ;
2026-07-24 17:35:34 -03:00
using SeaHaven.Services.DTOs ;
using SeaHaven.Services.Exceptions ;
using SeaHaven.Services.Interfaces ;
using System.Security.Claims ;
namespace Api.SeaHavenIndustries.Controllers
{
[Authorize]
[ApiController]
[Route("api/WorkOrder")]
[Route("api/workorders")]
public class WorkOrderDetailController : Controller
{
private readonly IWorkOrderDetailService _workOrderDetailService ;
private readonly IWorkOrderCommentService _workOrderCommentService ;
2026-08-13 14:49:56 -03:00
private readonly IWorkOrderUpliftService _workOrderUpliftService ;
private readonly ILogger < WorkOrderDetailController > _logger ;
2026-07-24 17:35:34 -03:00
public WorkOrderDetailController (
IWorkOrderDetailService workOrderDetailService ,
2026-08-13 14:49:56 -03:00
IWorkOrderCommentService workOrderCommentService ,
IWorkOrderUpliftService workOrderUpliftService ,
ILogger < WorkOrderDetailController > logger )
2026-07-24 17:35:34 -03:00
{
_workOrderDetailService = workOrderDetailService ;
_workOrderCommentService = workOrderCommentService ;
2026-08-13 14:49:56 -03:00
_workOrderUpliftService = workOrderUpliftService ;
_logger = logger ;
2026-07-24 17:35:34 -03:00
}
[HttpGet("{id:int}/detail")]
public async Task < IActionResult > GetDetail ( int id )
{
2026-08-11 10:45:37 -03:00
try
{
var detail = await _workOrderDetailService . GetDetailAsync ( id , User ) ;
if ( detail = = null )
return NotFound ( new Response { Status = "Error" , Message = "Work order not found." } ) ;
return Ok ( detail ) ;
}
catch ( WorkOrderBoardValidationException ex ) when ( ex . Code = = "Forbidden" )
{
return StatusCode ( StatusCodes . Status403Forbidden , new Response { Status = "Error" , Message = ex . Message } ) ;
}
2026-07-24 17:35:34 -03:00
}
[HttpGet("{id:int}/audit")]
public async Task < IActionResult > GetAudit ( int id , [ FromQuery ] int limit = 50 )
{
2026-08-11 10:45:37 -03:00
try
{
var audit = await _workOrderDetailService . GetAuditAsync ( id , User , limit ) ;
if ( audit = = null )
return NotFound ( new Response { Status = "Error" , Message = "Work order not found." } ) ;
return Ok ( audit ) ;
}
catch ( WorkOrderBoardValidationException ex ) when ( ex . Code = = "Forbidden" )
{
return StatusCode ( StatusCodes . Status403Forbidden , new Response { Status = "Error" , Message = ex . Message } ) ;
}
2026-07-24 17:35:34 -03:00
}
[HttpGet("{id:int}/comments")]
public async Task < IActionResult > GetBoardComments ( int id )
{
2026-08-11 14:52:02 -03:00
try
{
var comments = await _workOrderCommentService . GetCommentsAsync ( id , User ) ;
if ( comments = = null )
return NotFound ( new Response { Status = "Error" , Message = "Work order not found." } ) ;
return Ok ( comments ) ;
}
catch ( WorkOrderBoardValidationException ex ) when ( ex . Code = = "Forbidden" )
{
return StatusCode ( StatusCodes . Status403Forbidden ,
new WorkOrderBoardValidationErrorDto { Code = ex . Code , Message = ex . Message } ) ;
}
2026-07-24 17:35:34 -03:00
}
[HttpPost("{id:int}/comments")]
public async Task < IActionResult > AddBoardComment ( int id , [ FromBody ] WorkOrderCommentCreateDto request )
{
try
{
var actorId = User . FindFirstValue ( ClaimTypes . NameIdentifier ) ;
2026-08-11 14:52:02 -03:00
var comment = await _workOrderCommentService . AddCommentAsync ( id , request , User , actorId ) ;
2026-07-24 17:35:34 -03:00
return Ok ( comment ) ;
}
catch ( WorkOrderBoardValidationException ex ) when ( ex . Code = = "NotFound" )
{
return NotFound ( new WorkOrderBoardValidationErrorDto { Code = ex . Code , Message = ex . Message } ) ;
}
2026-08-11 14:52:02 -03:00
catch ( WorkOrderBoardValidationException ex ) when ( ex . Code = = "Forbidden" )
{
return StatusCode ( StatusCodes . Status403Forbidden ,
new WorkOrderBoardValidationErrorDto { Code = ex . Code , Message = ex . Message } ) ;
}
2026-07-24 17:35:34 -03:00
catch ( WorkOrderBoardValidationException ex )
{
return UnprocessableEntity ( new WorkOrderBoardValidationErrorDto { Code = ex . Code , Message = ex . Message } ) ;
}
}
2026-07-24 18:28:44 -03:00
[HttpPatch("{id:int}/comments/{commentId:int}")]
public async Task < IActionResult > UpdateBoardComment (
int id ,
int commentId ,
[FromBody] WorkOrderCommentCreateDto request )
{
try
{
var actorId = User . FindFirstValue ( ClaimTypes . NameIdentifier ) ;
var comment = await _workOrderCommentService . UpdateCommentAsync (
2026-08-11 14:52:02 -03:00
id , commentId , request , User , actorId ) ;
2026-07-24 18:28:44 -03:00
return Ok ( comment ) ;
}
catch ( WorkOrderBoardValidationException ex ) when ( ex . Code = = "NotFound" )
{
return NotFound ( new WorkOrderBoardValidationErrorDto { Code = ex . Code , Message = ex . Message } ) ;
}
catch ( WorkOrderBoardValidationException ex ) when ( ex . Code = = "Forbidden" )
{
return StatusCode ( StatusCodes . Status403Forbidden ,
new WorkOrderBoardValidationErrorDto { Code = ex . Code , Message = ex . Message } ) ;
}
catch ( WorkOrderBoardValidationException ex )
{
return UnprocessableEntity ( new WorkOrderBoardValidationErrorDto { Code = ex . Code , Message = ex . Message } ) ;
}
}
2026-08-13 14:49:56 -03:00
[HttpGet("{id:int}/uplifts")]
public async Task < IActionResult > ListUplifts ( int id , CancellationToken cancellationToken )
{
try
{
var items = await _workOrderUpliftService . ListAsync ( id , User , cancellationToken ) ;
if ( items = = null )
return NotFound ( new Response { Status = "Error" , Message = "Work order not found." } ) ;
return Ok ( new DataResponse { Status = "Success" , Data = new WorkOrderUpliftListDto { Items = items . ToList ( ) } } ) ;
}
catch ( WorkOrderBoardValidationException ex ) when ( ex . Code = = "Forbidden" )
{
return StatusCode ( StatusCodes . Status403Forbidden , new Response { Status = "Error" , Message = ex . Message } ) ;
}
}
[HttpPost("{id:int}/uplifts")]
public async Task < IActionResult > CreateUplift (
int id ,
[FromBody] CreateWorkOrderUpliftRequestDto request ,
CancellationToken cancellationToken )
{
try
{
var created = await _workOrderUpliftService . CreateAsync ( id , request , User , cancellationToken ) ;
if ( created = = null )
return NotFound ( new Response { Status = "Error" , Message = "Work order not found." } ) ;
return Ok ( new DataResponse { Status = "Success" , Data = created } ) ;
}
catch ( KeyNotFoundException ex )
{
return NotFound ( new Response { Status = "Error" , Message = _logger . Sanitize ( ex , "Resource not found" ) } ) ;
}
catch ( UpliftForbiddenException ex )
{
return StatusCode ( StatusCodes . Status403Forbidden , new Response { Status = "Error" , Message = _logger . Sanitize ( ex , "You are not authorized to perform this action" ) } ) ;
}
catch ( InvalidOperationException ex )
{
return BadRequest ( new Response { Status = "Error" , Message = _logger . Sanitize ( ex , "The uplift request could not be created" ) } ) ;
}
}
[HttpPost("{id:int}/uplifts/{upliftId:int}/cancel")]
public async Task < IActionResult > CancelUplift ( int id , int upliftId , CancellationToken cancellationToken )
{
try
{
var cancelled = await _workOrderUpliftService . CancelAsync ( id , upliftId , User , cancellationToken ) ;
if ( cancelled = = null )
return NotFound ( new Response { Status = "Error" , Message = "Work order not found." } ) ;
return Ok ( new DataResponse { Status = "Success" , Data = cancelled } ) ;
}
catch ( KeyNotFoundException ex )
{
return NotFound ( new Response { Status = "Error" , Message = _logger . Sanitize ( ex , "Uplift request not found" ) } ) ;
}
catch ( UpliftForbiddenException ex )
{
return StatusCode ( StatusCodes . Status403Forbidden , new Response { Status = "Error" , Message = _logger . Sanitize ( ex , "You are not authorized to perform this action" ) } ) ;
}
catch ( InvalidOperationException ex )
{
return BadRequest ( new Response { Status = "Error" , Message = _logger . Sanitize ( ex , "The uplift request cannot be cancelled in its current state" ) } ) ;
}
}
[HttpPost("{id:int}/uplifts/{upliftId:int}/revoke")]
public async Task < IActionResult > RevokeUplift (
int id ,
int upliftId ,
[FromBody] RevokeWorkOrderUpliftRequestDto ? request ,
CancellationToken cancellationToken )
{
try
{
var revoked = await _workOrderUpliftService . RevokeAsync (
id ,
upliftId ,
request ? ? new RevokeWorkOrderUpliftRequestDto ( ) ,
User ,
cancellationToken ) ;
if ( revoked = = null )
return NotFound ( new Response { Status = "Error" , Message = "Work order not found." } ) ;
return Ok ( new DataResponse { Status = "Success" , Data = revoked } ) ;
}
catch ( KeyNotFoundException ex )
{
return NotFound ( new Response { Status = "Error" , Message = _logger . Sanitize ( ex , "Uplift request not found" ) } ) ;
}
catch ( UpliftForbiddenException ex )
{
return StatusCode ( StatusCodes . Status403Forbidden , new Response { Status = "Error" , Message = _logger . Sanitize ( ex , "You are not authorized to perform this action" ) } ) ;
}
catch ( InvalidOperationException ex )
{
return BadRequest ( new Response { Status = "Error" , Message = _logger . Sanitize ( ex , "The uplift request cannot be revoked in its current state" ) } ) ;
}
}
2026-07-24 17:35:34 -03:00
}
}