SmartReports
Generatore di report PDF per certificati finanziari strutturati, sviluppato in ASP.NET Core 8 con libreria Syncfusion PDF (Community License) e SkiaSharp per i grafici.
Caratteristiche principali
- Generazione PDF multi-sezione da dati SQL Server
- Due template report: certificati in quotazione (4 sezioni) e certificati non in quotazione / scaduti / rimborsati / revocati (3 sezioni) — rilevamento automatico dal campo
Stato - Pagina dividendi opzionale (
?dividend=true): pagina landscape con tabella Sottostanti+Dividendi a header raggruppati (SOTTOSTANTE / BARRIERE / DIVIDENDI), inserita dopo la Sezione 1 - Grafico performance sottostanti (SkiaSharp → PNG in memoria)
- Footer con branding opzionale e hyperlink cliccabile
- Cache in memoria per ISIN già generati (chiavi separate per ogni combinazione di flag: suffissi
:branded,:dividend,:natixisconcatenati) - Endpoint per PDF inline, download, grafico standalone v1 e grafico V2 con multi-formato e salvataggio su disco
- Supporto Docker
Stack tecnologico
| Componente | Tecnologia |
|---|---|
| Framework | ASP.NET Core 8 |
| Syncfusion PDF v33 (Community License) | |
| Grafici | SkiaSharp |
| Database | SQL Server (Microsoft.Data.SqlClient v5) |
| Runtime | .NET 8 |
Struttura del report
Certificati in quotazione (Stato = "Quotazione") — 4 sezioni (+1 opzionale)
| Sezione | Contenuto |
|---|---|
| 1 — Anagrafica | Header con Tipologia / Data / Bid / Ask, caratteristiche prodotto, analisi KV (inclusi Direzione, RendimentoPotenziale, CategoryID), tabella sottostanti (omessa se ?dividend=true) |
1b — Sottostanti e Dividendi (opzionale, ?dividend=true) |
Pagina landscape: tabella unificata con colonne SOTTOSTANTE / BARRIERE / DIVIDENDI a 2 livelli di header |
| 2 — Eventi | Lista eventi cedole e autocall (tabella landscape multi-pagina) |
| 3 — Scenario | Scenari di rendimento (opzionale, saltato se assente) |
| 4 — Grafico | Performance storica dei sottostanti |
Certificati non in quotazione (Stato = "Scaduto" / "Rimborsato" / "Revocato") — 3 sezioni (+1 opzionale)
| Sezione | Contenuto |
|---|---|
| 1 — Anagrafica (semplificata) | Header con solo Tipologia, caratteristiche con Valore/Data Rimborso, analisi KV, tabella sottostanti (omessa se ?dividend=true) |
1b — Sottostanti e Dividendi (opzionale, ?dividend=true) |
Pagina landscape: tabella unificata con colonne SOTTOSTANTE / BARRIERE / DIVIDENDI a 2 livelli di header |
| 2 — Eventi | Lista eventi con colonne adattate (Barriera Cedola, Soglia Rimborso, Barriera Capitale, Rimborso Capitale) |
| 3 — Grafico | Performance storica dei sottostanti |
Il tipo di report viene selezionato automaticamente dall'orchestratore in base al campo Stato restituito dalla SP rpt_Master_CFT_ISIN.
API Endpoints
GET /api/report/by-isin/{ISIN} → PDF inline
GET /api/report?p={isin_cifrato} → PDF inline (ISIN cifrato)
GET /api/report?alias={id} → PDF inline (alias)
GET /api/report/download?p={...} → PDF come allegato
GET /api/chart/{isin} → Grafico standalone v1 (PNG/PDF)
GET /api/chart/v2/{isin} → Grafico standalone v2 (multi-formato, vedi sotto)
GET /health → Health check DB + chart service
Parametri opzionali accettati da tutti gli endpoint report:
| Parametro | Default | Effetto |
|---|---|---|
?branding=true |
false |
Aggiunge footer "Powered by Smart Roots" con hyperlink |
?dividend=true |
false |
Inserisce pagina landscape Sottostanti+Dividendi dopo la Sezione 1; omette la tabella sottostanti dalla Sezione 1 |
?natixis=true |
false |
Box Tipologia mostra info.Nome invece di info.Categoria |
I parametri sono combinabili, es. ?branding=true÷nd=true&natixis=true.
Grafico V2 — parametri
GET /api/chart/v2/{isin}[?format=png|jpg|jpeg|jpgEnc|pdf&width=&height=&save=true]
| Parametro | Valori | Effetto |
|---|---|---|
?format= |
png (default), jpg/jpeg, jpgEnc, pdf |
Formato output; jpgEnc usa filename da alias SP; pdf genera PDF landscape |
?save=true |
— | Salva il JPEG su disco (percorsi da ChartSettings:SavePath / SavePathEnc) — solo per jpg/jpeg/jpgEnc |
Colori grafico V2: CTF = nero #000000, WorstOf = rosso #CC0000, altri sottostanti = palette vivace (teal/amber/viola/celeste…), Barriera Capitale = marrone #715548.
Avvio locale
# Restore e build
dotnet restore
dotnet build
# Run
dotnet run --project CertReports.Syncfusion
# → https://localhost:{porta}/api/report/by-isin/{ISIN}
Avvio con Docker
docker-compose up --build
# → http://localhost:5080/api/report/by-isin/{ISIN}
Configurazione
| File | Scopo |
|---|---|
appsettings.json |
Connection string (CertDb), Syncfusion license key, CryptoSettings passphrase, cache TTL |
appsettings.Development.json |
Override per sviluppo locale (non deve contenere ConnectionStrings) |
Connection string SQL Server:
"ConnectionStrings": {
"CertDb": "Data Source=tcp:IP;Initial Catalog=FirstSolutionDB;User Id=...;Password=...;Encrypt=False;"
}
Aggiungere una nuova sezione PDF
- Implementare
IPdfSectionRenderer - Impostare
SectionNameeOrder - Registrare in
Program.cs:builder.Services.AddScoped<IPdfSectionRenderer, NuovaSezione>();
L'orchestratore la include automaticamente ordinandola per Order.
Tema grafico
Tutto il tema (colori, font, layout, brush/pen) è centralizzato in CertReports.Syncfusion/Helpers/PdfTheme.cs.
| Colore | Hex | Utilizzo |
|---|---|---|
| AccentBlue | #1565C0 |
Titoli, header tabelle, valori chiave |
| NegativeRed | #CC0000 |
Valori negativi |
| PositiveGreen | #2E7D32 |
Valori positivi |
Architettura
HTTP (ISIN) → ReportController → ReportOrchestrator
├── CertificateDataService (SP → anagrafica, sottostanti, eventi, scenario)
│
├── [Stato == "Quotazione"] ──────────────────────────────────────────
│ ├── AnagraficaSectionRenderer → PdfDocument (Sezione 1, senza tabella sottostanti se dividend=true)
│ ├── DividendSectionRenderer → PdfDocument (Sezione 1b, solo se ?dividend=true, landscape)
│ ├── EventiSectionRenderer → PdfDocument (Sezione 2)
│ ├── ScenarioSectionRenderer → PdfDocument (Sezione 3, opzionale)
│ └── ChartSectionRenderer → PdfDocument (Sezione 4)
│
├── [Stato != "Quotazione"] ─────────────────────────────────────────
│ ├── ExpiredAnagraficaSectionRenderer → PdfDocument (Sezione 1, senza tabella sottostanti se dividend=true)
│ ├── DividendSectionRenderer → PdfDocument (Sezione 1b, solo se ?dividend=true, landscape)
│ ├── EventiSectionRenderer → PdfDocument (Sezione 2, colonne adattate)
│ └── ChartSectionRenderer → PdfDocument (Sezione 3)
│
├── ChartDataService (SP → dati grafico v1)
├── SkiaChartRenderer → PNG in memoria (v1)
└── PdfMergerService → byte[] → Response
HTTP (ISIN) → ChartController → /api/chart/v2/{isin}
├── ChartDataServiceV2 (cedlab_Chart_UL1 + cedlab_Chart_AllSeriesV2)
└── SkiaChartRendererV2 → PNG/JPEG/PDF → Response (+ salvataggio disco se ?save=true)
Sviluppato da Smart Roots