feat: Complete API endpoints for grains and cattle data

This commit is contained in:
2025-07-01 12:45:32 -03:00
parent 8595dd16a8
commit 5e9270eda7
5 changed files with 85 additions and 6 deletions

View File

@@ -9,15 +9,60 @@ namespace Mercados.Api.Controllers
public class MercadosController : ControllerBase public class MercadosController : ControllerBase
{ {
private readonly ICotizacionBolsaRepository _bolsaRepo; private readonly ICotizacionBolsaRepository _bolsaRepo;
private readonly ICotizacionGranoRepository _granoRepo;
private readonly ICotizacionGanadoRepository _ganadoRepo;
private readonly ILogger<MercadosController> _logger; private readonly ILogger<MercadosController> _logger;
// Inyectamos los repositorios que este controlador necesita. // Inyectamos TODOS los repositorios que necesita el controlador.
public MercadosController(ICotizacionBolsaRepository bolsaRepo, ILogger<MercadosController> logger) public MercadosController(
ICotizacionBolsaRepository bolsaRepo,
ICotizacionGranoRepository granoRepo,
ICotizacionGanadoRepository ganadoRepo,
ILogger<MercadosController> logger)
{ {
_bolsaRepo = bolsaRepo; _bolsaRepo = bolsaRepo;
_granoRepo = granoRepo;
_ganadoRepo = ganadoRepo;
_logger = logger; _logger = logger;
} }
// --- Endpoint para Agroganadero ---
[HttpGet("agroganadero")]
[ProducesResponseType(typeof(IEnumerable<CotizacionGanado>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetAgroganadero()
{
try
{
var data = await _ganadoRepo.ObtenerUltimaTandaAsync();
return Ok(data);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener cotizaciones de agroganadero.");
return StatusCode(500, "Ocurrió un error interno en el servidor.");
}
}
// --- Endpoint para Granos ---
[HttpGet("granos")]
[ProducesResponseType(typeof(IEnumerable<CotizacionGrano>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetGranos()
{
try
{
var data = await _granoRepo.ObtenerUltimasAsync();
return Ok(data);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener cotizaciones de granos.");
return StatusCode(500, "Ocurrió un error interno en el servidor.");
}
}
// --- Endpoints de Bolsa ---
[HttpGet("bolsa/eeuu")] [HttpGet("bolsa/eeuu")]
[ProducesResponseType(typeof(IEnumerable<CotizacionBolsa>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(IEnumerable<CotizacionBolsa>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)] [ProducesResponseType(StatusCodes.Status500InternalServerError)]
@@ -51,7 +96,5 @@ namespace Mercados.Api.Controllers
return StatusCode(500, "Ocurrió un error interno en el servidor."); return StatusCode(500, "Ocurrió un error interno en el servidor.");
} }
} }
// NOTA: Añadiremos los endpoints para Granos y Ganado en un momento.
} }
} }

View File

@@ -30,5 +30,18 @@ namespace Mercados.Infrastructure.Persistence.Repositories
await connection.ExecuteAsync(sql, cotizaciones); await connection.ExecuteAsync(sql, cotizaciones);
} }
public async Task<IEnumerable<CotizacionGanado>> ObtenerUltimaTandaAsync()
{
using IDbConnection connection = _connectionFactory.CreateConnection();
// Primero, obtenemos la fecha de registro más reciente.
// Luego, seleccionamos todos los registros que tengan esa fecha.
const string sql = @"
SELECT *
FROM CotizacionesGanado
WHERE FechaRegistro = (SELECT MAX(FechaRegistro) FROM CotizacionesGanado);";
return await connection.QueryAsync<CotizacionGanado>(sql);
}
} }
} }

View File

@@ -23,5 +23,26 @@ namespace Mercados.Infrastructure.Persistence.Repositories
await connection.ExecuteAsync(sql, cotizaciones); await connection.ExecuteAsync(sql, cotizaciones);
} }
public async Task<IEnumerable<CotizacionGrano>> ObtenerUltimasAsync()
{
using IDbConnection connection = _connectionFactory.CreateConnection();
const string sql = @"
WITH RankedCotizaciones AS (
SELECT
*,
ROW_NUMBER() OVER(PARTITION BY Nombre ORDER BY FechaRegistro DESC) as rn
FROM
CotizacionesGranos
)
SELECT
Id, Nombre, Precio, VariacionPrecio, FechaOperacion, FechaRegistro
FROM
RankedCotizaciones
WHERE
rn = 1;";
return await connection.QueryAsync<CotizacionGrano>(sql);
}
} }
} }

View File

@@ -5,5 +5,6 @@ namespace Mercados.Infrastructure.Persistence.Repositories
public interface ICotizacionGanadoRepository : IBaseRepository public interface ICotizacionGanadoRepository : IBaseRepository
{ {
Task GuardarMuchosAsync(IEnumerable<CotizacionGanado> cotizaciones); Task GuardarMuchosAsync(IEnumerable<CotizacionGanado> cotizaciones);
Task<IEnumerable<CotizacionGanado>> ObtenerUltimaTandaAsync();
} }
} }

View File

@@ -5,5 +5,6 @@ namespace Mercados.Infrastructure.Persistence.Repositories
public interface ICotizacionGranoRepository : IBaseRepository public interface ICotizacionGranoRepository : IBaseRepository
{ {
Task GuardarMuchosAsync(IEnumerable<CotizacionGrano> cotizaciones); Task GuardarMuchosAsync(IEnumerable<CotizacionGrano> cotizaciones);
Task<IEnumerable<CotizacionGrano>> ObtenerUltimasAsync();
} }
} }