using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using TaxBaik.Application.Services; namespace TaxBaik.Web.Controllers; [ApiController] [Route("api/[controller]")] [Authorize] public class RevenueTrackingController(RevenueTrackingService service) : ControllerBase { [HttpPost] public async Task Create([FromBody] CreateRevenueTrackingRequest request) { try { var id = await service.CreateAsync(request.ClientId, request.InvoiceNumber, request.InvoiceDate, request.Amount, request.ServiceType, request.DueDate); return CreatedAtAction(nameof(GetById), new { id }, new { id }); } catch (ValidationException ex) { return BadRequest(new { error = ex.Message }); } } [HttpGet] public async Task GetAll() { try { var revenues = await service.GetAllAsync(); return Ok(revenues); } catch (Exception ex) { return StatusCode(500, new { error = "조회 실패", message = ex.Message }); } } [HttpGet("{id:int}")] public async Task GetById(int id) { try { var revenue = await service.GetByIdAsync(id); return revenue is null ? NotFound(new { error = "조회 실패", message = "해당 청구를 찾을 수 없습니다." }) : Ok(revenue); } catch (Exception ex) { return StatusCode(500, new { error = "조회 실패", message = ex.Message }); } } [HttpGet("client/{clientId:int}")] public async Task GetByClientId(int clientId) { try { var revenues = await service.GetByClientIdAsync(clientId); return Ok(new { data = revenues }); } catch (Exception ex) { return StatusCode(500, new { error = "조회 실패", message = ex.Message }); } } [HttpGet("pending")] public async Task GetPendingPayments() { try { var revenues = await service.GetPendingPaymentsAsync(); return Ok(new { data = revenues }); } catch (Exception ex) { return StatusCode(500, new { error = "조회 실패", message = ex.Message }); } } [HttpGet("monthly")] public async Task GetMonthlyRevenue([FromQuery] int year, [FromQuery] int month) { try { var monthDate = new DateTime(year, month, 1); var revenues = await service.GetMonthlyRevenueAsync(monthDate); return Ok(new { data = revenues, year, month }); } catch (Exception ex) { return StatusCode(500, new { error = "조회 실패", message = ex.Message }); } } [HttpGet("total")] public async Task GetTotalRevenue([FromQuery] DateTime startDate, [FromQuery] DateTime endDate) { try { var total = await service.GetTotalRevenueAsync(startDate, endDate); return Ok(new { total, startDate, endDate }); } catch (Exception ex) { return StatusCode(500, new { error = "조회 실패", message = ex.Message }); } } [HttpPut("{id:int}/paid")] public async Task MarkPaid(int id, [FromBody] MarkPaidRequest request) { try { await service.MarkPaidAsync(id, request.PaymentDate); return Ok(new { message = "결제가 완료됨으로 표시되었습니다." }); } catch (Exception ex) { return StatusCode(500, new { error = "수정 실패", message = ex.Message }); } } public record CreateRevenueTrackingRequest( int ClientId, string InvoiceNumber, DateTime InvoiceDate, decimal Amount, string? ServiceType = null, DateTime? DueDate = null); public record MarkPaidRequest(DateTime PaymentDate); }