using Microsoft.AspNetCore.Mvc;
using Documents.Models;
using Domain.Dtos;
using Domain.Entities;
using Domain.Generics;
using Models.Interfaces;
using System.Reflection;
using Documents.Interfaces;
namespace phronCare.API.Controllers.Sales
{
[Route("api/[controller]")]
[ApiController]
public class QuoteController : ControllerBase
{
private readonly IDocumentTemplateService _documentTemplateService;
private readonly IQuoteDom _quoteService;
public QuoteController(IDocumentTemplateService documentTemplateService, IQuoteDom quoteService)
{
_documentTemplateService = documentTemplateService ??
throw new ArgumentNullException(nameof(documentTemplateService)); ;
_quoteService = quoteService ??
throw new ArgumentNullException(nameof(quoteService));
}
#region Obtener Presupuestos
///
/// Busca presupuestos con filtros de texto libre o por ID, paginados.
///
[HttpGet("search")]
public async Task>> Search(
[FromQuery] int? customerId,
[FromQuery] string? customerText,
[FromQuery] string? quoteNumber,
[FromQuery] int? professionalId,
[FromQuery] string? professionalText,
[FromQuery] int? institutionId,
[FromQuery] string? institutionText,
[FromQuery] int? patientId,
[FromQuery] string? patientText,
[FromQuery] DateTime? issueDateFrom,
[FromQuery] DateTime? issueDateTo,
[FromQuery] string? status,
[FromQuery] int page = 1,
[FromQuery] int pageSize = 50)
{
try
{
var result = await _quoteService.SearchAsync(
customerId,
customerText,
quoteNumber,
professionalId,
professionalText,
institutionId,
institutionText,
patientId,
patientText,
issueDateFrom,
issueDateTo,
status,
page,
pageSize);
return Ok(result);
}
catch (Exception ex)
{
var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
// Log exception as needed...
return StatusCode(500, $"{methodName} Message: {ex.Message}");
}
}
[HttpGet("{id}/pdf")]
public async Task GetQuotePdf(int id)
{
var quote = await _quoteService.GetDtoByIdAsync(id);
if (quote == null)
return NotFound($"Presupuesto con ID {id} no encontrado.");
var pdfBytes = await _documentTemplateService.GenerateDocumentAsync(new DocumentGenerationRequest
{
Model = quote
});
return File(pdfBytes, "application/pdf", $"Presupuesto_{quote.Quotenumber}.pdf");
}
#endregion
#region Endpoint de emision de presupuesto (encabezado + detalles + roles + ajustes + impuestos)
[HttpPost("createfull")]
public async Task CreateFullQuote([FromBody] CreateFullQuoteRequest request)
{
try
{
// Validamos que el request y el objeto Quote no sean nulos
if (request == null || request.Quote == null)
return BadRequest("El payload no puede contener elementos nulos.");
// Desempaquetamos los datos
var quote = request.Quote;
var formSeriesId = request.FormSeriesId;
// Llamada al servicio de negocio
var quoteNumber = await _quoteService.CreateFullQuoteAsync(quote, formSeriesId);
// Devolvemos el número generado
return Ok(new { Success = true, QuoteNumber = quoteNumber });
}
catch (ArgumentNullException ex)
{
return BadRequest($"Validación fallida: {ex.Message}");
}
catch (InvalidOperationException ex)
{
return BadRequest($"Error de negocio: {ex.Message}");
}
catch (Exception ex)
{
return StatusCode(500, $"Ocurrió un error interno: {ex.Message}");
}
}
public class CreateFullQuoteRequest
{
public EQuoteHeader Quote { get; set; } = default!;
public int FormSeriesId { get; set; }
}
#endregion
}
}