using DevExpress.Pdf; using DXApp.TemplateKitProject.Models; namespace DXApp.TemplateKitProject.Services; public class PdfResultPackageService( IConfiguration configuration, ILogger logger) { public async Task CreateResultPackageAsync( byte[] originalPdfBytes, string originalFileName, ZugferdInvoice invoice) { // 1. Bericht-PDF suchen var reportPath = FindReportFile(originalFileName); if (reportPath is null) { logger.LogWarning( "Kein Ergebnisbericht gefunden für '{FileName}'.", originalFileName); return null; } logger.LogInformation( "Ergebnisbericht gefunden: '{ReportPath}'.", reportPath); // 2. Ausgabepfad bestimmen var outputDir = configuration["PdfResults:OutputDirectory"] ?? Path.Combine(Path.GetTempPath(), "PdfResults"); Directory.CreateDirectory(outputDir); var baseName = Path.GetFileNameWithoutExtension(originalFileName); var outputPath = Path.Combine(outputDir, $"{baseName}_result.pdf"); // 3. Original auf PDF/A-3b hochstufen + Bericht anhängen await Task.Run(() => { using var inputStream = new MemoryStream(originalPdfBytes); // Schritt 1: PDF/A-3b Konvertierung PdfDocumentConverter converter; try { converter = new PdfDocumentConverter(inputStream); converter.Convert(PdfCompatibility.PdfA3b); } catch (Exception ex) { throw new InvalidOperationException( "Konvertierung nach PDF/A-3b fehlgeschlagen. " + "Die Originaldatei ist möglicherweise beschädigt oder nicht konvertierbar.", ex); } // Schritt 2: Konvertiertes PDF puffern using var convertedStream = new MemoryStream(); converter.SaveDocument(convertedStream); convertedStream.Position = 0; // Schritt 3: Anhang einbetten using var processor = new PdfDocumentProcessor(); processor.LoadDocument(convertedStream); processor.AttachFile(new PdfFileAttachment { FileName = Path.GetFileName(reportPath), Description = "Ergebnisbericht", MimeType = "application/pdf", Relationship = PdfAssociatedFileRelationship.Supplement, CreationDate = DateTime.Now, Data = File.ReadAllBytes(reportPath) }); // Schritt 4: Speichern try { processor.SaveDocument(outputPath); } catch (Exception ex) { throw new InvalidOperationException( $"Result-PDF konnte nicht gespeichert werden unter '{outputPath}'. " + "Prüfe ob das Verzeichnis existiert und beschreibbar ist.", ex); } }); logger.LogInformation( "Result-PDF gespeichert: '{OutputPath}'.", outputPath); return outputPath; } private string? FindReportFile(string originalFileName) { var inputDir = configuration["PdfResultReports:InputDirectory"] ?? Path.Combine(Path.GetTempPath(), "PdfResultReports"); if (!Directory.Exists(inputDir)) { logger.LogWarning("Berichtsverzeichnis nicht gefunden: '{Dir}'.", inputDir); return null; } // Konvention Option A: {originalname}_report.pdf var baseName = Path.GetFileNameWithoutExtension(originalFileName); var reportName = $"{baseName}_report.pdf"; var reportPath = Path.Combine(inputDir, reportName); return File.Exists(reportPath) ? reportPath : null; } }