| | 1 | | using Domain.Common; |
| | 2 | | using Domain.Currencies; |
| | 3 | | using System.Net.Http.Json; |
| | 4 | | using System.Reflection; |
| | 5 | | using System.Text.Json; |
| | 6 | | using Microsoft.Extensions.Logging; |
| | 7 | | using Infrastructure.ExchangeProviders.Frankfurter.Models; |
| | 8 | |
|
| | 9 | | namespace Infrastructure.ExchangeProviders.Frankfurter |
| | 10 | | { |
| | 11 | | public class FrankfurterExchangeProvider : IExchangeProvider |
| | 12 | | { |
| | 13 | | private readonly ILogger<FrankfurterExchangeProvider> _logger; |
| | 14 | | private readonly HttpClient _httpClient; |
| 10 | 15 | | public FrankfurterExchangeProvider(HttpClient httpClient, ILogger<FrankfurterExchangeProvider> logger) |
| 10 | 16 | | { |
| 10 | 17 | | _logger = logger; |
| 10 | 18 | | _httpClient = httpClient; |
| 10 | 19 | | } |
| | 20 | |
|
| 12 | 21 | | public ExchangeProviderType ProviderType { get; } = ExchangeProviderType.Frankfurter; |
| | 22 | |
|
| | 23 | | public async Task<Result<CurrencySnapshot>> FindLatestAsync(CurrencyCode currencyCode) |
| 3 | 24 | | { |
| | 25 | | try |
| 3 | 26 | | { |
| 3 | 27 | | var response = await _httpClient.GetFromJsonAsync<FrankfurterLatestResponse>($"v1/latest?base={currencyC |
| | 28 | |
|
| 2 | 29 | | List<(string Code, decimal Amount)> expectedRates = response.Rates.GetType() |
| 2 | 30 | | .GetProperties(BindingFlags.Public | BindingFlags.Instance) |
| 60 | 31 | | .Where(prop => prop.GetValue(response.Rates) != null) |
| 31 | 32 | | .Select(prop => (Code: prop.Name, Amount: Convert.ToDecimal(prop.GetValue(response.Rates)))) |
| 2 | 33 | | .ToList(); |
| | 34 | |
|
| 2 | 35 | | var result = CurrencySnapshot.Create(response.Base, |
| 2 | 36 | | response.Date, |
| 2 | 37 | | expectedRates); |
| | 38 | |
|
| 2 | 39 | | return result.Value; |
| | 40 | | } |
| 1 | 41 | | catch (JsonException exception) |
| 1 | 42 | | { |
| 1 | 43 | | _logger.LogError("Franfurter returned an invalid json payload, {error}", exception.Message); |
| 1 | 44 | | return Result.Failure<CurrencySnapshot>(Error.SystemError); |
| | 45 | | } |
| 3 | 46 | | } |
| | 47 | |
|
| | 48 | | public async Task<Result<List<CurrencySnapshot>>> SearchAsync(CurrencyCode currencyCode, DateTime startDate, Dat |
| 4 | 49 | | { |
| | 50 | | try |
| 4 | 51 | | { |
| 4 | 52 | | var response = await _httpClient.GetFromJsonAsync<FrankfurterSearchResponse>($"v1/{startDate.ToString("y |
| 3 | 53 | | List<CurrencySnapshot> result = new List<CurrencySnapshot>(); |
| 33 | 54 | | foreach (var rate in response.Rates) |
| 12 | 55 | | { |
| 12 | 56 | | var snapShotResult = |
| 12 | 57 | | CurrencySnapshot.Create( |
| 12 | 58 | | currencyCode.Value, |
| 12 | 59 | | rate.Key, |
| 32 | 60 | | rate.Value.Select(r => (r.Key, r.Value)).ToList()); |
| 12 | 61 | | if (snapShotResult.IsSuccess) |
| 12 | 62 | | { |
| 12 | 63 | | result.Add(snapShotResult.Value); |
| 12 | 64 | | } |
| 12 | 65 | | } |
| 3 | 66 | | return result; |
| | 67 | | } |
| 1 | 68 | | catch (JsonException exception) |
| 1 | 69 | | { |
| 1 | 70 | | _logger.LogError("Franfurter returned an invalid json payload, {error}", exception.Message); |
| 1 | 71 | | return Result.Failure<List<CurrencySnapshot>>(Error.SystemError); |
| | 72 | | } |
| 4 | 73 | | } |
| | 74 | | } |
| | 75 | | } |