feat: add sottostanti table to expired certificate report (sezione 1)
Adds the 9-column underlyings table (identical to the active report) to ExpiredAnagraficaSectionRenderer, with overflow-to-new-page guard. Also excludes Logs/** from csproj build and updates README accordingly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,13 +4,14 @@ using CertReports.Syncfusion.Services.Interfaces;
|
||||
using Syncfusion.Drawing;
|
||||
using Syncfusion.Pdf;
|
||||
using Syncfusion.Pdf.Graphics;
|
||||
using Syncfusion.Pdf.Grid;
|
||||
|
||||
namespace CertReports.Syncfusion.Services.Implementations;
|
||||
|
||||
/// <summary>
|
||||
/// Sezione 1 — Prima pagina del report per certificati non in quotazione
|
||||
/// (Scaduto, Rimborsato, Revocato). Struttura semplificata rispetto al report attivo:
|
||||
/// solo Titolo + Caratteristiche Prodotto + Analisi. Niente Bid/Ask, niente Sottostanti.
|
||||
/// (Scaduto, Rimborsato, Revocato). Struttura: Titolo + Caratteristiche Prodotto + Analisi + Sottostanti.
|
||||
/// Niente Bid/Ask nel titolo.
|
||||
/// </summary>
|
||||
public class ExpiredAnagraficaSectionRenderer : IPdfSectionRenderer
|
||||
{
|
||||
@@ -42,8 +43,24 @@ public class ExpiredAnagraficaSectionRenderer : IPdfSectionRenderer
|
||||
// ── SEZIONE B: ANALISI ────────────────────────────────────────
|
||||
y = DrawSectionLabel(g, "Analisi", y);
|
||||
y = DrawAnalisi(g, info, y);
|
||||
y += SectionGap;
|
||||
|
||||
PdfTheme.DrawFooter(g, PageW, PageH, 1, data.ShowBranding);
|
||||
// ── SEZIONE C: SOTTOSTANTI ────────────────────────────────────
|
||||
if (info.Sottostanti.Count > 0)
|
||||
{
|
||||
if (y > PageH - 80f)
|
||||
{
|
||||
PdfTheme.DrawFooter(g, PageW, PageH, 1, data.ShowBranding);
|
||||
page = doc.Pages.Add();
|
||||
g = page.Graphics;
|
||||
y = 0f;
|
||||
}
|
||||
|
||||
y = DrawSectionLabel(g, "Sottostanti", y);
|
||||
DrawSottostanti(g, info.Sottostanti, PageW, y);
|
||||
}
|
||||
|
||||
PdfTheme.DrawFooter(g, PageW, PageH, doc.Pages.Count, data.ShowBranding);
|
||||
|
||||
return doc;
|
||||
}
|
||||
@@ -201,6 +218,90 @@ public class ExpiredAnagraficaSectionRenderer : IPdfSectionRenderer
|
||||
return DrawKVList(g, items, 0, ColW, y);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// SEZIONE C: SOTTOSTANTI (9 colonne, font 7.5pt)
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
|
||||
private void DrawSottostanti(PdfGraphics g, List<Sottostante> sottostanti, float w, float y)
|
||||
{
|
||||
var grid = new PdfGrid();
|
||||
grid.Style.CellPadding = new PdfPaddings(2, 2, 2, 2);
|
||||
|
||||
string[] headers = { "Nome", "Strike", "Last", "% Perf.", "Barriera Capitale",
|
||||
"Buffer Capitale", "Trigger Cedola", "Buffer Cedola", "Trigger Autocall" };
|
||||
|
||||
foreach (var _ in headers) grid.Columns.Add();
|
||||
|
||||
var hr = grid.Headers.Add(1)[0];
|
||||
for (int i = 0; i < headers.Length; i++)
|
||||
{
|
||||
hr.Cells[i].Value = headers[i];
|
||||
hr.Cells[i].Style.Font = PdfTheme.TableBold;
|
||||
hr.Cells[i].Style.BackgroundBrush = PdfTheme.TableHeaderBrush;
|
||||
hr.Cells[i].Style.TextBrush = PdfTheme.HeaderTextBrush;
|
||||
hr.Cells[i].StringFormat = new PdfStringFormat(
|
||||
i == 0 ? PdfTextAlignment.Left : PdfTextAlignment.Center);
|
||||
}
|
||||
|
||||
for (int i = 0; i < sottostanti.Count; i++)
|
||||
{
|
||||
var s = sottostanti[i];
|
||||
var row = grid.Rows.Add();
|
||||
|
||||
row.Cells[0].Value = s.Nome;
|
||||
row.Cells[1].Value = s.Strike;
|
||||
row.Cells[2].Value = s.LastPrice;
|
||||
row.Cells[3].Value = s.Performance;
|
||||
row.Cells[4].Value = s.CapitalBarrier;
|
||||
row.Cells[5].Value = s.ULCapitalBarrierBuffer;
|
||||
row.Cells[6].Value = s.CouponBarrier;
|
||||
row.Cells[7].Value = s.ULCouponBarrierBuffer;
|
||||
row.Cells[8].Value = s.TriggerAutocall;
|
||||
|
||||
for (int c = 0; c < headers.Length; c++)
|
||||
{
|
||||
row.Cells[c].Style.Font = PdfTheme.TableFont;
|
||||
row.Cells[c].StringFormat = new PdfStringFormat(
|
||||
c == 0 ? PdfTextAlignment.Left : PdfTextAlignment.Right);
|
||||
}
|
||||
|
||||
ColorPerformanceCell(row.Cells[3], s.Performance);
|
||||
ColorPerformanceCell(row.Cells[5], s.ULCapitalBarrierBuffer);
|
||||
ColorPerformanceCell(row.Cells[7], s.ULCouponBarrierBuffer);
|
||||
|
||||
if (i % 2 == 1)
|
||||
for (int c = 0; c < headers.Length; c++)
|
||||
row.Cells[c].Style.BackgroundBrush = PdfTheme.TableAltRowBrush;
|
||||
}
|
||||
|
||||
float[] cw = { 90f, 52f, 52f, 46f, 52f, 46f, 52f, 46f, 46f };
|
||||
float total = cw.Sum();
|
||||
float scale = w / total;
|
||||
for (int i = 0; i < cw.Length; i++)
|
||||
grid.Columns[i].Width = cw[i] * scale;
|
||||
|
||||
PdfTheme.ApplyThinBorders(grid);
|
||||
grid.Draw(g, new PointF(0, y));
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// Helper
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
|
||||
private static bool IsNegativeValue(string? value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) return false;
|
||||
return value.TrimStart().StartsWith('-');
|
||||
}
|
||||
|
||||
private static void ColorPerformanceCell(PdfGridCell cell, string? value)
|
||||
{
|
||||
if (IsNegativeValue(value))
|
||||
cell.Style.TextBrush = new PdfSolidBrush(PdfTheme.NegativeRed);
|
||||
else if (!string.IsNullOrWhiteSpace(value) && value != "-" && value != "—")
|
||||
cell.Style.TextBrush = new PdfSolidBrush(PdfTheme.PositiveGreen);
|
||||
}
|
||||
|
||||
private float DrawKVList(PdfGraphics g, (string Label, string Value)[] items, float x, float w, float y)
|
||||
{
|
||||
float rh = PdfTheme.RowHeight;
|
||||
|
||||
Reference in New Issue
Block a user