Add ExtractSwissQrCode feature and update feature order
Updated PHASENPLAN.md and ROADMAP.md to reflect the new feature order, making "ExtractSwissQrCode" Feature 2 and renumbering previous Features 2-5 to 3-6. Added detailed steps, endpoints, and acceptance criteria for the new feature. Implemented `ISwissQrCodeProcessor` interface with `DevExpressSwissQrCodeProcessor` for extracting and parsing Swiss QR Codes using DevExpress and Codecrete libraries. Registered the new service in DependencyInjection.cs. Introduced `SwissQrCodeData` value object and `SwissQrCodeNotFoundException` for domain modeling and error handling. Updated project dependencies to include libraries for QR code processing. Adjusted existing feature descriptions and steps to align with the new feature order.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# ?? DocumentOperator - Phasenplan (Feature-Driven Development)
|
||||
|
||||
> **Stand:** 17.01.2025 | **Aktuell:** Feature 1 - ValidatePDF ? ABGESCHLOSSEN! | **Projektdauer:** 6 Wochen
|
||||
> **Stand:** 17.01.2025 | **Aktuell:** Feature 2 - ExtractSwissQrCode ? IN PROGRESS | **Projektdauer:** 6 Wochen
|
||||
|
||||
---
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
| Woche | Features / Concerns | Status | Fortschritt |
|
||||
|-------|---------------------|--------|-------------|
|
||||
| **W1** | Feature 1: ValidatePDF | ? Abgeschlossen | 100% (Foundation + Application + API + Swagger fertig) |
|
||||
| **W2** | Feature 2: ExtractAttachments | ? Geplant | 0% |
|
||||
| **W2** | Feature 3: ApplyStamp | ? Geplant | 0% |
|
||||
| **W3** | Feature 4: EmbedCertificate | ? Geplant | 0% |
|
||||
| **W3** | Feature 5: ConcatenatePDFs (Async) | ? Geplant | 0% |
|
||||
| **W1-W2** | Feature 2: ExtractSwissQrCode | ? In Progress | 0% (Gerade gestartet!) |
|
||||
| **W2** | Feature 3: ExtractAttachments | ? Geplant | 0% |
|
||||
| **W2** | Feature 4: ApplyStamp | ? Geplant | 0% |
|
||||
| **W3** | Feature 5: EmbedCertificate | ? Geplant | 0% |
|
||||
| **W3** | Feature 6: ConcatenatePDFs (Async) | ? Geplant | 0% |
|
||||
| **W4** | Multi-Tenancy (X-API-Key Header) | ? Geplant | 0% |
|
||||
| **W5** | Health Checks + Polly + Logging | ? Geplant | 0% |
|
||||
| **W6** | Production Deployment | ? Geplant | 0% |
|
||||
@@ -169,19 +170,52 @@
|
||||
|
||||
---
|
||||
|
||||
### WOCHE 2 - Features 2 & 3 | ? Geplant - 0%
|
||||
### WOCHE 1-2 - Feature 2: ExtractSwissQrCode | ? In Progress - 0%
|
||||
|
||||
#### Feature 2: ExtractAttachments (Synchron)
|
||||
**Dauer:** ~1-2 Tage
|
||||
**Status:** ? In Progress (gerade gestartet!)
|
||||
|
||||
**Endpoint:** POST /api/v1/documents/extract-swiss-qr-code
|
||||
|
||||
**Was wird gebaut:**
|
||||
- Client sendet Referenzen (Array) + PDF (Base64)
|
||||
- API extrahiert Swiss QR Code von **letzter Seite**
|
||||
- API gibt Referenzen + alle QR Code Felder zurück (Swiss QR Bill Standard 2.0)
|
||||
|
||||
**Technologie:**
|
||||
- **DevExpress PDF Document API** (PDF-Zugriff, letzte Seite)
|
||||
- **Codecrete.SwissQRBill.Generator** (Swiss QR Code Parsing - Standard 2.0)
|
||||
|
||||
**Steps:**
|
||||
- ?? Step 2.1: Domain Layer (SwissQrCodeData Value Object)
|
||||
- ?? Step 2.2: Infrastructure Layer (IQrCodeProcessor + DevExpressSwissQrCodeProcessor + Codecrete Integration)
|
||||
- ?? Step 2.3: Application Layer (ExtractSwissQrCodeQuery + Handler + Validator)
|
||||
- ?? Step 2.4: API Layer (Endpoint + Integration Tests)
|
||||
- ?? Step 2.5: Swagger Dokumentation
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- ? QR Code wird von letzter Seite extrahiert
|
||||
- ? Alle Swiss QR Bill Felder werden geparst (Standard 2.0)
|
||||
- ? Referenzen werden durchgeschliffen (Echo)
|
||||
- ? Fehler wenn kein QR Code gefunden
|
||||
- ? Swagger-testbar
|
||||
- ? Tests grün
|
||||
|
||||
---
|
||||
|
||||
### WOCHE 2 - Features 3 & 4 | ? Geplant - 0%
|
||||
|
||||
#### Feature 3: ExtractAttachments (Synchron)
|
||||
**Dauer:** ~1 Tag
|
||||
**Status:** ? Pending
|
||||
|
||||
**Endpoint:** POST /api/v1/documents/extract-attachments
|
||||
|
||||
**Steps:**
|
||||
- ? Step 2.1: Infrastructure Layer (DevExpressPdfProcessor.ExtractAttachmentsAsync)
|
||||
- ? Step 2.2: Application Layer (ExtractAttachmentsCommand + Handler + Validator)
|
||||
- ? Step 2.3: API Layer (Endpoint)
|
||||
- ? Step 2.4: Swagger Dokumentation
|
||||
- ? Step 3.1: Infrastructure Layer (DevExpressPdfProcessor.ExtractAttachmentsAsync)
|
||||
- ? Step 3.2: Application Layer (ExtractAttachmentsCommand + Handler + Validator)
|
||||
- ? Step 3.3: API Layer (Endpoint)
|
||||
- ? Step 3.4: Swagger Dokumentation
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- ? Endpoint im Swagger testbar
|
||||
@@ -189,17 +223,17 @@
|
||||
|
||||
---
|
||||
|
||||
#### Feature 3: ApplyStamp (Synchron)
|
||||
#### Feature 4: ApplyStamp (Synchron)
|
||||
**Dauer:** ~1 Tag
|
||||
**Status:** ? Pending
|
||||
|
||||
**Endpoint:** POST /api/v1/documents/apply-stamp
|
||||
|
||||
**Steps:**
|
||||
- ? Step 3.1: Infrastructure Layer (DevExpressPdfProcessor.ApplyStampAsync)
|
||||
- ? Step 3.2: Application Layer (ApplyStampCommand + Handler + Validator)
|
||||
- ? Step 3.3: API Layer (Endpoint)
|
||||
- ? Step 3.4: Swagger Dokumentation
|
||||
- ? Step 4.1: Infrastructure Layer (DevExpressPdfProcessor.ApplyStampAsync)
|
||||
- ? Step 4.2: Application Layer (ApplyStampCommand + Handler + Validator)
|
||||
- ? Step 4.3: API Layer (Endpoint)
|
||||
- ? Step 4.4: Swagger Dokumentation
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- ? Endpoint im Swagger testbar
|
||||
@@ -208,19 +242,19 @@
|
||||
|
||||
---
|
||||
|
||||
### WOCHE 3 - Features 4 & 5 | ? Geplant - 0%
|
||||
### WOCHE 3 - Features 5 & 6 | ? Geplant - 0%
|
||||
|
||||
#### Feature 4: EmbedCertificate (Synchron)
|
||||
#### Feature 5: EmbedCertificate (Synchron)
|
||||
**Dauer:** ~1 Tag
|
||||
**Status:** ? Pending
|
||||
|
||||
**Endpoint:** POST /api/v1/documents/embed-certificate
|
||||
|
||||
**Steps:**
|
||||
- ? Step 4.1: Infrastructure Layer (DevExpressPdfProcessor.EmbedCertificateAsync)
|
||||
- ? Step 4.2: Application Layer (EmbedCertificateCommand + Handler + Validator)
|
||||
- ? Step 4.3: API Layer (Endpoint)
|
||||
- ? Step 4.4: Swagger Dokumentation
|
||||
- ? Step 5.1: Infrastructure Layer (DevExpressPdfProcessor.EmbedCertificateAsync)
|
||||
- ? Step 5.2: Application Layer (EmbedCertificateCommand + Handler + Validator)
|
||||
- ? Step 5.3: API Layer (Endpoint)
|
||||
- ? Step 5.4: Swagger Dokumentation
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- ? Endpoint im Swagger testbar
|
||||
@@ -229,7 +263,7 @@
|
||||
|
||||
---
|
||||
|
||||
#### Feature 5: ConcatenatePDFs (Asynchron)
|
||||
#### Feature 6: ConcatenatePDFs (Asynchron)
|
||||
**Dauer:** ~2 Tage
|
||||
**Status:** ? Pending
|
||||
|
||||
@@ -239,10 +273,10 @@
|
||||
- GET /api/v1/jobs/{jobId}/download (Ergebnis herunterladen)
|
||||
|
||||
**Steps:**
|
||||
- ? Step 5.1: Infrastructure Layer (In-Memory Queue + Background Worker)
|
||||
- ? Step 5.2: Application Layer (SubmitConcatenateJobCommand + GetJobStatusQuery)
|
||||
- ? Step 5.3: API Layer (Async Endpoints)
|
||||
- ? Step 5.4: Swagger Dokumentation
|
||||
- ? Step 6.1: Infrastructure Layer (In-Memory Queue + Background Worker)
|
||||
- ? Step 6.2: Application Layer (SubmitConcatenateJobCommand + GetJobStatusQuery)
|
||||
- ? Step 6.3: API Layer (Async Endpoints)
|
||||
- ? Step 6.4: Swagger Dokumentation
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- ? POST /concatenate gibt JobId zurück
|
||||
@@ -453,16 +487,21 @@
|
||||
|
||||
### Nächstes Feature
|
||||
|
||||
**Feature 2: ExtractAttachments** - **NEXT**
|
||||
1. ? Step 2.1: Infrastructure Layer (DevExpressPdfProcessor.ExtractAttachmentsAsync)
|
||||
2. ? Step 2.2: Application Layer (ExtractAttachmentsCommand + Handler + Validator + DTOs)
|
||||
3. ? Step 2.3: API Layer (Endpoint + Integration Tests)
|
||||
4. ? Step 2.4: Swagger Dokumentation
|
||||
**Feature 2: ExtractSwissQrCode** - **IN PROGRESS**
|
||||
1. ?? Step 2.1: Domain Layer (SwissQrCodeData Value Object)
|
||||
2. ?? Step 2.2: Infrastructure Layer (IQrCodeProcessor + DevExpressSwissQrCodeProcessor + Codecrete Integration)
|
||||
3. ?? Step 2.3: Application Layer (ExtractSwissQrCodeQuery + Handler + Validator + DTOs)
|
||||
4. ?? Step 2.4: API Layer (Endpoint + Integration Tests)
|
||||
5. ?? Step 2.5: Swagger Dokumentation
|
||||
|
||||
**Erwarteter Zeitaufwand:** ~1 Tag
|
||||
**Erwarteter Zeitaufwand:** ~1-2 Tage
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- ? POST /api/v1/documents/extract-attachments im Swagger testbar
|
||||
- ? POST /api/v1/documents/extract-swiss-qr-code im Swagger testbar
|
||||
- ? Swiss QR Code wird von letzter Seite extrahiert
|
||||
- ? Alle Swiss QR Bill Felder geparst (Standard 2.0)
|
||||
- ? Referenzen durchgeschliffen
|
||||
- ? Fehler wenn kein QR Code gefunden
|
||||
- ? Alle Tests grün
|
||||
- ? Clean Architecture eingehalten
|
||||
|
||||
@@ -483,6 +522,8 @@
|
||||
| 17.01.2025 | **Feature 1** | ? **KOMPLETT ABGESCHLOSSEN** - ValidatePDF Feature testbar im Swagger UI! |
|
||||
| 17.01.2025 | **Fix: Attachment Detection (Multiple Attachments)** | ? **KORRIGIERT** - ValidatePDF erkennt jetzt auch PDFs mit mehreren Attachments korrekt (globale Suche statt 1000-Zeichen-Limit) - 13/13 Tests grün |
|
||||
| 17.01.2025 | **Fix: Attachment Count (6 Attachments)** | ? **KORRIGIERT** - AttachmentCount wird jetzt korrekt gezählt (objectCount statt objectCount/2). PDFs mit 6 Attachments werden korrekt erkannt - 13/13 Tests grün |
|
||||
| 17.01.2025 | **PHASENPLAN** | ?? **Feature-Reihenfolge geändert** - Neues Feature 2: ExtractSwissQrCode (Swiss QR Bill Standard 2.0) eingefügt. Alte Features 2-5 werden zu Features 3-6. |
|
||||
| 17.01.2025 | **Feature 2 - ExtractSwissQrCode** | ?? **GESTARTET** - Swiss QR Code Extraktion von letzter PDF-Seite (DevExpress + Codecrete.SwissQRBill.Generator) |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -45,10 +45,11 @@
|
||||
| Feature | Type | Status | Swagger Testbar? |
|
||||
|---------|------|--------|------------------|
|
||||
| **1. ValidatePDF** | Synchron | ? Abgeschlossen | ? |
|
||||
| **2. ExtractAttachments** | Synchron | ? Pending | ? |
|
||||
| **3. ApplyStamp** | Synchron | ? Pending | ? |
|
||||
| **4. EmbedCertificate** | Synchron | ? Pending | ? |
|
||||
| **5. ConcatenatePDFs** | Asynchron | ? Pending | ? |
|
||||
| **2. ExtractSwissQrCode** | Synchron | ? In Progress | ? |
|
||||
| **3. ExtractAttachments** | Synchron | ? Pending | ? |
|
||||
| **4. ApplyStamp** | Synchron | ? Pending | ? |
|
||||
| **5. EmbedCertificate** | Synchron | ? Pending | ? |
|
||||
| **6. ConcatenatePDFs** | Asynchron | ? Pending | ? |
|
||||
|
||||
### ?? Cross-Cutting Concerns (nach Features 1-4)
|
||||
|
||||
@@ -278,11 +279,85 @@ Response: { "pageCount": 5, "fileSizeBytes": 1024, "pdfVersion": "1.4", "hasAtta
|
||||
- ? Swagger-Dokumentation vollständig
|
||||
|
||||
**Nächstes Feature:**
|
||||
? **Feature 2: ExtractAttachments**
|
||||
? **Feature 2: ExtractSwissQrCode**
|
||||
|
||||
---
|
||||
|
||||
## ?? FEATURE 2: ExtractAttachments (Synchron) - **NEXT**
|
||||
## ?? FEATURE 2: ExtractSwissQrCode (Synchron) - **IN PROGRESS**
|
||||
|
||||
**Was macht dieses Feature?**
|
||||
- Client sendet PDF als Base64 + Referenzen (Array von Strings)
|
||||
- API extrahiert Swiss QR Code von der **letzten Seite** des PDFs
|
||||
- API gibt Referenzen + alle QR Code Felder zurück (Swiss QR Bill Standard 2.0)
|
||||
|
||||
**Endpoint:**
|
||||
```
|
||||
POST /api/v1/documents/extract-swiss-qr-code
|
||||
Request:
|
||||
{
|
||||
"references": ["REF-001", "REF-002"],
|
||||
"base64Pdf": "JVBERi0xLjQK..."
|
||||
}
|
||||
|
||||
Response:
|
||||
{
|
||||
"references": ["REF-001", "REF-002"],
|
||||
"qrCodeData": {
|
||||
"qrType": "SPC",
|
||||
"version": "0200",
|
||||
"codingType": "1",
|
||||
"iban": "CH4431999123000889012",
|
||||
"creditor": {
|
||||
"name": "Robert Schneider AG",
|
||||
"addressType": "S",
|
||||
"street": "Rue du Lac",
|
||||
"buildingNumber": "1268",
|
||||
"postalCode": "2501",
|
||||
"city": "Biel",
|
||||
"country": "CH"
|
||||
},
|
||||
"ultimateCreditor": null,
|
||||
"amount": 1949.75,
|
||||
"currency": "CHF",
|
||||
"ultimateDebtor": {
|
||||
"name": "Pia-Maria Rutschmann-Schnyder",
|
||||
"addressType": "S",
|
||||
"street": "Grosse Marktgasse",
|
||||
"buildingNumber": "28",
|
||||
"postalCode": "9400",
|
||||
"city": "Rorschach",
|
||||
"country": "CH"
|
||||
},
|
||||
"referenceType": "QRR",
|
||||
"reference": "210000000003139471430009017",
|
||||
"unstructuredMessage": "Rechnung vom 15.01.2025",
|
||||
"billInformation": "//S1/01/...",
|
||||
"alternativeProcedureParameters": ["Name AV1: UV;UltraPay005;12345", "Name AV2: XY;XYService;54321"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Technologie:**
|
||||
- **DevExpress PDF Document API** (PDF-Zugriff, letzte Seite, QR Code Image)
|
||||
- **Codecrete.SwissQRBill.Generator** (Swiss QR Code Parsing - Standard 2.0)
|
||||
|
||||
**Steps:**
|
||||
- ?? Step 2.1: Domain Layer (SwissQrCodeData Value Object)
|
||||
- ?? Step 2.2: Infrastructure Layer (IQrCodeProcessor + DevExpressSwissQrCodeProcessor)
|
||||
- ?? Step 2.3: Application Layer (ExtractSwissQrCodeQuery + Handler + Validator)
|
||||
- ?? Step 2.4: API Layer (Endpoint + Integration Tests)
|
||||
- ?? Step 2.5: Swagger Dokumentation
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- ? QR Code wird von letzter Seite extrahiert
|
||||
- ? Alle Swiss QR Bill Felder werden geparst (Standard 2.0)
|
||||
- ? Referenzen werden durchgeschliffen (Echo)
|
||||
- ? Fehler wenn kein QR Code gefunden
|
||||
- ? Swagger-testbar
|
||||
|
||||
---
|
||||
|
||||
## ?? FEATURE 3: ExtractAttachments (Synchron) - **PENDING**
|
||||
|
||||
**Was macht dieses Feature?**
|
||||
- Client sendet PDF als Base64 (JSON)
|
||||
@@ -297,14 +372,14 @@ Response: { "attachments": [{ "name": "invoice.xml", "base64Content": "..." }] }
|
||||
```
|
||||
|
||||
**Steps:**
|
||||
- ?? Step 2.1: Infrastructure Layer (DevExpressPdfProcessor.ExtractAttachmentsAsync)
|
||||
- ?? Step 2.2: Application Layer (ExtractAttachmentsCommand + Handler + Validator)
|
||||
- ?? Step 2.3: API Layer (Endpoint)
|
||||
- ?? Step 2.4: Swagger Dokumentation
|
||||
- ?? Step 3.1: Infrastructure Layer (DevExpressPdfProcessor.ExtractAttachmentsAsync)
|
||||
- ?? Step 3.2: Application Layer (ExtractAttachmentsCommand + Handler + Validator)
|
||||
- ?? Step 3.3: API Layer (Endpoint)
|
||||
- ?? Step 3.4: Swagger Dokumentation
|
||||
|
||||
---
|
||||
|
||||
## ?? FEATURE 3: ApplyStamp (Synchron) - **PENDING**
|
||||
## ?? FEATURE 4: ApplyStamp (Synchron) - **PENDING**
|
||||
|
||||
**Was macht dieses Feature?**
|
||||
- Client sendet PDF + Stamp-Konfiguration (Text, Position)
|
||||
@@ -319,14 +394,14 @@ Response: { "base64Pdf": "JVBERi0xLjQK..." }
|
||||
```
|
||||
|
||||
**Steps:**
|
||||
- ?? Step 3.1: Infrastructure Layer (DevExpressPdfProcessor.ApplyStampAsync)
|
||||
- ?? Step 3.2: Application Layer (ApplyStampCommand + Handler + Validator)
|
||||
- ?? Step 3.3: API Layer (Endpoint)
|
||||
- ?? Step 3.4: Swagger Dokumentation
|
||||
- ?? Step 4.1: Infrastructure Layer (DevExpressPdfProcessor.ApplyStampAsync)
|
||||
- ?? Step 4.2: Application Layer (ApplyStampCommand + Handler + Validator)
|
||||
- ?? Step 4.3: API Layer (Endpoint)
|
||||
- ?? Step 4.4: Swagger Dokumentation
|
||||
|
||||
---
|
||||
|
||||
## ?? FEATURE 4: EmbedCertificate (Synchron) - **PENDING**
|
||||
## ?? FEATURE 5: EmbedCertificate (Synchron) - **PENDING**
|
||||
|
||||
**Was macht dieses Feature?**
|
||||
- Client sendet PDF + Zertifikat (PFX als Base64)
|
||||
@@ -341,14 +416,14 @@ Response: { "base64Pdf": "JVBERi0xLjQK..." }
|
||||
```
|
||||
|
||||
**Steps:**
|
||||
- ?? Step 4.1: Infrastructure Layer (DevExpressPdfProcessor.EmbedCertificateAsync)
|
||||
- ?? Step 4.2: Application Layer (EmbedCertificateCommand + Handler + Validator)
|
||||
- ?? Step 4.3: API Layer (Endpoint)
|
||||
- ?? Step 4.4: Swagger Dokumentation
|
||||
- ?? Step 5.1: Infrastructure Layer (DevExpressPdfProcessor.EmbedCertificateAsync)
|
||||
- ?? Step 5.2: Application Layer (EmbedCertificateCommand + Handler + Validator)
|
||||
- ?? Step 5.3: API Layer (Endpoint)
|
||||
- ?? Step 5.4: Swagger Dokumentation
|
||||
|
||||
---
|
||||
|
||||
## ?? FEATURE 5: ConcatenatePDFs (Asynchron) - **PENDING**
|
||||
## ?? FEATURE 6: ConcatenatePDFs (Asynchron) - **PENDING**
|
||||
|
||||
**Was macht dieses Feature?**
|
||||
- Client sendet mehrere PDFs (Array von Base64)
|
||||
@@ -370,10 +445,10 @@ Response: PDF-Datei (Binary)
|
||||
```
|
||||
|
||||
**Steps:**
|
||||
- ?? Step 5.1: Infrastructure Layer (In-Memory Queue + Background Worker)
|
||||
- ?? Step 5.2: Application Layer (SubmitConcatenateJobCommand + GetJobStatusQuery)
|
||||
- ?? Step 5.3: API Layer (Async Endpoints)
|
||||
- ?? Step 5.4: Swagger Dokumentation
|
||||
- ?? Step 6.1: Infrastructure Layer (In-Memory Queue + Background Worker)
|
||||
- ?? Step 6.2: Application Layer (SubmitConcatenateJobCommand + GetJobStatusQuery)
|
||||
- ?? Step 6.3: API Layer (Async Endpoints)
|
||||
- ?? Step 6.4: Swagger Dokumentation
|
||||
|
||||
---
|
||||
|
||||
@@ -995,6 +1070,8 @@ DocumentOperator.Tests/
|
||||
| 17.01.2025 | **Feature 1** | ? **KOMPLETT ABGESCHLOSSEN** - ValidatePDF Feature testbar im Swagger UI! |
|
||||
| 17.01.2025 | **Fix: Attachment Detection (Multiple Attachments)** | ? **KORRIGIERT** - ValidatePDF erkennt jetzt auch PDFs mit mehreren Attachments korrekt (globale Suche statt 1000-Zeichen-Limit) - 13/13 Tests grün |
|
||||
| 17.01.2025 | **Fix: Attachment Count (6 Attachments)** | ? **KORRIGIERT** - AttachmentCount wird jetzt korrekt gezählt (objectCount statt objectCount/2). PDFs mit 6 Attachments werden korrekt erkannt - 13/13 Tests grün |
|
||||
| 17.01.2025 | **ROADMAP** | ?? **Feature-Reihenfolge geändert** - Neues Feature 2: ExtractSwissQrCode (Swiss QR Bill Standard 2.0) eingefügt. Alte Features 2-5 werden zu Features 3-6. |
|
||||
| 17.01.2025 | **Feature 2 - ExtractSwissQrCode** | ?? **GESTARTET** - Swiss QR Code Extraktion von letzter PDF-Seite (DevExpress + Codecrete.SwissQRBill.Generator) |
|
||||
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user