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