using Core.Interfaces; using Domain.Entities; using Models.Interfaces; using System.Net.Http.Json; using System.Text.Json.Serialization; public class ExchangeRateDom : IExchangeRateDom { private readonly IPhOHExchangeRateHistory _repository; private readonly HttpClient _http; public ExchangeRateDom(IPhOHExchangeRateHistory repository, HttpClient http) { _repository = repository; _http = http; } public async Task GetYesterdayRateAsync() { // 1) Calcular “ayer” en ART var argentinaNow = DateTime.UtcNow.AddHours(-3); var yesterday = DateOnly.FromDateTime(argentinaNow.Date.AddDays(-1)); // 2) Intentar rescatar del histórico var existing = await _repository.GetByDateAsync(yesterday); if (existing is not null) return existing; // 3) Si no está, llamar al API BCRA pedimos desde hace 7 días hasta ayer para saltar feriados/fines de semana var from = yesterday.AddDays(-7).ToString("yyyy-MM-dd"); var to = yesterday.ToString("yyyy-MM-dd"); var url = $"estadisticascambiarias/v1.0/Cotizaciones/USD?fechadesde={from}&fechahasta={to}"; var series = await _http.GetFromJsonAsync(url) ?? throw new InvalidOperationException("No se obtuvo JSON válido del BCRA"); if (series.Results == null || !series.Results.Any()) throw new InvalidOperationException("No hay datos de cotización en el período solicitado"); // 4) El primer elemento es el más reciente (ayer o último día hábil) var day = series.Results.First(); var detail = day.Details.First(d => d.CodigoMoneda == "USD"); var rate = detail.TipoCotizacion; // 5) Construir dominio y persistir var entity = new EExchangeRateHistory { Ratedate = yesterday, Purchaserate = rate, Salerate = rate, Source = "BCRA", Createdat = DateTime.UtcNow }; return await _repository.AddAsync(entity); } public Task GetByDateAsync(DateOnly date) { // Simplemente delega al repositorio return _repository.GetByDateAsync(date); } } // Core/Services/Dto.cs public class SeriesResponse { public int Status { get; set; } public Metadata Metadata { get; set; } = null!; public List Results { get; set; } = new(); } public class Metadata { public Resultset Resultset { get; set; } = null!; } public class Resultset { public int Count { get; set; } public int Offset { get; set; } public int Limit { get; set; } } public class RateDay { public DateTime Fecha { get; set; } [JsonPropertyName("detalle")] public List Details { get; set; } = new(); } public class RateDetail { public string CodigoMoneda { get; set; } = null!; public decimal TipoCotizacion { get; set; } // otros campos opcionales: descripcion, tipoPase, etc. }