-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCSharpTest
More file actions
158 lines (136 loc) · 5.58 KB
/
CSharpTest
File metadata and controls
158 lines (136 loc) · 5.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
/// <summary>
/// APIConsultas.cs
/// SDK en C# para consultar la API de Divisas nativamente en Windows, Unity, Xamarin/MAUI y Backend .NET.
/// Utiliza HttpClient y System.Text.Json incluidos en .NET Core/.NET 5+ sin dependencias de terceros.
/// </summary>
public static class APIConsultas
{
private const string URL_DATOS_GITHUB = "https://LucielDOD.github.io/API-Divisas/datos.json";
private static readonly HttpClient client = new HttpClient();
public class RespuestaAPI
{
public string Status { get; set; }
public string Mensaje { get; set; }
public string FechaConsulta { get; set; }
// Pedir lista
public int Cantidad { get; set; }
public List<string> Divisas { get; set; }
// Pedir conversion
public string Codigo { get; set; }
public decimal Valor { get; set; }
public string DivisaBase { get; set; }
public string DivisaObjetivo { get; set; }
}
// Estructura interna para deserializar el JSON del repositorio
private class DivisaJson
{
public string codigo { get; set; }
public string valor_actual { get; set; }
}
private static string GetFechaLocal()
{
// Toma la fecha y hora de la máquina de Windows/Linux del usuario
return DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss");
}
public static async Task<RespuestaAPI> SolicitarDivisasDisponiblesAsync()
{
var res = new RespuestaAPI();
try
{
var response = await client.GetAsync(URL_DATOS_GITHUB);
response.EnsureSuccessStatusCode();
var jsonString = await response.Content.ReadAsStringAsync();
var datos = JsonSerializer.Deserialize<List<DivisaJson>>(jsonString);
// Normalizar todos los codigos a un solo token (moneda base)
var codigos = datos
.SelectMany(d => {
var partes = d.codigo.Split(new[]{'/', '-'}, StringSplitOptions.RemoveEmptyEntries);
if (partes.Length == 2)
return new[] { partes[0] == "USD" ? partes[1] : partes[0] };
return Array.Empty<string>();
})
.Append("USD") // USD siempre está disponible
.Distinct()
.OrderBy(c => c)
.ToList();
res.Status = "success";
res.Cantidad = codigos.Count;
res.Divisas = codigos;
res.FechaConsulta = GetFechaLocal();
}
catch (Exception ex)
{
res.Status = "error";
res.Mensaje = $"Error al obtener divisas: {ex.Message}";
}
return res;
}
public static async Task<RespuestaAPI> SolicitarValorDivisaAsync(string divisaBase, string divisaObjetivo)
{
var res = new RespuestaAPI();
divisaBase = divisaBase.ToUpper();
divisaObjetivo = divisaObjetivo.ToUpper();
try
{
var response = await client.GetAsync(URL_DATOS_GITHUB);
response.EnsureSuccessStatusCode();
var jsonString = await response.Content.ReadAsStringAsync();
var datos = JsonSerializer.Deserialize<List<DivisaJson>>(jsonString);
// Normalizar: construir mapa de valores en USD para cada moneda
var valoresEnUSD = new Dictionary<string, decimal>();
valoresEnUSD["USD"] = 1m; // USD = 1 por definicion
foreach (var d in datos)
{
var partes = d.codigo.Split(new[]{'/', '-'}, StringSplitOptions.RemoveEmptyEntries);
if (partes.Length != 2) continue;
string monedaA = partes[0].Trim().ToUpper();
string monedaB = partes[1].Trim().ToUpper();
if (!decimal.TryParse(d.valor_actual, System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out decimal val)) continue;
if (monedaB == "USD")
{
// XXX/USD -> valor directo en USD
valoresEnUSD[monedaA] = val;
}
else if (monedaA == "USD" && val != 0)
{
// USD/YYY -> invertir para obtener YYY en USD
valoresEnUSD.TryAdd(monedaB, Math.Round(1m / val, 8));
}
}
if (!valoresEnUSD.ContainsKey(divisaBase))
{
res.Status = "error";
res.Mensaje = $"La divisa base '{divisaBase}' no se encuentra.";
return res;
}
if (!valoresEnUSD.ContainsKey(divisaObjetivo))
{
res.Status = "error";
res.Mensaje = $"La divisa objetivo '{divisaObjetivo}' no se encuentra.";
return res;
}
decimal valBase = valoresEnUSD[divisaBase];
decimal valObj = valoresEnUSD[divisaObjetivo];
decimal resultado = Math.Round(valBase / valObj, 4);
res.Status = "success";
res.Codigo = $"{divisaBase}-{divisaObjetivo}";
res.Valor = resultado;
res.DivisaBase = divisaBase;
res.DivisaObjetivo = divisaObjetivo;
res.FechaConsulta = GetFechaLocal();
}
catch (Exception ex)
{
res.Status = "error";
res.Mensaje = $"Error al calcular conversiones: {ex.Message}";
}
return res;
}
}