# 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`, `:natixis` concatenati) - 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 | | PDF | 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 ```bash # Restore e build dotnet restore dotnet build # Run dotnet run --project CertReports.Syncfusion # → https://localhost:{porta}/api/report/by-isin/{ISIN} ``` ## Avvio con Docker ```bash 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:** ```json "ConnectionStrings": { "CertDb": "Data Source=tcp:IP;Initial Catalog=FirstSolutionDB;User Id=...;Password=...;Encrypt=False;" } ``` ## Aggiungere una nuova sezione PDF 1. Implementare `IPdfSectionRenderer` 2. Impostare `SectionName` e `Order` 3. Registrare in `Program.cs`: ```csharp builder.Services.AddScoped(); ``` 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](https://www.smart-roots.net)*