6.3 KiB
Design Spec: Report Certificati Non in Quotazione (Expired)
Data: 2026-03-21 Progetto: SmartReports / CertReports.Syncfusion Autore: Brainstorming session
Obiettivo
Implementare un secondo template di report PDF per certificati non più in quotazione (Stato: Revocato, Scaduto, Rimborsato). Il report mantiene lo stesso stile grafico del report attivo ma mostra meno informazioni: 3 pagine totali (Anagrafica semplificata + Lista Eventi + Grafico). Niente Scenario. Il rilevamento del tipo è automatico tramite il campo Stato restituito dalla SP esistente rpt_Master_CFT_ISIN.
Struttura del Report Expired (3 pagine)
| Pagina | Renderer | Contenuto |
|---|---|---|
| 1 | ExpiredAnagraficaSectionRenderer |
Titolo + Caratteristiche + Analisi |
| 2 | EventiSectionRenderer (riusato) |
Lista eventi (identica all'attuale) |
| 3 | ChartSectionRenderer (riusato) |
Grafico performance (identico all'attuale) |
Modifiche al Modello
CertificateInfo — aggiungere un campo
public string Stato { get; set; } = string.Empty;
// Valori possibili: "Quotazione" | "Revocato" | "Scaduto" | "Rimborsato"
CertificateDataService — mappare il nuovo campo
Nel metodo che chiama rpt_Master_CFT_ISIN, aggiungere la mappatura:
Stato = reader["Stato"]?.ToString() ?? string.Empty
Nessuna altra modifica alle query o agli altri servizi dati.
Nuovo Renderer: ExpiredAnagraficaSectionRenderer
File: CertReports.Syncfusion/Services/Implementations/ExpiredAnagraficaSectionRenderer.cs
Interfaccia: IPdfSectionRenderer
Order: 1
SectionName: "ExpiredAnagrafica"
Layout Pagina 1 (Portrait A4)
Blocco Titolo
- "Scheda Prodotto {ISIN}" — stesso stile del titolo attuale (font grande, colore AccentBlue)
- Riga sotto: "Tipologia: {Categoria}" — font normale
- Niente Bid/Ask, niente LastPriceDate
- Linea separatrice orizzontale blu (come attuale)
Blocco Caratteristiche Prodotto (tabella sinistra, stessa grafica attuale)
| Label | Campo modello |
|---|---|
| EMITTENTE | Info.Emittente |
| ISIN | Info.Isin |
| Mercato | Info.Mercato |
| Valuta | Info.Valuta |
| Data Emissione | Info.DataEmissione |
| Valore Rimborso | Info.ValoreRimborso |
| Data Rimborso | Info.DataRimborso |
Blocco Analisi (KV, stessa grafica attuale)
| Label | Campo modello |
|---|---|
| Importo Cedola (p.a.) | Info.NominalAnnualYield |
| Frequenza Cedola | Info.FrequenzaCedole |
| Valore Nominale | Info.NominalValue |
| Memoria Cedola | Info.Memory |
| Tipo Barriera | Info.BarrierType |
| Tipo Basket | Info.BasketType |
| Rendimento Totale | Info.RendimentoTotale |
Escluso dalla pagina 1
- Sezione Bid/Ask/LastPriceDate
- Tabella Sottostanti (sezione C del report attivo)
- Sezione cedole (CpnPagati/DaPagare/InMemoria)
- Sezione Analisi (8+9 KV del report attivo)
Footer
PdfTheme.DrawFooter(g, pageWidth, pageHeight, pageNumber, showBranding) — identico a tutti gli altri renderer, supporta il parametro branding.
Modifiche all'Orchestratore
ReportOrchestrator.cs
Dopo il caricamento dei dati (CertificateDataService), leggere data.Info.Stato per scegliere il flusso:
bool isExpired = data.Info.Stato != "Quotazione" && !string.IsNullOrEmpty(data.Info.Stato);
List<PdfDocument> sections;
if (isExpired)
{
// Flusso expired: ExpiredAnagrafica + Eventi + Chart
sections = new List<PdfDocument>
{
_expiredAnagraficaRenderer.Render(data),
eventiRenderer.Render(data),
// chart (async, può essere null)
};
}
else
{
// Flusso attuale: Anagrafica + Eventi + Scenario (condizionale) + Chart
// logica esistente invariata
}
Il renderer ExpiredAnagraficaSectionRenderer è iniettato direttamente nell'orchestratore (non via IEnumerable<IPdfSectionRenderer>) per evitare che venga incluso nel ciclo del flusso normale.
Cache — chiavi separate
| Scenario | Chiave cache |
|---|---|
| Attivo, no branding | {isin} |
| Attivo, branding | {isin}:branded |
| Expired, no branding | {isin}:expired |
| Expired, branding | {isin}:expired:branded |
Branding
Il parametro ?branding=true funziona identicamente al report attivo:
- Propagato come
CertificateReportData.ShowBranding - Passato a
PdfTheme.DrawFooter(..., showBranding)in ogni pagina del report expired - Footer sinistra: "Powered by " + hyperlink "Smart Roots" →
https://www.smart-roots.net - Footer destra: numero pagina
- Cache usa chiave
{isin}:expired:brandedvs{isin}:expired
Dependency Injection — Program.cs
// Registrazione diretta (non come IPdfSectionRenderer) per evitare inclusione nel ciclo normale
builder.Services.AddScoped<ExpiredAnagraficaSectionRenderer>();
Gli altri renderer esistenti rimangono invariati.
Endpoint
Nessun nuovo endpoint. Il rilevamento del tipo report è trasparente al chiamante. Tutti gli endpoint esistenti funzionano per entrambi i tipi:
| Endpoint | Comportamento |
|---|---|
GET /api/report?p={encrypted} |
Auto-rileva da Stato |
GET /api/report?alias={id} |
Auto-rileva da Stato |
GET /api/report/by-isin/{isin} |
Auto-rileva da Stato |
GET /api/report/download?p={...} |
Auto-rileva da Stato |
GET /api/report/download?alias={...} |
Auto-rileva da Stato |
| Tutti | Supportano ?branding=true |
File Modificati / Creati
| File | Tipo modifica |
|---|---|
Models/CertificateModels.cs |
Aggiunta campo Stato a CertificateInfo |
Services/Implementations/CertificateDataService.cs |
Mappatura campo Stato dalla SP |
Services/Implementations/ExpiredAnagraficaSectionRenderer.cs |
Nuovo file |
Services/Implementations/ReportOrchestrator.cs |
Logica branching expired/attivo + cache keys |
Program.cs |
Registrazione ExpiredAnagraficaSectionRenderer |
Non modificati
AnagraficaSectionRenderer.cs— invariatoEventiSectionRenderer.cs— riusato as-isScenarioSectionRenderer.cs— invariato (semplicemente non incluso nel flusso expired)ChartSectionRenderer.cs— riusato as-isPdfTheme.cs— invariatoReportController.cs— invariato- Tutti gli endpoint — invariati