diff --git a/DocumentService.Client/README.md b/DocumentService.Client/README.md index 3efe137..8837861 100644 --- a/DocumentService.Client/README.md +++ b/DocumentService.Client/README.md @@ -183,98 +183,73 @@ Alle Beispiele nutzen ausschließlich den statischen `Client`-Einstiegspunkt. Vo ### Workflows – Kombinierte Operationen -`Client.Workflows` fasst häufig benötigte Abläufe zusammen, die mehrere Einzelendpunkte orchestrieren. Die Validierung läuft dabei immer zuerst – die Folgeaktion wird nur bei einem gültigen Dokument ausgeführt. +`Client.Workflows` fasst häufig benötigte Abläufe zusammen, die mehrere Einzelendpunkte orchestrieren. Validierung und Extraktion laufen in einem einzigen Aufruf – das Ergebnis enthält immer beide Informationen. > Für Anwendungsfälle wie den **eParser** (Swiss QR Bill aus Eingangsrechnungen lesen) ist dies der empfohlene Einstiegspunkt. -#### Swiss QR Code – mit vorgelagerter Validierung +#### Swiss QR Code – Validierung und Extraktion in einem Schritt ```csharp using DocumentService.Client; +using DocumentService.Client.Models.Results; -// Variante A: byte[] byte[] pdfBytes = await File.ReadAllBytesAsync("rechnung.pdf"); -var result = await Client.Workflows.ExtractSwissQrCodeAsync(pdfBytes); +SwissQrCodeResult result = await Client.Workflows.InspectSwissQrCodeAsync(pdfBytes); -Console.WriteLine($"Betrag: {result?.Bill?.Amount} {result?.Bill?.Currency}"); -Console.WriteLine($"Empfänger: {result?.Bill?.Creditor?.Name}"); +// Validierungsergebnis ist immer verfügbar +Console.WriteLine($"Gültig: {result.Validation.IsValid}"); +Console.WriteLine($"Seiten: {result.Validation.PageCount}"); +Console.WriteLine($"Verschlüsselt: {result.Validation.IsEncrypted}"); -// Variante B: Stream -using var stream = File.OpenRead("rechnung.pdf"); -var result2 = await Client.Workflows.ExtractSwissQrCodeAsync(stream); - -// Variante C: Dateipfad -var result3 = await Client.Workflows.ExtractSwissQrCodeAsync("rechnung.pdf"); +// QR-Code nur auswerten wenn Dokument gültig war +if (result.QrCode is not null) +{ + Console.WriteLine($"Betrag: {result.QrCode.Bill?.Amount} {result.QrCode.Bill?.Currency}"); + Console.WriteLine($"Empfänger: {result.QrCode.Bill?.Creditor?.Name}"); +} +else +{ + Console.WriteLine("Kein Swiss QR Code gefunden oder Dokument ungültig."); +} ``` ```vbnet Imports DocumentService.Client +Imports DocumentService.Client.Models.Results -' Variante A: byte[] Dim pdfBytes = System.IO.File.ReadAllBytes("rechnung.pdf") -Dim result = Await Client.Workflows.ExtractSwissQrCodeAsync(pdfBytes) +Dim result As SwissQrCodeResult = Await Client.Workflows.InspectSwissQrCodeAsync(pdfBytes) -Console.WriteLine($"Betrag: {result?.Bill?.Amount} {result?.Bill?.Currency}") -Console.WriteLine($"Empfänger: {result?.Bill?.Creditor?.Name}") +Console.WriteLine($"Gültig: {result.Validation.IsValid}") +Console.WriteLine($"Seiten: {result.Validation.PageCount}") +Console.WriteLine($"Verschlüsselt: {result.Validation.IsEncrypted}") -' Variante B: Dateipfad -Dim result2 = Await Client.Workflows.ExtractSwissQrCodeAsync("rechnung.pdf") +If result.QrCode IsNot Nothing Then + Console.WriteLine($"Betrag: {result.QrCode.Bill?.Amount} {result.QrCode.Bill?.Currency}") + Console.WriteLine($"Empfänger: {result.QrCode.Bill?.Creditor?.Name}") +Else + Console.WriteLine("Kein Swiss QR Code gefunden oder Dokument ungültig.") +End If ``` ```powershell Add-Type -Path "DocumentService.Client.dll" -# Variante A: byte[] $pdfBytes = [System.IO.File]::ReadAllBytes("rechnung.pdf") -$result = [DocumentService.Client.Client]::Workflows.ExtractSwissQrCodeAsync($pdfBytes).GetAwaiter().GetResult() -Write-Host "Betrag: $($result.Bill.Amount) $($result.Bill.Currency)" -Write-Host "Empfaenger:$($result.Bill.Creditor.Name)" +$result = [DocumentService.Client.Client]::Workflows.InspectSwissQrCodeAsync($pdfBytes).GetAwaiter().GetResult() -# Variante B: Dateipfad -$result2 = [DocumentService.Client.Client]::Workflows.ExtractSwissQrCodeAsync("rechnung.pdf").GetAwaiter().GetResult() -``` +Write-Host "Gueltig: $($result.Validation.IsValid)" +Write-Host "Seiten: $($result.Validation.PageCount)" +Write-Host "Verschluesselt:$($result.Validation.IsEncrypted)" -**Fehlerbehandlung – `throwIfInvalid`:** - -Standardmäßig wirft die Methode eine `InvalidOperationException`, wenn das PDF ungültig ist. Mit `throwIfInvalid: false` wird stattdessen `null` zurückgegeben – geeignet, wenn ungültige Dokumente kein Ausnahmefall sind und ohne try/catch behandelt werden sollen. - -```csharp -// Exception (Standard) – geeignet, wenn ungültige PDFs ein Fehlerfall sind -var result = await Client.Workflows.ExtractSwissQrCodeAsync(pdfBytes); - -// Null zurückgeben – geeignet für Batch-Verarbeitung o. Ä. -var result = await Client.Workflows.ExtractSwissQrCodeAsync(pdfBytes, throwIfInvalid: false); -if (result is null) -{ - Console.WriteLine("Dokument ungültig oder verschlüsselt – übersprungen."); +if ($null -ne $result.QrCode) { + Write-Host "Betrag: $($result.QrCode.Bill.Amount) $($result.QrCode.Bill.Currency)" + Write-Host "Empfaenger:$($result.QrCode.Bill.Creditor.Name)" +} else { + Write-Host "Kein Swiss QR Code gefunden oder Dokument ungueltig." } ``` -```vbnet -' Exception (Standard) -Dim result = Await Client.Workflows.ExtractSwissQrCodeAsync(pdfBytes) - -' Null zurückgeben -Dim result2 = Await Client.Workflows.ExtractSwissQrCodeAsync(pdfBytes, throwIfInvalid:=False) -If result2 Is Nothing Then - Console.WriteLine("Dokument ungültig oder verschlüsselt – übersprungen.") -End If -``` - -```powershell -# Exception (Standard) -$result = [DocumentService.Client.Client]::Workflows.ExtractSwissQrCodeAsync($pdfBytes).GetAwaiter().GetResult() - -# Null zurückgeben ($false = throwIfInvalid:false) -$result2 = [DocumentService.Client.Client]::Workflows.ExtractSwissQrCodeAsync($pdfBytes, $false, $false).GetAwaiter().GetResult() -if ($null -eq $result2) { - Write-Host "Dokument ungueltig oder verschluesselt – uebersprungen." -} -``` - -> **Signatur:** `ExtractSwissQrCodeAsync(pdfBytes / Stream / filePath, raw = false, throwIfInvalid = true, ct = default)` -> `raw: true` liefert die Rohtextzeilen des QR-Codes ohne Parsing zurück (siehe [Schweizer QR-Code-Extraktion](#4-schweizer-qr-code-extraktion)). - --- ### 1. PDF-Validierung @@ -1085,7 +1060,7 @@ Sobald die Endpunkte auf dem Server bereitgestellt werden, entfällt das `[Obsol | `Client.Zugferd` | `ExtractAsResultAsync()` | `POST /api/pdf/zugferd/extract` | ✅ Verfügbar | ZUGFeRD-XML mit Metadaten als Objekt | | `Client.Conversion` | `ToPdfAAsync()` | `POST /api/pdf/conversion/to-pdfa` | ⏳ Geplant | PDF zu PDF/A konvertieren | | `Client.Conversion` | `FromPdfAAsync()` | `POST /api/pdf/conversion/from-pdfa` | ⏳ Geplant | PDF/A-Einschränkungen aufheben | -| `Client.Workflows` | `ExtractSwissQrCodeAsync()` | — | ✅ Verfügbar | Validierung + Swiss QR Code Extraktion in einem Schritt | +| `Client.Workflows` | `InspectSwissQrCodeAsync()` | — | ✅ Verfügbar | Validierung + Swiss QR Code Extraktion; gibt immer `SwissQrCodeResult` zurück, wirft nie | > **⏳ Geplant:** Der Client-Code ist vorhanden und kompiliert fehlerfrei. Ein Aufruf zur Laufzeit wirft jedoch `NotImplementedException`, da der serverseitige Endpunkt noch nicht existiert. Die Methoden sind mit `[Obsolete]` markiert, sodass der Compiler eine Build-Warnung ausgibt.