feat: add FundDataService (sfih_GetOptDettagli + sfih_GetChartPrices)

This commit is contained in:
2026-06-08 17:37:26 +02:00
parent fa1fc94fd8
commit bbb7e4207a

View File

@@ -0,0 +1,125 @@
using System.Data;
using CertReports.Syncfusion.Models;
using CertReports.Syncfusion.Services.Interfaces;
using Microsoft.Data.SqlClient;
namespace CertReports.Syncfusion.Services.Implementations;
public class FundDataService : IFundDataService
{
private readonly string _connectionString;
private readonly ILogger<FundDataService> _logger;
public FundDataService(IConfiguration config, ILogger<FundDataService> logger)
{
_connectionString = config.GetConnectionString("CertDb")
?? throw new InvalidOperationException("ConnectionString 'CertDb' non configurata.");
_logger = logger;
}
public async Task<FundInfo?> GetFundInfoAsync(string isin)
{
try
{
await using var conn = new SqlConnection(_connectionString);
await conn.OpenAsync();
await using var cmd = new SqlCommand("sfih_GetOptDettagli", conn)
{
CommandType = CommandType.StoredProcedure
};
cmd.Parameters.AddWithValue("@ISIN", isin);
await using var r = await cmd.ExecuteReaderAsync();
if (!await r.ReadAsync()) return null;
return MapFundInfo(r);
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore GetFundInfoAsync per ISIN {Isin}", isin);
throw;
}
}
public async Task<List<FundChartPoint>> GetChartPricesAsync(string isin)
{
var points = new List<FundChartPoint>();
try
{
await using var conn = new SqlConnection(_connectionString);
await conn.OpenAsync();
await using var cmd = new SqlCommand("sfih_GetChartPrices", conn)
{
CommandType = CommandType.StoredProcedure
};
cmd.Parameters.AddWithValue("@ISIN", isin);
await using var r = await cmd.ExecuteReaderAsync();
while (await r.ReadAsync())
{
points.Add(new FundChartPoint
{
Date = r.GetSafe<DateTime>("Px_Date"),
Close = r.GetSafe<decimal>("Px_Close")
});
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore GetChartPricesAsync per ISIN {Isin}", isin);
throw;
}
return points;
}
public async Task<string?> FindIsinByAliasIdAsync(string aliasId)
{
await using var conn = new SqlConnection(_connectionString);
await conn.OpenAsync();
await using var cmd = new SqlCommand("rpt_FindIsinbyAliasID", conn)
{
CommandType = CommandType.StoredProcedure
};
cmd.Parameters.AddWithValue("@AliasID", aliasId);
await using var r = await cmd.ExecuteReaderAsync();
if (!await r.ReadAsync()) return null;
var isin = r.GetStringSafe("ISIN");
return string.IsNullOrEmpty(isin) ? null : isin;
}
private static FundInfo MapFundInfo(SqlDataReader r) => new()
{
Isin = r.GetStringSafe("isn"),
Strumento = r.GetStringSafe("str"),
Tipo = r.GetStringSafe("typ").NullIfEmpty(),
Societa = r.GetStringSafe("soc").NullIfEmpty(),
CategoriaMorningstar = r.GetStringSafe("msc").NullIfEmpty(),
Valuta = r.GetStringSafe("val").NullIfEmpty(),
Hedged = r.GetStringSafe("hed").NullIfEmpty(),
Benchmark = r.GetStringSafe("bmk").NullIfEmpty(),
Catalogo = r.GetStringSafe("itr").NullIfEmpty(),
Proventi = r.GetStringSafe("prv").NullIfEmpty(),
DataLancio = r.GetSafe<DateTime>("daf") == default ? null : r.GetSafe<DateTime>("daf"),
Patrimonio = r.GetSafe<decimal>("pat") == 0m ? null : r.GetSafe<decimal>("pat"),
SpeseCorrenti = r.GetSafe<decimal>("spc"),
Prezzo = r.GetSafe<decimal>("prz") == 0m ? null : r.GetSafe<decimal>("prz"),
DataPrezzo = r.GetSafe<DateTime>("dpz") == default ? null : r.GetSafe<DateTime>("dpz"),
Rank = r.GetSafe<decimal>("rnk"),
P3M = r.GetSafe<decimal>("p3M"), P6M = r.GetSafe<decimal>("p6M"),
PYD = r.GetSafe<decimal>("pYD"), P1Y = r.GetSafe<decimal>("p1Y"),
P3Y = r.GetSafe<decimal>("p3Y"), P5Y = r.GetSafe<decimal>("p5Y"),
V3M = r.GetSafe<decimal>("v3M"), V6M = r.GetSafe<decimal>("v6M"),
VYD = r.GetSafe<decimal>("vYD"), V1Y = r.GetSafe<decimal>("v1Y"),
V3Y = r.GetSafe<decimal>("v3Y"), V5Y = r.GetSafe<decimal>("v5Y"),
R3M = r.GetSafe<decimal>("r3M"), R6M = r.GetSafe<decimal>("r6M"),
RYD = r.GetSafe<decimal>("rYD"), R1Y = r.GetSafe<decimal>("r1Y"),
R3Y = r.GetSafe<decimal>("r3Y"), R5Y = r.GetSafe<decimal>("r5Y"),
Sustainability = r.GetSafe<decimal>("sus"),
Environmental = r.GetSafe<decimal>("env"),
Social = r.GetSafe<decimal>("ssc"),
Governance = r.GetSafe<decimal>("gov"),
};
}
file static class StringExtensions
{
public static string? NullIfEmpty(this string s) =>
string.IsNullOrEmpty(s) ? null : s;
}