Compare commits
11 Commits
5e9598e9dd
...
79b02b39b6
| Author | SHA1 | Date | |
|---|---|---|---|
| 79b02b39b6 | |||
| 7a3a8114bd | |||
| 716f191fc5 | |||
| 7595530490 | |||
| cd1a366f77 | |||
| 59ff3e9ac8 | |||
| df726306db | |||
| de9d235703 | |||
| 1bf99a917c | |||
| 2a10a058b3 | |||
| 998c24da31 |
@@ -44,7 +44,8 @@ public class ReportController : ControllerBase
|
|||||||
[FromQuery(Name = "p")] string? encryptedIsin = null,
|
[FromQuery(Name = "p")] string? encryptedIsin = null,
|
||||||
[FromQuery(Name = "alias")] string? aliasId = null,
|
[FromQuery(Name = "alias")] string? aliasId = null,
|
||||||
[FromQuery(Name = "branding")] bool showBranding = false,
|
[FromQuery(Name = "branding")] bool showBranding = false,
|
||||||
[FromQuery(Name = "dividend")] bool showDividend = false)
|
[FromQuery(Name = "dividend")] bool showDividend = false,
|
||||||
|
[FromQuery(Name = "natixis")] bool showNatixis = false)
|
||||||
{
|
{
|
||||||
string? isin = null;
|
string? isin = null;
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ public class ReportController : ControllerBase
|
|||||||
return BadRequest("Specificare il parametro 'p' (ISIN cifrato) o 'alias' (alias ID).");
|
return BadRequest("Specificare il parametro 'p' (ISIN cifrato) o 'alias' (alias ID).");
|
||||||
}
|
}
|
||||||
|
|
||||||
return await GenerateAndReturnPdf(isin, showBranding, showDividend);
|
return await GenerateAndReturnPdf(isin, showBranding, showDividend, showNatixis);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -82,14 +83,15 @@ public class ReportController : ControllerBase
|
|||||||
public async Task<IActionResult> GenerateReportByIsin(
|
public async Task<IActionResult> GenerateReportByIsin(
|
||||||
string isin,
|
string isin,
|
||||||
[FromQuery(Name = "branding")] bool showBranding = false,
|
[FromQuery(Name = "branding")] bool showBranding = false,
|
||||||
[FromQuery(Name = "dividend")] bool showDividend = false)
|
[FromQuery(Name = "dividend")] bool showDividend = false,
|
||||||
|
[FromQuery(Name = "natixis")] bool showNatixis = false)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(isin) || isin.Length < 12)
|
if (string.IsNullOrWhiteSpace(isin) || isin.Length < 12)
|
||||||
{
|
{
|
||||||
return BadRequest("ISIN non valido.");
|
return BadRequest("ISIN non valido.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return await GenerateAndReturnPdf(isin, showBranding, showDividend);
|
return await GenerateAndReturnPdf(isin, showBranding, showDividend, showNatixis);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -100,7 +102,8 @@ public class ReportController : ControllerBase
|
|||||||
[FromQuery(Name = "p")] string? encryptedIsin = null,
|
[FromQuery(Name = "p")] string? encryptedIsin = null,
|
||||||
[FromQuery(Name = "alias")] string? aliasId = null,
|
[FromQuery(Name = "alias")] string? aliasId = null,
|
||||||
[FromQuery(Name = "branding")] bool showBranding = false,
|
[FromQuery(Name = "branding")] bool showBranding = false,
|
||||||
[FromQuery(Name = "dividend")] bool showDividend = false)
|
[FromQuery(Name = "dividend")] bool showDividend = false,
|
||||||
|
[FromQuery(Name = "natixis")] bool showNatixis = false)
|
||||||
{
|
{
|
||||||
string? isin = null;
|
string? isin = null;
|
||||||
|
|
||||||
@@ -114,7 +117,7 @@ public class ReportController : ControllerBase
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var pdfBytes = await _orchestrator.GenerateReportAsync(isin, showBranding, showDividend);
|
var pdfBytes = await _orchestrator.GenerateReportAsync(isin, showBranding, showDividend, showNatixis);
|
||||||
return File(pdfBytes, "application/pdf", $"{isin}.pdf");
|
return File(pdfBytes, "application/pdf", $"{isin}.pdf");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -126,12 +129,12 @@ public class ReportController : ControllerBase
|
|||||||
|
|
||||||
// ─── Helper ────────────────────────────────────────────────────────
|
// ─── Helper ────────────────────────────────────────────────────────
|
||||||
|
|
||||||
private async Task<IActionResult> GenerateAndReturnPdf(string isin, bool showBranding = false, bool showDividend = false)
|
private async Task<IActionResult> GenerateAndReturnPdf(string isin, bool showBranding = false, bool showDividend = false, bool showNatixis = false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Richiesta report per ISIN {Isin}", isin);
|
_logger.LogInformation("Richiesta report per ISIN {Isin}", isin);
|
||||||
var pdfBytes = await _orchestrator.GenerateReportAsync(isin, showBranding, showDividend);
|
var pdfBytes = await _orchestrator.GenerateReportAsync(isin, showBranding, showDividend, showNatixis);
|
||||||
|
|
||||||
// Inline: il PDF si apre direttamente nel browser
|
// Inline: il PDF si apre direttamente nel browser
|
||||||
Response.Headers.Append("Content-Disposition", $"inline; filename={isin}.pdf");
|
Response.Headers.Append("Content-Disposition", $"inline; filename={isin}.pdf");
|
||||||
|
|||||||
@@ -161,4 +161,5 @@ public class CertificateReportData
|
|||||||
public byte[]? ChartImage { get; set; }
|
public byte[]? ChartImage { get; set; }
|
||||||
public bool ShowBranding { get; set; } = false;
|
public bool ShowBranding { get; set; } = false;
|
||||||
public bool ShowDividend { get; set; } = false;
|
public bool ShowDividend { get; set; } = false;
|
||||||
|
public bool ShowNatixis { get; set; } = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class AnagraficaSectionRenderer : IPdfSectionRenderer
|
|||||||
float y = 0f;
|
float y = 0f;
|
||||||
|
|
||||||
// ── TITOLO ────────────────────────────────────────────────────
|
// ── TITOLO ────────────────────────────────────────────────────
|
||||||
y = DrawTitle(g, info, PageW, y);
|
y = DrawTitle(g, info, PageW, y, data.ShowNatixis);
|
||||||
|
|
||||||
// ── SEZIONE A: CARATTERISTICHE PRODOTTO ───────────────────────
|
// ── SEZIONE A: CARATTERISTICHE PRODOTTO ───────────────────────
|
||||||
y = DrawSectionLabel(g, "Caratteristiche Prodotto", y);
|
y = DrawSectionLabel(g, "Caratteristiche Prodotto", y);
|
||||||
@@ -71,7 +71,7 @@ public class AnagraficaSectionRenderer : IPdfSectionRenderer
|
|||||||
// TITOLO centrato + riga box informativi (Tipologia/Data/Bid/Ask)
|
// TITOLO centrato + riga box informativi (Tipologia/Data/Bid/Ask)
|
||||||
// ═══════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y)
|
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y, bool showNatixis)
|
||||||
{
|
{
|
||||||
// ── Titolo centrato ──────────────────────────────────────────
|
// ── Titolo centrato ──────────────────────────────────────────
|
||||||
g.DrawString($"Scheda Prodotto {info.Isin}",
|
g.DrawString($"Scheda Prodotto {info.Isin}",
|
||||||
@@ -92,7 +92,8 @@ public class AnagraficaSectionRenderer : IPdfSectionRenderer
|
|||||||
const float bidW = 70f;
|
const float bidW = 70f;
|
||||||
const float askW = 70f;
|
const float askW = 70f;
|
||||||
|
|
||||||
bool showTip = !string.IsNullOrEmpty(info.Categoria);
|
string tipologia = showNatixis ? info.Nome : info.Categoria;
|
||||||
|
bool showTip = !string.IsNullOrEmpty(tipologia);
|
||||||
bool showData = !string.IsNullOrEmpty(info.LastPriceDate);
|
bool showData = !string.IsNullOrEmpty(info.LastPriceDate);
|
||||||
bool showBidAsk = !string.IsNullOrEmpty(info.Bid) && !string.IsNullOrEmpty(info.Ask);
|
bool showBidAsk = !string.IsNullOrEmpty(info.Bid) && !string.IsNullOrEmpty(info.Ask);
|
||||||
|
|
||||||
@@ -107,7 +108,7 @@ public class AnagraficaSectionRenderer : IPdfSectionRenderer
|
|||||||
if (showTip)
|
if (showTip)
|
||||||
{
|
{
|
||||||
DrawInfoBox(g, xCursor, y, tipW, boxH,
|
DrawInfoBox(g, xCursor, y, tipW, boxH,
|
||||||
"TIPOLOGIA", info.Categoria,
|
"TIPOLOGIA", tipologia,
|
||||||
PdfTheme.BoxLightBlueBgBrush, PdfTheme.AccentBlueBrush,
|
PdfTheme.BoxLightBlueBgBrush, PdfTheme.AccentBlueBrush,
|
||||||
PdfTheme.AccentBlueBrush, PdfTheme.AccentBlueDarkBrush,
|
PdfTheme.AccentBlueBrush, PdfTheme.AccentBlueDarkBrush,
|
||||||
PdfTheme.Bold);
|
PdfTheme.Bold);
|
||||||
@@ -325,6 +326,7 @@ public class AnagraficaSectionRenderer : IPdfSectionRenderer
|
|||||||
("Tipo Barriera", info.BarrierType ?? "-"),
|
("Tipo Barriera", info.BarrierType ?? "-"),
|
||||||
("Tipo Basket", info.BasketType ?? "-"),
|
("Tipo Basket", info.BasketType ?? "-"),
|
||||||
("Leva", string.IsNullOrWhiteSpace(info.Leva) ? "—" : info.Leva),
|
("Leva", string.IsNullOrWhiteSpace(info.Leva) ? "—" : info.Leva),
|
||||||
|
("Memoria", string.IsNullOrWhiteSpace(info.Memory) ? "—" : info.Memory),
|
||||||
};
|
};
|
||||||
|
|
||||||
var rightItems = new (string Label, string Value)[]
|
var rightItems = new (string Label, string Value)[]
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class ExpiredAnagraficaSectionRenderer : IPdfSectionRenderer
|
|||||||
float y = 0f;
|
float y = 0f;
|
||||||
|
|
||||||
// ── TITOLO ────────────────────────────────────────────────────
|
// ── TITOLO ────────────────────────────────────────────────────
|
||||||
y = DrawTitle(g, info, PageW, y);
|
y = DrawTitle(g, info, PageW, y, data.ShowNatixis);
|
||||||
|
|
||||||
// ── SEZIONE A: CARATTERISTICHE PRODOTTO ───────────────────────
|
// ── SEZIONE A: CARATTERISTICHE PRODOTTO ───────────────────────
|
||||||
y = DrawSectionLabel(g, "Caratteristiche Prodotto", y);
|
y = DrawSectionLabel(g, "Caratteristiche Prodotto", y);
|
||||||
@@ -69,7 +69,7 @@ public class ExpiredAnagraficaSectionRenderer : IPdfSectionRenderer
|
|||||||
// TITOLO — Solo Tipologia box (niente Data/Bid/Ask)
|
// TITOLO — Solo Tipologia box (niente Data/Bid/Ask)
|
||||||
// ═══════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y)
|
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y, bool showNatixis)
|
||||||
{
|
{
|
||||||
g.DrawString($"Scheda Prodotto {info.Isin}",
|
g.DrawString($"Scheda Prodotto {info.Isin}",
|
||||||
PdfTheme.SectionTitleFont,
|
PdfTheme.SectionTitleFont,
|
||||||
@@ -83,10 +83,11 @@ public class ExpiredAnagraficaSectionRenderer : IPdfSectionRenderer
|
|||||||
|
|
||||||
// Solo box Tipologia, niente Data/Bid/Ask
|
// Solo box Tipologia, niente Data/Bid/Ask
|
||||||
const float boxH = 28f;
|
const float boxH = 28f;
|
||||||
if (!string.IsNullOrEmpty(info.Categoria))
|
string tipologia = showNatixis ? info.Nome : info.Categoria;
|
||||||
|
if (!string.IsNullOrEmpty(tipologia))
|
||||||
{
|
{
|
||||||
DrawInfoBox(g, 0, y, w, boxH,
|
DrawInfoBox(g, 0, y, w, boxH,
|
||||||
"TIPOLOGIA", info.Categoria,
|
"TIPOLOGIA", tipologia,
|
||||||
PdfTheme.BoxLightBlueBgBrush, PdfTheme.AccentBlueBrush,
|
PdfTheme.BoxLightBlueBgBrush, PdfTheme.AccentBlueBrush,
|
||||||
PdfTheme.AccentBlueBrush, PdfTheme.AccentBlueDarkBrush,
|
PdfTheme.AccentBlueBrush, PdfTheme.AccentBlueDarkBrush,
|
||||||
PdfTheme.Bold);
|
PdfTheme.Bold);
|
||||||
@@ -208,7 +209,7 @@ public class ExpiredAnagraficaSectionRenderer : IPdfSectionRenderer
|
|||||||
("Importo Cedola (p.a.)", info.NominalAnnualYield),
|
("Importo Cedola (p.a.)", info.NominalAnnualYield),
|
||||||
("Frequenza Cedola", info.FrequenzaCedole),
|
("Frequenza Cedola", info.FrequenzaCedole),
|
||||||
("Valore Nominale", info.NominalValue?.ToString("N0") ?? string.Empty),
|
("Valore Nominale", info.NominalValue?.ToString("N0") ?? string.Empty),
|
||||||
("Memoria Cedola", info.Memory),
|
("Memoria", string.IsNullOrWhiteSpace(info.Memory) ? "—" : info.Memory),
|
||||||
("Tipo Barriera", info.BarrierType),
|
("Tipo Barriera", info.BarrierType),
|
||||||
("Barriera Capitale", info.LivelloBarriera),
|
("Barriera Capitale", info.LivelloBarriera),
|
||||||
("Rimborso Capitale", info.CapitalValue),
|
("Rimborso Capitale", info.CapitalValue),
|
||||||
|
|||||||
@@ -44,12 +44,17 @@ public class ReportOrchestrator : IReportOrchestrator
|
|||||||
_dividendRenderer = dividendRenderer;
|
_dividendRenderer = dividendRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<byte[]> GenerateReportAsync(string isin, bool showBranding = false, bool showDividend = false)
|
public async Task<byte[]> GenerateReportAsync(string isin, bool showBranding = false, bool showDividend = false, bool showNatixis = false)
|
||||||
{
|
{
|
||||||
// ── Cache check ────────────────────────────────────────────────
|
// ── Cache check ────────────────────────────────────────────────
|
||||||
var dividendSuffix = showDividend ? ":dividend" : "";
|
var dividendSuffix = showDividend ? ":dividend" : "";
|
||||||
var baseCacheKey = showBranding ? $"{isin}:branded{dividendSuffix}" : $"{isin}{dividendSuffix}";
|
var natixisSuffix = showNatixis ? ":natixis" : "";
|
||||||
var expiredCacheKey = showBranding ? $"{isin}:expired:branded{dividendSuffix}" : $"{isin}:expired{dividendSuffix}";
|
var baseCacheKey = showBranding
|
||||||
|
? $"{isin}:branded{dividendSuffix}{natixisSuffix}"
|
||||||
|
: $"{isin}{dividendSuffix}{natixisSuffix}";
|
||||||
|
var expiredCacheKey = showBranding
|
||||||
|
? $"{isin}:expired:branded{dividendSuffix}{natixisSuffix}"
|
||||||
|
: $"{isin}:expired{dividendSuffix}{natixisSuffix}";
|
||||||
|
|
||||||
var cached = _cache.Get(baseCacheKey) ?? _cache.Get(expiredCacheKey);
|
var cached = _cache.Get(baseCacheKey) ?? _cache.Get(expiredCacheKey);
|
||||||
if (cached != null)
|
if (cached != null)
|
||||||
@@ -68,6 +73,7 @@ public class ReportOrchestrator : IReportOrchestrator
|
|||||||
Scenario = await _dataService.GetScenarioAnalysisAsync(isin),
|
Scenario = await _dataService.GetScenarioAnalysisAsync(isin),
|
||||||
ShowBranding = showBranding,
|
ShowBranding = showBranding,
|
||||||
ShowDividend = showDividend,
|
ShowDividend = showDividend,
|
||||||
|
ShowNatixis = showNatixis,
|
||||||
};
|
};
|
||||||
|
|
||||||
// ── 2. Determina il tipo di report ────────────────────────────
|
// ── 2. Determina il tipo di report ────────────────────────────
|
||||||
|
|||||||
@@ -46,5 +46,5 @@ public interface IPdfMergerService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IReportOrchestrator
|
public interface IReportOrchestrator
|
||||||
{
|
{
|
||||||
Task<byte[]> GenerateReportAsync(string isin, bool showBranding = false, bool showDividend = false);
|
Task<byte[]> GenerateReportAsync(string isin, bool showBranding = false, bool showDividend = false, bool showNatixis = false);
|
||||||
}
|
}
|
||||||
|
|||||||
521
docs/superpowers/plans/2026-03-26-memoria-natixis.md
Normal file
521
docs/superpowers/plans/2026-03-26-memoria-natixis.md
Normal file
@@ -0,0 +1,521 @@
|
|||||||
|
# Memoria Field + Natixis Parameter — Implementation Plan
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** Add a "Memoria" KV field in the Analisi section of all reports, and a `?natixis` query param that switches the Tipologia source from `info.Categoria` to `info.Nome`.
|
||||||
|
|
||||||
|
**Architecture:** The `ShowNatixis` bool follows the existing `ShowBranding`/`ShowDividend` pattern: added to `CertificateReportData`, propagated from controller → orchestrator → renderers. Cache keys follow the existing suffix-concatenation pattern. The `DrawTitle` private method in both renderers gains a `bool showNatixis` parameter (Option A from spec).
|
||||||
|
|
||||||
|
**Tech Stack:** ASP.NET Core 8, Syncfusion PDF, C# 12
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Important Pre-Read
|
||||||
|
|
||||||
|
Before starting, note these facts about the existing code:
|
||||||
|
|
||||||
|
- `CertificateInfo.Memory` (string) **already exists** in `CertificateModels.cs:22` — no model/SP changes needed for Feature 1.
|
||||||
|
- `ExpiredAnagraficaSectionRenderer.DrawAnalisi` **already contains** `("Memoria Cedola", info.Memory)` at line 211 — it only needs to be **renamed** to `"Memoria"`.
|
||||||
|
- `AnagraficaSectionRenderer.DrawAnalisi` does **not** have the field — it needs to be **added** after `("Leva", ...)` at line 327.
|
||||||
|
- No automated tests exist in this project. Each task ends with `dotnet build` as verification.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## File Map
|
||||||
|
|
||||||
|
| File | Change |
|
||||||
|
|------|--------|
|
||||||
|
| `Models/CertificateModels.cs` | Add `bool ShowNatixis` to `CertificateReportData` |
|
||||||
|
| `Services/Interfaces/IServices.cs` | Add `showNatixis` param to `GenerateReportAsync` |
|
||||||
|
| `Controllers/ReportController.cs` | Add `[FromQuery] natixis` to all 3 endpoints + helper |
|
||||||
|
| `Services/Implementations/ReportOrchestrator.cs` | Add param, propagate flag, update cache key logic |
|
||||||
|
| `Services/Implementations/AnagraficaSectionRenderer.cs` | Add Memoria item in `DrawAnalisi`; add `showNatixis` to `DrawTitle` |
|
||||||
|
| `Services/Implementations/ExpiredAnagraficaSectionRenderer.cs` | Rename "Memoria Cedola"→"Memoria"; add `showNatixis` to `DrawTitle` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 1: Add `ShowNatixis` to `CertificateReportData`
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `CertReports.Syncfusion/Models/CertificateModels.cs` (around line 162)
|
||||||
|
|
||||||
|
- [ ] **Step 1: Add the property**
|
||||||
|
|
||||||
|
In `CertificateModels.cs`, find the `CertificateReportData` class:
|
||||||
|
```csharp
|
||||||
|
public class CertificateReportData
|
||||||
|
{
|
||||||
|
public CertificateInfo Info { get; set; } = new();
|
||||||
|
public List<CertificateEvent> Eventi { get; set; } = new();
|
||||||
|
public ScenarioAnalysis Scenario { get; set; } = new();
|
||||||
|
public byte[]? ChartImage { get; set; }
|
||||||
|
public bool ShowBranding { get; set; } = false;
|
||||||
|
public bool ShowDividend { get; set; } = false;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Add `ShowNatixis` after `ShowDividend`:
|
||||||
|
```csharp
|
||||||
|
public bool ShowDividend { get; set; } = false;
|
||||||
|
public bool ShowNatixis { get; set; } = false;
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Build**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet build CertReports.Syncfusion
|
||||||
|
```
|
||||||
|
Expected: Build succeeded, 0 errors.
|
||||||
|
|
||||||
|
- [ ] **Step 3: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add CertReports.Syncfusion/Models/CertificateModels.cs
|
||||||
|
git commit -m "feat: add ShowNatixis flag to CertificateReportData"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 2: Update `IReportOrchestrator` interface
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `CertReports.Syncfusion/Services/Interfaces/IServices.cs` (line 49)
|
||||||
|
|
||||||
|
- [ ] **Step 1: Update the signature**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
Task<byte[]> GenerateReportAsync(string isin, bool showBranding = false, bool showDividend = false);
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
Task<byte[]> GenerateReportAsync(string isin, bool showBranding = false, bool showDividend = false, bool showNatixis = false);
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Build**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet build CertReports.Syncfusion
|
||||||
|
```
|
||||||
|
Expected: **Build fails** with CS0535 ("ReportOrchestrator does not implement interface member GenerateReportAsync") — this is intentional and will be resolved in Task 4.
|
||||||
|
|
||||||
|
- [ ] **Step 3: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add CertReports.Syncfusion/Services/Interfaces/IServices.cs
|
||||||
|
git commit -m "feat: add showNatixis param to IReportOrchestrator interface"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 3: Update `ReportController`
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `CertReports.Syncfusion/Controllers/ReportController.cs`
|
||||||
|
|
||||||
|
- [ ] **Step 1: Update `GenerateReport` endpoint (line 43)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
public async Task<IActionResult> GenerateReport(
|
||||||
|
[FromQuery(Name = "p")] string? encryptedIsin = null,
|
||||||
|
[FromQuery(Name = "alias")] string? aliasId = null,
|
||||||
|
[FromQuery(Name = "branding")] bool showBranding = false,
|
||||||
|
[FromQuery(Name = "dividend")] bool showDividend = false)
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
public async Task<IActionResult> GenerateReport(
|
||||||
|
[FromQuery(Name = "p")] string? encryptedIsin = null,
|
||||||
|
[FromQuery(Name = "alias")] string? aliasId = null,
|
||||||
|
[FromQuery(Name = "branding")] bool showBranding = false,
|
||||||
|
[FromQuery(Name = "dividend")] bool showDividend = false,
|
||||||
|
[FromQuery(Name = "natixis")] bool showNatixis = false)
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Update the call to `GenerateAndReturnPdf` inside `GenerateReport` (line 74)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
return await GenerateAndReturnPdf(isin, showBranding, showDividend);
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
return await GenerateAndReturnPdf(isin, showBranding, showDividend, showNatixis);
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Update `GenerateReportByIsin` endpoint (line 82)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
public async Task<IActionResult> GenerateReportByIsin(
|
||||||
|
string isin,
|
||||||
|
[FromQuery(Name = "branding")] bool showBranding = false,
|
||||||
|
[FromQuery(Name = "dividend")] bool showDividend = false)
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
public async Task<IActionResult> GenerateReportByIsin(
|
||||||
|
string isin,
|
||||||
|
[FromQuery(Name = "branding")] bool showBranding = false,
|
||||||
|
[FromQuery(Name = "dividend")] bool showDividend = false,
|
||||||
|
[FromQuery(Name = "natixis")] bool showNatixis = false)
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: Update the call to `GenerateAndReturnPdf` inside `GenerateReportByIsin` (line 92)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
return await GenerateAndReturnPdf(isin, showBranding, showDividend);
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
return await GenerateAndReturnPdf(isin, showBranding, showDividend, showNatixis);
|
||||||
|
```
|
||||||
|
Note: there are two identical `return await GenerateAndReturnPdf(isin, showBranding, showDividend);` lines — make sure you update the one inside `GenerateReportByIsin` (around line 92).
|
||||||
|
|
||||||
|
- [ ] **Step 5: Update `DownloadReport` endpoint (line 99)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
public async Task<IActionResult> DownloadReport(
|
||||||
|
[FromQuery(Name = "p")] string? encryptedIsin = null,
|
||||||
|
[FromQuery(Name = "alias")] string? aliasId = null,
|
||||||
|
[FromQuery(Name = "branding")] bool showBranding = false,
|
||||||
|
[FromQuery(Name = "dividend")] bool showDividend = false)
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
public async Task<IActionResult> DownloadReport(
|
||||||
|
[FromQuery(Name = "p")] string? encryptedIsin = null,
|
||||||
|
[FromQuery(Name = "alias")] string? aliasId = null,
|
||||||
|
[FromQuery(Name = "branding")] bool showBranding = false,
|
||||||
|
[FromQuery(Name = "dividend")] bool showDividend = false,
|
||||||
|
[FromQuery(Name = "natixis")] bool showNatixis = false)
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 6: Update the `_orchestrator.GenerateReportAsync` call inside `DownloadReport` (line 117)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
var pdfBytes = await _orchestrator.GenerateReportAsync(isin, showBranding, showDividend);
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
var pdfBytes = await _orchestrator.GenerateReportAsync(isin, showBranding, showDividend, showNatixis);
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 7: Update `GenerateAndReturnPdf` helper signature (line 129)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
private async Task<IActionResult> GenerateAndReturnPdf(string isin, bool showBranding = false, bool showDividend = false)
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
private async Task<IActionResult> GenerateAndReturnPdf(string isin, bool showBranding = false, bool showDividend = false, bool showNatixis = false)
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 8: Update the `_orchestrator.GenerateReportAsync` call inside `GenerateAndReturnPdf` (line 134)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
var pdfBytes = await _orchestrator.GenerateReportAsync(isin, showBranding, showDividend);
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
var pdfBytes = await _orchestrator.GenerateReportAsync(isin, showBranding, showDividend, showNatixis);
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 9: Build**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet build CertReports.Syncfusion
|
||||||
|
```
|
||||||
|
Expected: Build succeeded.
|
||||||
|
|
||||||
|
- [ ] **Step 10: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add CertReports.Syncfusion/Controllers/ReportController.cs
|
||||||
|
git commit -m "feat: add natixis query param to all ReportController endpoints"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 4: Update `ReportOrchestrator`
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `CertReports.Syncfusion/Services/Implementations/ReportOrchestrator.cs`
|
||||||
|
|
||||||
|
- [ ] **Step 1: Update method signature (line 47)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
public async Task<byte[]> GenerateReportAsync(string isin, bool showBranding = false, bool showDividend = false)
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
public async Task<byte[]> GenerateReportAsync(string isin, bool showBranding = false, bool showDividend = false, bool showNatixis = false)
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Update cache key logic (lines 50-52)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
var dividendSuffix = showDividend ? ":dividend" : "";
|
||||||
|
var baseCacheKey = showBranding ? $"{isin}:branded{dividendSuffix}" : $"{isin}{dividendSuffix}";
|
||||||
|
var expiredCacheKey = showBranding ? $"{isin}:expired:branded{dividendSuffix}" : $"{isin}:expired{dividendSuffix}";
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
var dividendSuffix = showDividend ? ":dividend" : "";
|
||||||
|
var natixisSuffix = showNatixis ? ":natixis" : "";
|
||||||
|
var baseCacheKey = showBranding
|
||||||
|
? $"{isin}:branded{dividendSuffix}{natixisSuffix}"
|
||||||
|
: $"{isin}{dividendSuffix}{natixisSuffix}";
|
||||||
|
var expiredCacheKey = showBranding
|
||||||
|
? $"{isin}:expired:branded{dividendSuffix}{natixisSuffix}"
|
||||||
|
: $"{isin}:expired{dividendSuffix}{natixisSuffix}";
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Propagate `ShowNatixis` into `CertificateReportData` (lines 64-71)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
var reportData = new CertificateReportData
|
||||||
|
{
|
||||||
|
Info = await _dataService.GetCertificateInfoAsync(isin),
|
||||||
|
Eventi = await _dataService.GetCertificateEventsAsync(isin),
|
||||||
|
Scenario = await _dataService.GetScenarioAnalysisAsync(isin),
|
||||||
|
ShowBranding = showBranding,
|
||||||
|
ShowDividend = showDividend,
|
||||||
|
};
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
var reportData = new CertificateReportData
|
||||||
|
{
|
||||||
|
Info = await _dataService.GetCertificateInfoAsync(isin),
|
||||||
|
Eventi = await _dataService.GetCertificateEventsAsync(isin),
|
||||||
|
Scenario = await _dataService.GetScenarioAnalysisAsync(isin),
|
||||||
|
ShowBranding = showBranding,
|
||||||
|
ShowDividend = showDividend,
|
||||||
|
ShowNatixis = showNatixis,
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: Build**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet build CertReports.Syncfusion
|
||||||
|
```
|
||||||
|
Expected: Build succeeded, 0 errors.
|
||||||
|
|
||||||
|
- [ ] **Step 5: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add CertReports.Syncfusion/Services/Implementations/ReportOrchestrator.cs
|
||||||
|
git commit -m "feat: propagate showNatixis through orchestrator and cache keys"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 5: Update `AnagraficaSectionRenderer` (active certs)
|
||||||
|
|
||||||
|
Two changes: (A) add Memoria to `DrawAnalisi`, (B) support natixis in `DrawTitle`.
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `CertReports.Syncfusion/Services/Implementations/AnagraficaSectionRenderer.cs`
|
||||||
|
|
||||||
|
### Change A — Add Memoria to DrawAnalisi
|
||||||
|
|
||||||
|
- [ ] **Step 1: Add Memoria item after Leva (line 327)**
|
||||||
|
|
||||||
|
Find (this is the closing `};` of the `leftItems` array — NOT the `rightItems` array that follows a few lines later):
|
||||||
|
```csharp
|
||||||
|
("Leva", string.IsNullOrWhiteSpace(info.Leva) ? "—" : info.Leva),
|
||||||
|
};
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
("Leva", string.IsNullOrWhiteSpace(info.Leva) ? "—" : info.Leva),
|
||||||
|
("Memoria", string.IsNullOrWhiteSpace(info.Memory) ? "—" : info.Memory),
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Change B — Support Natixis in DrawTitle
|
||||||
|
|
||||||
|
- [ ] **Step 2: Update the `DrawTitle` call site in `Render` (line 37)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
y = DrawTitle(g, info, PageW, y);
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
y = DrawTitle(g, info, PageW, y, data.ShowNatixis);
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Update `DrawTitle` signature (line 74)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y)
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y, bool showNatixis)
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: Update Tipologia resolution in `DrawTitle` (line 95)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
bool showTip = !string.IsNullOrEmpty(info.Categoria);
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
string tipologia = showNatixis ? info.Nome : info.Categoria;
|
||||||
|
bool showTip = !string.IsNullOrEmpty(tipologia);
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 5: Replace `info.Categoria` with `tipologia` in the `DrawInfoBox` call (line 110)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
"TIPOLOGIA", info.Categoria,
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
"TIPOLOGIA", tipologia,
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 6: Build**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet build CertReports.Syncfusion
|
||||||
|
```
|
||||||
|
Expected: Build succeeded, 0 errors.
|
||||||
|
|
||||||
|
- [ ] **Step 7: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add CertReports.Syncfusion/Services/Implementations/AnagraficaSectionRenderer.cs
|
||||||
|
git commit -m "feat: add Memoria field to Analisi and natixis support to AnagraficaSectionRenderer"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 6: Update `ExpiredAnagraficaSectionRenderer` (expired certs)
|
||||||
|
|
||||||
|
Two changes: (A) rename "Memoria Cedola" → "Memoria" in `DrawAnalisi`, (B) support natixis in `DrawTitle`.
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `CertReports.Syncfusion/Services/Implementations/ExpiredAnagraficaSectionRenderer.cs`
|
||||||
|
|
||||||
|
### Change A — Rename label in DrawAnalisi
|
||||||
|
|
||||||
|
- [ ] **Step 1: Rename "Memoria Cedola" to "Memoria" (line 211)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
("Memoria Cedola", info.Memory),
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
("Memoria", info.Memory),
|
||||||
|
```
|
||||||
|
|
||||||
|
### Change B — Support Natixis in DrawTitle
|
||||||
|
|
||||||
|
- [ ] **Step 2: Update the `DrawTitle` call site in `Render` (line 36)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
y = DrawTitle(g, info, PageW, y);
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
y = DrawTitle(g, info, PageW, y, data.ShowNatixis);
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Update `DrawTitle` signature (line 72)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y)
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y, bool showNatixis)
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: Update Tipologia resolution in `DrawTitle` (line 86)**
|
||||||
|
|
||||||
|
Find:
|
||||||
|
```csharp
|
||||||
|
if (!string.IsNullOrEmpty(info.Categoria))
|
||||||
|
{
|
||||||
|
DrawInfoBox(g, 0, y, w, boxH,
|
||||||
|
"TIPOLOGIA", info.Categoria,
|
||||||
|
```
|
||||||
|
Replace with:
|
||||||
|
```csharp
|
||||||
|
string tipologia = showNatixis ? info.Nome : info.Categoria;
|
||||||
|
if (!string.IsNullOrEmpty(tipologia))
|
||||||
|
{
|
||||||
|
DrawInfoBox(g, 0, y, w, boxH,
|
||||||
|
"TIPOLOGIA", tipologia,
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 5: Build**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet build CertReports.Syncfusion
|
||||||
|
```
|
||||||
|
Expected: Build succeeded, 0 errors.
|
||||||
|
|
||||||
|
- [ ] **Step 6: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add CertReports.Syncfusion/Services/Implementations/ExpiredAnagraficaSectionRenderer.cs
|
||||||
|
git commit -m "feat: rename Memoria Cedola and add natixis support to ExpiredAnagraficaSectionRenderer"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 7: Manual Verification
|
||||||
|
|
||||||
|
- [ ] **Step 1: Run the application**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet run --project CertReports.Syncfusion
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Verify Memoria field (active cert)**
|
||||||
|
|
||||||
|
Open: `https://localhost:{port}/api/report/by-isin/{ISIN_ATTIVO}`
|
||||||
|
|
||||||
|
Expected: In the Analisi section (left column), "Memoria" appears below "Leva" as the 9th item. If `info.Memory` is empty, shows "—".
|
||||||
|
|
||||||
|
- [ ] **Step 3: Verify Memoria field (expired cert)**
|
||||||
|
|
||||||
|
Open: `https://localhost:{port}/api/report/by-isin/{ISIN_SCADUTO}`
|
||||||
|
|
||||||
|
Expected: In the Analisi section, the field is labeled "Memoria" (not "Memoria Cedola").
|
||||||
|
|
||||||
|
- [ ] **Step 4: Verify Natixis=false (default)**
|
||||||
|
|
||||||
|
Open: `https://localhost:{port}/api/report/by-isin/{ISIN}` (no natixis param)
|
||||||
|
|
||||||
|
Expected: Tipologia box shows `info.Categoria` — same as before.
|
||||||
|
|
||||||
|
- [ ] **Step 5: Verify Natixis=true**
|
||||||
|
|
||||||
|
Open: `https://localhost:{port}/api/report/by-isin/{ISIN}?natixis=true`
|
||||||
|
|
||||||
|
Expected: Tipologia box shows `info.Nome` instead of `info.Categoria`.
|
||||||
|
|
||||||
|
- [ ] **Step 6: Verify cache keys are independent**
|
||||||
|
|
||||||
|
Open the same ISIN first without natixis, then with `?natixis=true`. Both should generate fresh PDFs with the correct Tipologia value (not the cached one).
|
||||||
92
docs/superpowers/specs/2026-03-26-memoria-natixis-design.md
Normal file
92
docs/superpowers/specs/2026-03-26-memoria-natixis-design.md
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
# Design Spec: Campo Memoria + Parametro Natixis
|
||||||
|
|
||||||
|
**Data:** 2026-03-26
|
||||||
|
**Scope:** `CertReports.Syncfusion` — tutti i report (quotazione + expired)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Panoramica
|
||||||
|
|
||||||
|
Due feature indipendenti da aggiungere a tutti i report PDF generati dall'API:
|
||||||
|
|
||||||
|
1. **Campo Memoria** — nuovo KV nella sezione Analisi, subito dopo Leva, che mostra il valore del campo `Memory` della SP `rpt_Master_CFT_ISIN`.
|
||||||
|
2. **Parametro `?natixis`** — flag URL che modifica il campo Tipologia: se `true`, usa `info.Nome` dalla SP; se `false` (default), usa `info.Categoria` come adesso.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature 1: Campo Memoria
|
||||||
|
|
||||||
|
### Origine dati
|
||||||
|
- Il campo `Memory` (string) esiste già in `CertificateInfo` (riga 22 di `CertificateModels.cs`) e viene già letto dalla SP `rpt_Master_CFT_ISIN`.
|
||||||
|
- Nessuna modifica al modello o al data service necessaria.
|
||||||
|
|
||||||
|
### Rendering
|
||||||
|
- Aggiunto come 9° item nella **colonna sinistra** di `DrawAnalisi` in entrambi i renderer:
|
||||||
|
- `AnagraficaSectionRenderer` (report in quotazione)
|
||||||
|
- `ExpiredAnagraficaSectionRenderer` (report expired: Scaduto/Rimborsato/Revocato)
|
||||||
|
- Posizione: subito dopo `("Leva", ...)`.
|
||||||
|
- Valore: `string.IsNullOrWhiteSpace(info.Memory) ? "—" : info.Memory`
|
||||||
|
- La colonna sinistra passa da 8 a **9 item**, simmetrica alla colonna destra che ne ha già 9.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature 2: Parametro `?natixis`
|
||||||
|
|
||||||
|
### Comportamento
|
||||||
|
- `?natixis=false` (default): `Tipologia = info.Categoria` — comportamento invariato
|
||||||
|
- `?natixis=true`: `Tipologia = info.Nome` (campo Nome dalla SP `rpt_Master_CFT_ISIN`)
|
||||||
|
|
||||||
|
### Propagazione del flag
|
||||||
|
Il flag segue lo stesso pattern di `showBranding` e `showDividend`:
|
||||||
|
|
||||||
|
1. **`CertificateReportData`**: aggiungere `bool ShowNatixis { get; set; } = false;`
|
||||||
|
2. **`ReportController`**: aggiungere `[FromQuery(Name = "natixis")] bool showNatixis = false` a tutti e 3 gli endpoint (`GenerateReport`, `GenerateReportByIsin`, `DownloadReport`) e al metodo helper `GenerateAndReturnPdf`.
|
||||||
|
3. **`IReportOrchestrator` / `ReportOrchestrator.GenerateReportAsync`**: aggiungere parametro `bool showNatixis = false`, propagarlo in `CertificateReportData.ShowNatixis`.
|
||||||
|
4. **Renderer — `DrawTitle`**: i metodi privati `DrawTitle` in entrambi i renderer hanno firma `(PdfGraphics g, CertificateInfo info, float w, float y)` e non ricevono `CertificateReportData`. La strategia adottata è **Option A**: aggiungere `bool showNatixis` come parametro aggiuntivo e aggiornare il sito di chiamata in `Render` passando `data.ShowNatixis`.
|
||||||
|
```csharp
|
||||||
|
// firma aggiornata
|
||||||
|
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y, bool showNatixis)
|
||||||
|
// call site in Render
|
||||||
|
y = DrawTitle(g, info, PageW, y, data.ShowNatixis);
|
||||||
|
// uso interno
|
||||||
|
string tipologia = showNatixis ? info.Nome : info.Categoria;
|
||||||
|
```
|
||||||
|
Il guard di visibilità del box Tipologia va aggiornato di conseguenza:
|
||||||
|
```csharp
|
||||||
|
bool showTip = !string.IsNullOrEmpty(showNatixis ? info.Nome : info.Categoria);
|
||||||
|
```
|
||||||
|
Questo evita che il box venga soppresso quando `natixis=true` ma `Categoria` è vuota.
|
||||||
|
|
||||||
|
### Cache (Approccio A — flag concatenati)
|
||||||
|
La chiave cache segue il pattern esistente. Il suffisso `:natixis` si applica **sia al path base che al path expired** (`{isin}:expired`):
|
||||||
|
|
||||||
|
| Flags attivi | Chiave base | Chiave expired |
|
||||||
|
|---------------------------------|--------------------------------|---------------------------------------|
|
||||||
|
| nessuno | `{isin}` | `{isin}:expired` |
|
||||||
|
| branding | `{isin}:branded` | `{isin}:expired:branded` |
|
||||||
|
| natixis | `{isin}:natixis` | `{isin}:expired:natixis` |
|
||||||
|
| branding + natixis | `{isin}:branded:natixis` | `{isin}:expired:branded:natixis` |
|
||||||
|
| dividend | `{isin}:dividend` | n/a (dividend solo per expired path) |
|
||||||
|
|
||||||
|
La logica in `ReportOrchestrator` aggiunge `:natixis` a entrambe le chiavi (base ed expired) quando `showNatixis == true`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## File modificati
|
||||||
|
|
||||||
|
| File | Modifica |
|
||||||
|
|------|----------|
|
||||||
|
| `Models/CertificateModels.cs` | Aggiungere `bool ShowNatixis` a `CertificateReportData` |
|
||||||
|
| `Controllers/ReportController.cs` | Aggiungere param `natixis` a tutti gli endpoint |
|
||||||
|
| `Services/Interfaces/IServices.cs` | Aggiornare firma `GenerateReportAsync` |
|
||||||
|
| `Services/Implementations/ReportOrchestrator.cs` | Aggiungere param, propagare flag, aggiornare cache key |
|
||||||
|
| `Services/Implementations/AnagraficaSectionRenderer.cs` | Aggiungere Memoria in DrawAnalisi; usare ShowNatixis in DrawTitle |
|
||||||
|
| `Services/Implementations/ExpiredAnagraficaSectionRenderer.cs` | Stesse modifiche |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Non in scope
|
||||||
|
|
||||||
|
- Modifica al data service o alle stored procedure (i campi `Memory` e `Nome` sono già letti)
|
||||||
|
- Modifica a `EventiSectionRenderer`, `ScenarioSectionRenderer`, `ChartSectionRenderer`, `DividendSectionRenderer`
|
||||||
|
- Aggiornamento documentazione API pubblica
|
||||||
Reference in New Issue
Block a user