using DevExpress.XtraReports.UI; using DevExpress.XtraReports.Web.Extensions; using DXApp.TemplateKitProject.Data; using Microsoft.EntityFrameworkCore; namespace DXApp.TemplateKitProject.DevExpressExtensions; public class CustomReportStorageWebExtension : ReportStorageWebExtension { private readonly AppDbContext _db; private readonly ILogger _logger; public CustomReportStorageWebExtension( AppDbContext db, ILogger logger) { _db = db; _logger = logger; } public override bool CanSetData(string url) { // Wir erlauben KEIN Speichern von Änderungen über den Viewer // PDFs sind bei uns Read-Only im Viewer return false; } public override bool IsValidUrl(string url) { // Prüfen ob URL dem Format entspricht: "invoice-{id}" return url.StartsWith("invoice-", StringComparison.OrdinalIgnoreCase); } public override byte[] GetData(string url) { try { _logger.LogDebug("GetData aufgerufen für URL: {Url}", url); // URL-Format: "invoice-123" → ID extrahieren if (!url.StartsWith("invoice-", StringComparison.OrdinalIgnoreCase)) { _logger.LogWarning("Ungültige URL: {Url}", url); return Array.Empty(); } var idString = url.Substring("invoice-".Length); if (!int.TryParse(idString, out var invoiceId)) { _logger.LogWarning("Ungültige Invoice-ID in URL: {Url}", url); return Array.Empty(); } // Rechnung aus Datenbank laden var invoice = _db.ZugferdInvoices .AsNoTracking() .FirstOrDefault(i => i.Id == invoiceId); if (invoice == null) { _logger.LogWarning("Rechnung mit ID {Id} nicht gefunden.", invoiceId); return Array.Empty(); } // Prüfen ob ResultFilePath existiert if (string.IsNullOrEmpty(invoice.ResultFilePath)) { _logger.LogWarning( "Rechnung {Id} hat keine Result-PDF (ResultFilePath ist leer).", invoiceId); return Array.Empty(); } // Datei vom Dateisystem laden if (!File.Exists(invoice.ResultFilePath)) { _logger.LogError( "Result-PDF-Datei nicht gefunden: {Path}", invoice.ResultFilePath); return Array.Empty(); } var pdfBytes = File.ReadAllBytes(invoice.ResultFilePath); _logger.LogInformation( "Result-PDF geladen: Invoice {Id}, Größe: {Size} Bytes", invoiceId, pdfBytes.Length); return pdfBytes; } catch (Exception ex) { _logger.LogError(ex, "Fehler beim Laden der PDF für URL: {Url}", url); return Array.Empty(); } } public override Dictionary GetUrls() { // Diese Methode wird verwendet um eine Liste aller verfügbaren Reports zu liefern // Für unseren Use-Case nicht benötigt (wir laden immer spezifisch eine Invoice) return new Dictionary(); } public override void SetData(XtraReport report, string url) { // Nicht implementiert - wir erlauben kein Speichern über den Viewer throw new NotSupportedException( "Das Speichern von Reports über den Document Viewer ist nicht unterstützt."); } public override string SetNewData(XtraReport report, string defaultUrl) { // Nicht implementiert - wir erstellen keine neuen Reports über den Viewer throw new NotSupportedException( "Das Erstellen neuer Reports über den Document Viewer ist nicht unterstützt."); } }