feat: add expired certificate report branching in orchestrator
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@ namespace CertReports.Syncfusion.Services.Implementations;
|
||||
|
||||
/// <summary>
|
||||
/// Orchestratore principale: coordina il flusso di generazione report.
|
||||
///
|
||||
///
|
||||
/// Flusso:
|
||||
/// 1. Recupera dati dal DB (stored procedures)
|
||||
/// 2. Renderizza le sezioni PDF (anagrafica, eventi, scenario)
|
||||
@@ -21,6 +21,7 @@ public class ReportOrchestrator : IReportOrchestrator
|
||||
private readonly IPdfMergerService _merger;
|
||||
private readonly IPdfCacheService _cache;
|
||||
private readonly ILogger<ReportOrchestrator> _logger;
|
||||
private readonly ExpiredAnagraficaSectionRenderer _expiredAnagraficaRenderer;
|
||||
|
||||
public ReportOrchestrator(
|
||||
ICertificateDataService dataService,
|
||||
@@ -28,7 +29,8 @@ public class ReportOrchestrator : IReportOrchestrator
|
||||
IChartSectionRenderer chartRenderer,
|
||||
IPdfMergerService merger,
|
||||
IPdfCacheService cache,
|
||||
ILogger<ReportOrchestrator> logger)
|
||||
ILogger<ReportOrchestrator> logger,
|
||||
ExpiredAnagraficaSectionRenderer expiredAnagraficaRenderer)
|
||||
{
|
||||
_dataService = dataService;
|
||||
_sectionRenderers = sectionRenderers;
|
||||
@@ -36,13 +38,16 @@ public class ReportOrchestrator : IReportOrchestrator
|
||||
_merger = merger;
|
||||
_cache = cache;
|
||||
_logger = logger;
|
||||
_expiredAnagraficaRenderer = expiredAnagraficaRenderer;
|
||||
}
|
||||
|
||||
public async Task<byte[]> GenerateReportAsync(string isin, bool showBranding = false)
|
||||
{
|
||||
// ── Cache check (chiave include branding) ─────────────────────────
|
||||
var cacheKey = showBranding ? $"{isin}:branded" : isin;
|
||||
var cached = _cache.Get(cacheKey);
|
||||
// ── Cache check ────────────────────────────────────────────────
|
||||
var baseCacheKey = showBranding ? $"{isin}:branded" : isin;
|
||||
var expiredCacheKey = showBranding ? $"{isin}:expired:branded" : $"{isin}:expired";
|
||||
|
||||
var cached = _cache.Get(baseCacheKey) ?? _cache.Get(expiredCacheKey);
|
||||
if (cached != null)
|
||||
{
|
||||
_logger.LogInformation("Report per ISIN {Isin} servito da cache ({Size} bytes)", isin, cached.Length);
|
||||
@@ -60,40 +65,56 @@ public class ReportOrchestrator : IReportOrchestrator
|
||||
ShowBranding = showBranding,
|
||||
};
|
||||
|
||||
// Determina se lo scenario ha dati validi (evita doppia chiamata SP)
|
||||
bool isScenarioAllowed = reportData.Scenario.Rows.Count > 0;
|
||||
// ── 2. Determina il tipo di report ────────────────────────────
|
||||
bool isExpired = !string.IsNullOrEmpty(reportData.Info.Stato)
|
||||
&& reportData.Info.Stato != "Quotazione";
|
||||
|
||||
var cacheKey = isExpired ? expiredCacheKey : baseCacheKey;
|
||||
|
||||
_logger.LogInformation(
|
||||
"Dati recuperati per {Isin}: {SottostantiCount} sottostanti, {EventiCount} eventi, Scenario: {ScenarioAllowed}",
|
||||
isin, reportData.Info.Sottostanti.Count, reportData.Eventi.Count, isScenarioAllowed);
|
||||
"Dati recuperati per {Isin}: Stato={Stato}, isExpired={IsExpired}, {EventiCount} eventi",
|
||||
isin, reportData.Info.Stato, isExpired, reportData.Eventi.Count);
|
||||
|
||||
// ── 2. Genera le sezioni PDF ───────────────────────────────────
|
||||
// ── 3. Genera le sezioni PDF ──────────────────────────────────
|
||||
var pdfSections = new List<PdfDocument>();
|
||||
|
||||
foreach (var renderer in _sectionRenderers.OrderBy(r => r.Order))
|
||||
if (isExpired)
|
||||
{
|
||||
// Salta la sezione scenario se il certificato è Protection
|
||||
if (renderer.SectionName == "Scenario" && !isScenarioAllowed)
|
||||
{
|
||||
_logger.LogInformation("Sezione Scenario saltata per {Isin} (certificato Protection)", isin);
|
||||
continue;
|
||||
}
|
||||
// Flusso expired: ExpiredAnagrafica + Eventi + Chart
|
||||
pdfSections.Add(_expiredAnagraficaRenderer.Render(reportData));
|
||||
_logger.LogInformation("Sezione 'ExpiredAnagrafica' generata per {Isin}", isin);
|
||||
|
||||
try
|
||||
var eventiRenderer = _sectionRenderers.First(r => r.SectionName == "Eventi");
|
||||
pdfSections.Add(eventiRenderer.Render(reportData));
|
||||
_logger.LogInformation("Sezione 'Eventi' generata per {Isin}", isin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Flusso attuale: Anagrafica + Eventi + Scenario (condizionale)
|
||||
bool isScenarioAllowed = reportData.Scenario.Rows.Count > 0;
|
||||
|
||||
foreach (var renderer in _sectionRenderers.OrderBy(r => r.Order))
|
||||
{
|
||||
var sectionPdf = renderer.Render(reportData);
|
||||
pdfSections.Add(sectionPdf);
|
||||
_logger.LogInformation("Sezione '{Section}' generata per {Isin}", renderer.SectionName, isin);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Errore nella generazione della sezione '{Section}' per {Isin}",
|
||||
renderer.SectionName, isin);
|
||||
throw;
|
||||
if (renderer.SectionName == "Scenario" && !isScenarioAllowed)
|
||||
{
|
||||
_logger.LogInformation("Sezione Scenario saltata per {Isin}", isin);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
pdfSections.Add(renderer.Render(reportData));
|
||||
_logger.LogInformation("Sezione '{Section}' generata per {Isin}", renderer.SectionName, isin);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Errore nella sezione '{Section}' per {Isin}", renderer.SectionName, isin);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 3. Genera/recupera il grafico ──────────────────────────────
|
||||
// ── 4. Grafico (entrambi i flussi) ────────────────────────────
|
||||
var chartPdf = await _chartRenderer.RenderAsync(isin);
|
||||
if (chartPdf != null)
|
||||
{
|
||||
@@ -101,20 +122,16 @@ public class ReportOrchestrator : IReportOrchestrator
|
||||
_logger.LogInformation("Sezione Grafico aggiunta per {Isin}", isin);
|
||||
}
|
||||
|
||||
// ── 4. Unisci tutto ────────────────────────────────────────────
|
||||
// ── 5. Unisci tutto ────────────────────────────────────────────
|
||||
var finalPdf = _merger.Merge(pdfSections);
|
||||
|
||||
_logger.LogInformation("Report generato per {Isin}: {Size} bytes, {Sections} sezioni",
|
||||
isin, finalPdf.Length, pdfSections.Count);
|
||||
|
||||
// Salva in cache
|
||||
_cache.Set(cacheKey, finalPdf);
|
||||
|
||||
// Cleanup
|
||||
foreach (var doc in pdfSections)
|
||||
{
|
||||
doc.Close(true);
|
||||
}
|
||||
|
||||
return finalPdf;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user