feat: add ChartDataServiceV2 with IChartDataServiceV2 (2-SP approach)
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
using CertReports.Syncfusion.Models;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Data;
|
||||
|
||||
namespace CertReports.Syncfusion.Services.Implementations;
|
||||
|
||||
/// <summary>
|
||||
/// Recupera i dati per il grafico V2 con solo 2 round-trip al DB.
|
||||
///
|
||||
/// SP utilizzate:
|
||||
/// - cedlab_Chart_UL1: Metadata sottostanti (1 query, N sottostanti)
|
||||
/// - cedlab_Chart_AllSeriesV2: Tutte le serie CTF + UL in una query (TOP 350 per-serie)
|
||||
/// </summary>
|
||||
public interface IChartDataServiceV2
|
||||
{
|
||||
Task<ChartDataV2?> GetChartDataV2Async(string isin);
|
||||
}
|
||||
|
||||
public class ChartDataServiceV2 : IChartDataServiceV2
|
||||
{
|
||||
private readonly string _connectionString;
|
||||
private readonly ILogger<ChartDataServiceV2> _logger;
|
||||
|
||||
public ChartDataServiceV2(IConfiguration config, ILogger<ChartDataServiceV2> logger)
|
||||
{
|
||||
_connectionString = config.GetConnectionString("CertDb")
|
||||
?? throw new InvalidOperationException("ConnectionString 'CertDb' non configurata.");
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<ChartDataV2?> GetChartDataV2Async(string isin)
|
||||
{
|
||||
await using var conn = new SqlConnection(_connectionString);
|
||||
await conn.OpenAsync();
|
||||
|
||||
// ── 1. Metadata sottostanti (cedlab_Chart_UL1) ─────────────────
|
||||
var underlyings = new List<ChartUlMetadata>();
|
||||
|
||||
await using (var cmd = new SqlCommand("cedlab_Chart_UL1", conn)
|
||||
{ CommandType = CommandType.StoredProcedure })
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@isin", isin);
|
||||
await using var r = await cmd.ExecuteReaderAsync();
|
||||
while (await r.ReadAsync())
|
||||
{
|
||||
underlyings.Add(new ChartUlMetadata
|
||||
{
|
||||
IDCertificates = r.GetInt32(r.GetOrdinal("IDCertificates")),
|
||||
IDUnderlyings = r.GetInt32(r.GetOrdinal("IDUnderlyings")),
|
||||
StartDate = r.GetDateTime(r.GetOrdinal("StartDate")),
|
||||
Strike = r.GetDecimal(r.GetOrdinal("Strike")),
|
||||
BarrieraCouponPerc = r.GetDecimal(r.GetOrdinal("BarrieraCouponPerc")),
|
||||
BarrieraCoupon = r.GetDecimal(r.GetOrdinal("BarrieraCoupon")),
|
||||
BarrieraCapitalePerc = r.GetDecimal(r.GetOrdinal("BarrieraCapitalePerc")),
|
||||
BarrieraCapitale = r.GetDecimal(r.GetOrdinal("BarrieraCapitale")),
|
||||
Sottostante = r.GetString(r.GetOrdinal("Sottostante")),
|
||||
IsWorstOf = r.GetInt32(r.GetOrdinal("IsWorstOf")),
|
||||
PriceWorst = r.GetDecimal(r.GetOrdinal("PriceWorst")),
|
||||
PriceWorstPerc = r.GetDecimal(r.GetOrdinal("PriceWorstPerc")),
|
||||
NumPrezziCFT = r.GetInt32(r.GetOrdinal("NumPrezziCFT")),
|
||||
NomeCFT = r.GetString(r.GetOrdinal("NomeCFT")),
|
||||
TriggerAutocallPerc = r.GetDecimal(r.GetOrdinal("TriggerAutocallPerc")),
|
||||
AutocallValue = r.GetDecimal(r.GetOrdinal("AutocallValue")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (underlyings.Count == 0)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
"Nessun sottostante trovato per il grafico V2 di {Isin} (meno di 30 prezzi EOD?)", isin);
|
||||
return null;
|
||||
}
|
||||
|
||||
var result = new ChartDataV2
|
||||
{
|
||||
Isin = isin,
|
||||
GlobalMeta = underlyings[0], // worst-of è il primo (SP ordina IsWorstOf DESC)
|
||||
Underlyings = underlyings,
|
||||
};
|
||||
|
||||
// ── 2. Tutte le serie (cedlab_Chart_AllSeriesV2) ────────────────
|
||||
await using (var cmd = new SqlCommand("cedlab_Chart_AllSeriesV2", conn)
|
||||
{ CommandType = CommandType.StoredProcedure })
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@isin", isin);
|
||||
await using var r = await cmd.ExecuteReaderAsync();
|
||||
while (await r.ReadAsync())
|
||||
{
|
||||
result.SeriesPoints.Add(new ChartSeriesPoint
|
||||
{
|
||||
IDUnderlyings = r.GetInt32(r.GetOrdinal("IDUnderlyings")),
|
||||
Date = r.GetDateTime(r.GetOrdinal("Px_date")),
|
||||
Performance = r.GetDecimal(r.GetOrdinal("Performance")),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogInformation(
|
||||
"Dati grafico V2 caricati per {Isin}: {UlCount} sottostanti, {Points} punti totali",
|
||||
isin, underlyings.Count, result.SeriesPoints.Count);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user