diff --git a/CHANGELOG.md b/CHANGELOG.md index 92ff42e..aa38d79 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,66 +2,6 @@ Alle wesentlichen Änderungen an diesem Projekt werden in dieser Datei dokumentiert. -## [3.5] - 2026-03-05 - -### Hinzugefügt -- **PDF-Kontoauszüge per FinTS**: Elektronische Kontoauszüge direkt von der Bank abrufen - - **HKEKP**: Direkt-Abruf (für Banken die dies unterstützen) - - **HKKAA**: Fallback über Bank-Archiv/Postfach (VR Banken, etc.) - - Automatische Methodenwahl: System prüft BPD und wählt beste verfügbare Methode - - Neue Segmente für php-fints: EKP/* (HKEKP) und KAA/* (HKKAA) - - Integration in bestehende PDF-Kontoauszüge-Seite -- **Cronjob für automatischen PDF-Abruf**: Neue geplante Aufgabe `doAutoFetchPdf` - - Aktivierbar über Konstante `BANKIMPORT_PDF_AUTO_ENABLED` - - Ruft automatisch neue PDF-Kontoauszüge ab und speichert sie - -### Geändert -- PDF-Kontoauszüge-Seite: Neues Layout mit zwei Spalten (FinTS-Abruf links, Upload rechts) -- fints.class.php: Neue Methoden für PDF-Abruf mit automatischer Methodenwahl - -### Technisch -- Erweiterung der php-fints Bibliothek: - - HKEKP-Unterstützung (Segment/EKP/*): HKEKPv2, HIEKPv2, HIEKPSv2 - - HKKAA-Unterstützung (Segment/KAA/*): HKKAAv2, HIKAAv2, HIKAASv1 - - Action-Klassen: GetStatementPDF, GetStatementFromArchive -- Neue Methoden in BankImportFinTS: - - `getPdfStatementMethod()`: Prüft welche Methode die Bank unterstützt - - `getStatementPDFAuto()`: Automatische Methodenwahl - - `supportsArchiveStatements()`: Prüft HKKAA-Support - -## [3.1] - 2026-03-05 - -### Hinzugefügt -- **Skonto-Erkennung**: Multi-Invoice-Matching erkennt jetzt Skonto-Abzüge bis 3% -- **Automatische Skonto-Verarbeitung**: Zahlungen werden proportional auf Rechnungen verteilt -- **Skonto-Vermerk**: Rechnungen werden mit `close_code='discount_vat'` als bezahlt markiert -- **Skonto-Dokumentation**: Notiz zeigt Skonto-Betrag pro Rechnung - -### Verbessert -- **Match-Sortierung**: Matches mit näherem Betrag werden jetzt bevorzugt angezeigt -- **Multi-Match Score**: Von 90 auf 98 erhöht, damit Sammelzahlungen vor Einzelmatches erscheinen -- Sammelzahlungen mit Skonto werden jetzt korrekt als Gruppe erkannt (statt einzelner Rechnungen) - -### Beispiel -Transaktion -523,40€ mit 3 Rechnungen (Summe 529,69€): -- Erkennt 6,29€ Skonto-Abzug -- Verteilt proportional: 59,37€ + 206,72€ + 257,32€ -- Markiert alle 3 als "bezahlt mit Skonto" - -## [3.0] - 2026-03-05 - -### Hinzugefügt -- **Repair-Seite**: Neue Admin-Seite zum Reparieren verwaister Transaktionen - - Findet Transaktionen die als "Neu" markiert sind, obwohl Zahlung bereits existiert - - Ermöglicht manuelles oder Batch-Reparieren - - Erreichbar über Admin-Setup → Admin-Werkzeuge -- **Admin-Werkzeuge Sektion**: Neuer Bereich im Setup für Wartungsfunktionen - -### Geändert -- **Filter für bezahlte Rechnungen**: Zeigt jetzt alle bezahlten Rechnungen die noch nicht über BankImport verknüpft sind - - Prüft nur BankImport-Verknüpfung (nicht mehr payment.fk_bank) - - Ermöglicht nachträgliche Verknüpfung von extern bezahlten Rechnungen - ## [2.9] - 2026-02-23 ### Entfernt diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100755 index 48a50e4..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,175 +0,0 @@ -# BankImport Modul - Entwicklernotizen - -## Modul-Übersicht -- **Name**: BankImport -- **Version**: 3.5 -- **Pfad**: `/srv/http/dolibarr/custom/bankimport/` -- **Funktion**: FinTS/HBCI Kontoauszüge importieren und mit Dolibarr-Rechnungen abgleichen - -## Wichtige Dateien - -| Datei | Funktion | -|-------|----------| -| `class/banktransaction.class.php` | Hauptklasse für Transaktionen, findMatches(), confirmMultiplePayment() | -| `confirm.php` | Übersicht aller Matches zur Bestätigung | -| `card.php` | Einzelansicht einer Transaktion mit manueller Zuordnung | -| `repair.php` | Admin-Seite für verwaiste Transaktionen | -| `cron/bankimport.cron.php` | Cronjob für automatischen Import | -| `admin/cronmonitor.php` | Cron-Monitoring und Pause/Resume | -| `pdfstatements.php` | PDF-Kontoauszüge hochladen und per FinTS abrufen | -| `vendor/.../Segment/EKP/*` | HKEKP-Segmente für PDF-Abruf (direkt) | -| `vendor/.../Segment/KAA/*` | HKKAA-Segmente für PDF-Abruf (Archiv) | -| `vendor/.../Action/GetStatementPDF.php` | Action-Klasse für HKEKP | -| `vendor/.../Action/GetStatementFromArchive.php` | Action-Klasse für HKKAA | - -## PDF-Kontoauszüge per FinTS - -### Übersicht -Seit Version 3.5 können PDF-Kontoauszüge von der Bank abgerufen werden. Es gibt zwei Methoden: - -| Methode | Segment | Beschreibung | Bank-Beispiele | -|---------|---------|--------------|----------------| -| **HKEKP** | Elektronischer Kontoauszug PDF | Direkt-Abruf | Sparkassen, einige Volksbanken | -| **HKKAA** | Kontoauszug aus Archiv | Abruf aus Bank-Postfach | VR Banken (z.B. VR Bank Schleswig-Holstein) | - -Das System wählt automatisch die beste verfügbare Methode. - -### Neue Dateien in php-fints -``` -vendor/nemiah/php-fints/lib/Fhp/ -├── Action/ -│ ├── GetStatementPDF.php # HKEKP Action -│ └── GetStatementFromArchive.php # HKKAA Action -└── Segment/ - ├── EKP/ # HKEKP Segmente - │ ├── HKEKPv2.php - │ ├── HIEKPv2.php - │ └── ... - └── KAA/ # HKKAA Segmente - ├── HKKAAv2.php - ├── HIKAAv2.php - ├── HIKAASv1.php - └── ParameterKontoauszugArchiv.php -``` - -### Verwendung (empfohlen: Auto-Modus) -```php -$fints = new BankImportFinTS($db); -$fints->login(); - -// Automatische Methodenwahl -$method = $fints->getPdfStatementMethod(); // 'HKEKP', 'HKKAA' oder false -if ($method) { - $result = $fints->getStatementPDFAuto(0); - if (is_array($result) && !empty($result['pdfData'])) { - $pdfData = $result['pdfData']; - $info = $result['info']; - $usedMethod = $result['method']; // 'HKEKP' oder 'HKKAA' - } -} -``` - -### Cronjob -- Aktivieren: `BANKIMPORT_PDF_AUTO_ENABLED = 1` -- Klasse: `BankImportCron::doAutoFetchPdf()` -- Frequenz: Wie Transaktions-Import konfigurierbar - -## Multi-Invoice Matching (Sammelzahlungen) - -### Ablauf -1. `findMatches()` sucht Einzelmatches und Multi-Matches -2. `findSupplierForMultiMatch()` findet Lieferant über IBAN oder Name (Similarity > 70%) -3. `findMultipleSupplierInvoiceMatches()` kombiniert Rechnungen deren ref_supplier im Buchungstext steht -4. Toleranz: **3% des Betrags** (für Skonto) - -### Sortierung -Matches werden sortiert nach: -1. Betragsnähe (innerhalb 10% Threshold bevorzugt) -2. Score (Multi-Match: 98-100, Einzelmatch: variabel) - -### Skonto-Verarbeitung -In `confirmMultiplePayment()`: -1. Wenn gezahlter Betrag < Rechnungssumme (max 5% Abweichung) -2. Zahlungen werden proportional verteilt (`discountFactor = actualAmount / totalPayment`) -3. Rechnungen werden mit `setPaid($user, 'discount_vat', 'Skonto (X EUR)')` geschlossen - -## Datenbank-Struktur - -### llx_bankimport_transaction -| Feld | Bedeutung | -|------|-----------| -| `status` | 0=Neu, 1=Zugeordnet, 2=Abgestimmt, 9=Ignoriert | -| `fk_facture_fourn` | Verknüpfte Lieferantenrechnung (erste bei Multi) | -| `fk_paiementfourn` | Verknüpfte Zahlung | -| `fk_bank` | Verknüpfter Bank-Eintrag | -| `note_private` | Multi-invoice payment: SI..., SI..., SI... (Skonto: X EUR) | - -### Rechnung (close_code) -| Code | Bedeutung | -|------|-----------| -| `NULL` | Normal bezahlt | -| `discount_vat` | Mit Skonto bezahlt | -| `badsupplier` | Zahlungsausfall | -| `abandon` | Aufgegeben | - -## Bekannte Edge Cases - -### Problem: Nur 1 statt 3 Rechnungen bestätigt -- **Ursache**: Multi-Match hatte niedrigeren Score als Einzelmatch -- **Lösung**: Score auf 98 erhöht + Sortierung nach Betragsnähe - -### Problem: Skonto nicht erkannt -- **Ursache**: Toleranz war 5€ fix, Skonto war 6,29€ -- **Lösung**: Toleranz auf 3% des Betrags geändert - -### Problem: Bezahlte Rechnungen nicht in Liste -- **Ursache**: Filter prüfte payment.fk_bank statt BankImport-Verknüpfung -- **Lösung**: Nur `llx_bankimport_transaction.status > 0` prüfen - -## Test-Datenbank -- **Host**: 192.168.155.1 (Produktiv) / 192.168.155.11 (Test) -- **User**: dolibarr -- **Passwort**: 8715 - -## Typische Debug-Queries - -```sql --- Transaktion mit Verknüpfungen -SELECT rowid, ref, amount, status, fk_facture_fourn, fk_paiementfourn, fk_bank, note_private -FROM llx_bankimport_transaction WHERE rowid = X; - --- Zahlungsverteilung prüfen -SELECT pf.fk_paiementfourn, pf.fk_facturefourn, pf.amount, f.ref -FROM llx_paiementfourn_facturefourn pf -JOIN llx_facture_fourn f ON f.rowid = pf.fk_facturefourn -WHERE pf.fk_paiementfourn = X; - --- Rechnungen mit Skonto-Status -SELECT rowid, ref, total_ttc, fk_statut, paye, close_code, close_note -FROM llx_facture_fourn WHERE rowid IN (X, Y, Z); -``` - -## Zurücksetzen einer Transaktion (für Tests) - -```sql --- 1. Zahlung-Rechnung Verknüpfung löschen -DELETE FROM llx_paiementfourn_facturefourn WHERE fk_paiementfourn = X; - --- 2. Bank-URL löschen -DELETE FROM llx_bank_url WHERE url_id = X AND type = 'payment_supplier'; - --- 3. Zahlung löschen -DELETE FROM llx_paiementfourn WHERE rowid = X; - --- 4. Bank-Eintrag löschen -DELETE FROM llx_bank WHERE rowid = Y; - --- 5. Rechnung(en) auf offen setzen -UPDATE llx_facture_fourn SET fk_statut = 1, paye = 0, close_code = NULL, close_note = NULL WHERE rowid IN (...); - --- 6. BankImport-Transaktion zurücksetzen -UPDATE llx_bankimport_transaction -SET status = 0, fk_facture_fourn = NULL, fk_paiementfourn = NULL, fk_bank = NULL, - fk_user_match = NULL, date_match = NULL -WHERE rowid = Z; -``` diff --git a/bin/module_bankimport-1.6.zip b/bin/module_bankimport-1.6.zip deleted file mode 100755 index 3f9fbef..0000000 Binary files a/bin/module_bankimport-1.6.zip and /dev/null differ diff --git a/bin/module_bankimport-1.7.zip b/bin/module_bankimport-1.7.zip deleted file mode 100755 index cfc0f8f..0000000 Binary files a/bin/module_bankimport-1.7.zip and /dev/null differ diff --git a/bin/module_bankimport-1.8.zip b/bin/module_bankimport-1.8.zip deleted file mode 100755 index 84cffca..0000000 Binary files a/bin/module_bankimport-1.8.zip and /dev/null differ diff --git a/bin/module_bankimport-1.9.zip b/bin/module_bankimport-1.9.zip deleted file mode 100755 index e87d50c..0000000 Binary files a/bin/module_bankimport-1.9.zip and /dev/null differ diff --git a/bin/module_bankimport-2.0.zip b/bin/module_bankimport-2.0.zip deleted file mode 100755 index ac98c3a..0000000 Binary files a/bin/module_bankimport-2.0.zip and /dev/null differ diff --git a/bin/module_bankimport-2.1.zip b/bin/module_bankimport-2.1.zip deleted file mode 100755 index 93493e6..0000000 Binary files a/bin/module_bankimport-2.1.zip and /dev/null differ diff --git a/bin/module_bankimport-2.2.zip b/bin/module_bankimport-2.2.zip deleted file mode 100755 index a46c65d..0000000 Binary files a/bin/module_bankimport-2.2.zip and /dev/null differ diff --git a/bin/module_bankimport-2.3.zip b/bin/module_bankimport-2.3.zip deleted file mode 100755 index 5baf298..0000000 Binary files a/bin/module_bankimport-2.3.zip and /dev/null differ diff --git a/bin/module_bankimport-2.4.zip b/bin/module_bankimport-2.4.zip deleted file mode 100755 index 7427493..0000000 Binary files a/bin/module_bankimport-2.4.zip and /dev/null differ diff --git a/bin/module_bankimport-2.5.zip b/bin/module_bankimport-2.5.zip deleted file mode 100755 index 274cb70..0000000 Binary files a/bin/module_bankimport-2.5.zip and /dev/null differ diff --git a/bin/module_bankimport-2.6.zip b/bin/module_bankimport-2.6.zip deleted file mode 100755 index 36ce9e3..0000000 Binary files a/bin/module_bankimport-2.6.zip and /dev/null differ diff --git a/class/bankimportcron.class.php b/class/bankimportcron.class.php index fcecc35..9c1dd98 100755 --- a/class/bankimportcron.class.php +++ b/class/bankimportcron.class.php @@ -16,7 +16,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; dol_include_once('/bankimport/class/fints.class.php'); dol_include_once('/bankimport/class/banktransaction.class.php'); -dol_include_once('/bankimport/class/bankstatement.class.php'); /** * Class BankImportCron @@ -733,184 +732,4 @@ class BankImportCron return $this->doAutoImport(); } - - /** - * Execute automatic PDF statement fetch via HKEKP - * Called by Dolibarr's scheduled task system - * - * @return int 0 if OK, < 0 if error - */ - public function doAutoFetchPdf() - { - global $conf, $langs, $user; - - // Initialize timing - $this->startTime = microtime(true); - - $langs->load('bankimport@bankimport'); - - $this->cronLog("========== PDF FETCH CRON START =========="); - $this->recordCronStatus('started', 'PDF fetch cron started'); - - // Check if PDF fetch is enabled - if (!getDolGlobalInt('BANKIMPORT_PDF_AUTO_ENABLED')) { - $this->output = $langs->trans('AutoPdfFetchDisabled'); - $this->cronLog("Auto PDF fetch is disabled - exiting"); - $this->recordCronStatus('completed', 'Auto PDF fetch disabled'); - return 0; - } - - // Check cron pause status (shared with main cron) - $pausedUntil = getDolGlobalInt('BANKIMPORT_CRON_PAUSED_UNTIL'); - if ($pausedUntil > 0 && $pausedUntil > time()) { - $pauseReason = getDolGlobalString('BANKIMPORT_CRON_PAUSE_REASON'); - $this->output = "Cron pausiert: {$pauseReason}"; - $this->cronLog("Cron is PAUSED - skipping PDF fetch", 'WARNING'); - return 0; - } - - $this->cronLog("Initializing FinTS for PDF fetch"); - - // Initialize FinTS - $fints = new BankImportFinTS($this->db); - - if (!$fints->isConfigured()) { - $this->error = $langs->trans('AutoImportNotConfigured'); - $this->cronLog("FinTS not configured", 'WARNING'); - return -1; - } - - try { - // Login to bank - $this->cronLog("Logging in to bank"); - $loginResult = $fints->login(); - - if ($loginResult < 0) { - $this->error = $fints->error; - $this->cronLog("Login failed: ".$fints->error, 'ERROR'); - return -1; - } - - if ($loginResult == 0) { - // TAN required - $this->output = $langs->trans('TANRequired'); - $this->cronLog("TAN required for PDF fetch", 'WARNING'); - $this->recordCronStatus('completed', 'TAN required'); - return 0; - } - - // Check if bank supports PDF statements - if (!$fints->supportsPdfStatements()) { - $this->output = $langs->trans('ErrorBankDoesNotSupportPdfStatements'); - $this->cronLog("Bank does not support PDF statements (HKEKP)", 'WARNING'); - $fints->close(); - return 0; - } - - // Fetch PDF statement - $this->cronLog("Fetching PDF statement via HKEKP"); - $pdfResult = $fints->getStatementPDF(0); - - if ($pdfResult === 0) { - // TAN required - $this->output = $langs->trans('TANRequired'); - $this->cronLog("TAN required for PDF statement", 'WARNING'); - $fints->close(); - return 0; - } - - if ($pdfResult === -1) { - $this->error = $fints->error; - $this->cronLog("PDF fetch failed: ".$fints->error, 'ERROR'); - $fints->close(); - return -1; - } - - // Check if we got any data - if (empty($pdfResult['pdfData'])) { - $this->output = $langs->trans('NoPdfStatementsAvailable'); - $this->cronLog("No new PDF statements available"); - $fints->close(); - return 0; - } - - // Save the PDF - $info = $pdfResult['info']; - $pdfData = $pdfResult['pdfData']; - - $this->cronLog("Received PDF statement #".$info['statementNumber'].'/'.$info['statementYear']); - - // Check if statement already exists - $stmt = new BankImportStatement($this->db); - $stmt->statement_number = $info['statementNumber']; - $stmt->statement_year = $info['statementYear']; - $stmt->iban = $info['iban'] ?: getDolGlobalString('BANKIMPORT_IBAN'); - - if ($stmt->exists()) { - $this->output = $langs->trans("StatementAlreadyExists").': '.$stmt->statement_number.'/'.$stmt->statement_year; - $this->cronLog("Statement already exists - skipping"); - $fints->close(); - return 0; - } - - // Save PDF to file - $dir = BankImportStatement::getStorageDir(); - $ibanPart = preg_replace('/[^A-Z0-9]/', '', strtoupper($stmt->iban ?: 'KONTO')); - $filename = sprintf('Kontoauszug_%s_%d_%s.pdf', - $ibanPart, - $stmt->statement_year, - str_pad($stmt->statement_number, 3, '0', STR_PAD_LEFT) - ); - - $filepath = $dir.'/'.$filename; - if (file_put_contents($filepath, $pdfData) === false) { - $this->error = $langs->trans("ErrorSavingPdfFile"); - $this->cronLog("Failed to save PDF file", 'ERROR'); - $fints->close(); - return -1; - } - - // Create database record - $stmt->filename = $filename; - $stmt->filepath = $filepath; - $stmt->filesize = strlen($pdfData); - $stmt->statement_date = $info['creationDate'] ? $info['creationDate']->getTimestamp() : dol_now(); - $stmt->import_key = 'fints_cron_'.date('YmdHis'); - - // Get system user - $importUser = new User($this->db); - $importUser->fetch(1); - - $result = $stmt->create($importUser); - - if ($result > 0) { - $this->output = $langs->trans("PdfStatementFetched", $stmt->statement_number.'/'.$stmt->statement_year); - $this->cronLog("PDF statement saved successfully: ".$stmt->statement_number.'/'.$stmt->statement_year); - - // Update last fetch timestamp - dolibarr_set_const($this->db, 'BANKIMPORT_PDF_LAST_FETCH', time(), 'chaine', 0, '', $conf->entity); - } else { - $this->error = $stmt->error; - $this->cronLog("Failed to create database record: ".$stmt->error, 'ERROR'); - @unlink($filepath); - $fints->close(); - return -1; - } - - $fints->close(); - - $duration = round(microtime(true) - $this->startTime, 2); - $this->cronLog("PDF fetch completed successfully in {$duration}s"); - $this->recordCronStatus('completed', "PDF fetched: {$stmt->statement_number}/{$stmt->statement_year}"); - $this->cronLog("========== PDF FETCH CRON END =========="); - - return 0; - - } catch (Exception $e) { - $this->error = 'Exception: '.$e->getMessage(); - $this->cronLog("EXCEPTION: ".$e->getMessage(), 'ERROR'); - $this->recordCronStatus('error', 'Exception: '.$e->getMessage()); - return -1; - } - } } diff --git a/class/bankstatement.class.php b/class/bankstatement.class.php index 9dbe529..7fa6d9d 100755 --- a/class/bankstatement.class.php +++ b/class/bankstatement.class.php @@ -299,7 +299,13 @@ class BankImportStatement extends CommonObject } // Sort and limit - $sql .= $this->db->order($sortfield, $sortorder); + if (strpos($sortfield, 'statement_number') !== false) { + // statement_number numerisch sortieren (db->order() sanitiert CAST-Ausdruecke) + $dir = strtoupper($sortorder) === 'DESC' ? 'DESC' : 'ASC'; + $sql .= " ORDER BY t.statement_year ".$dir.", CAST(t.statement_number AS UNSIGNED) ".$dir; + } else { + $sql .= $this->db->order($sortfield, $sortorder); + } if ($limit > 0) { $sql .= $this->db->plimit($limit, $offset); } @@ -747,6 +753,7 @@ class BankImportStatement extends CommonObject $sql = "SELECT DISTINCT statement_year"; $sql .= " FROM ".MAIN_DB_PREFIX."bankimport_statement"; $sql .= " WHERE entity = ".((int) $this->entity); + $sql .= " AND statement_year > 0"; $sql .= " ORDER BY statement_year DESC"; $result = array(); @@ -1166,6 +1173,14 @@ class BankImportStatement extends CommonObject $txType = trim($rest); } + // Ungueltige Daten korrigieren (z.B. 30.02. bei Monatsabschluss) + if (!checkdate($bookMonth, $bookDay, $bookYear)) { + $bookDay = (int) date('t', mktime(0, 0, 0, $bookMonth, 1, $bookYear)); + } + if (!checkdate($valMonth, $valDay, $valYear)) { + $valDay = (int) date('t', mktime(0, 0, 0, $valMonth, 1, $valYear)); + } + // Build date strings $dateBooking = sprintf('%04d-%02d-%02d', $bookYear, $bookMonth, $bookDay); $dateValue = sprintf('%04d-%02d-%02d', $valYear, $valMonth, $valDay); diff --git a/class/fints.class.php b/class/fints.class.php index b6a89c8..77c5447 100755 --- a/class/fints.class.php +++ b/class/fints.class.php @@ -38,8 +38,8 @@ use Fhp\Options\Credentials; use Fhp\Action\GetSEPAAccounts; use Fhp\Action\GetStatementOfAccount; use Fhp\Action\GetStatementOfAccountXML; -use Fhp\Action\GetStatementPDF; -use Fhp\Action\GetStatementFromArchive; +use Fhp\Action\GetBankStatement; +use Fhp\Action\GetElectronicStatement; use Fhp\Model\StatementOfAccount\Statement; use Fhp\Model\StatementOfAccount\Transaction; @@ -296,16 +296,28 @@ class BankImportFinTS */ public function login($tanModeId = null) { + dol_syslog("BankImport FinTS: login() gestartet, tanModeId=".($tanModeId ?: 'auto'), LOG_DEBUG); + if ($this->fints === null) { + dol_syslog("BankImport FinTS: Keine bestehende Verbindung, rufe initConnection() auf", LOG_DEBUG); $result = $this->initConnection(); + dol_syslog("BankImport FinTS: initConnection() Ergebnis=".$result, LOG_DEBUG); if ($result < 0) { + dol_syslog("BankImport FinTS: initConnection() FEHLGESCHLAGEN: ".$this->error, LOG_ERR); return -1; } } try { // Get and select TAN mode + dol_syslog("BankImport FinTS: Rufe getTanModes() ab...", LOG_DEBUG); $tanModes = $this->fints->getTanModes(); + dol_syslog("BankImport FinTS: ".count($tanModes)." TAN-Modi verfuegbar", LOG_DEBUG); + + foreach ($tanModes as $mode) { + dol_syslog("BankImport FinTS: TAN-Modus: ID=".$mode->getId()." Name=".$mode->getName() + ." Decoupled=".($mode->isDecoupled() ? 'JA' : 'NEIN'), LOG_DEBUG); + } if ($tanModeId !== null) { foreach ($tanModes as $mode) { @@ -330,24 +342,34 @@ class BankImportFinTS if ($this->selectedTanMode === null) { $this->error = 'No TAN mode available'; + dol_syslog("BankImport FinTS: KEIN TAN-Modus ausgewaehlt", LOG_ERR); return -1; } + dol_syslog("BankImport FinTS: Ausgewaehlter TAN-Modus: ID=".$this->selectedTanMode->getId() + ." Name=".$this->selectedTanMode->getName() + ." Decoupled=".($this->selectedTanMode->isDecoupled() ? 'JA' : 'NEIN'), LOG_DEBUG); + $this->fints->selectTanMode($this->selectedTanMode); + dol_syslog("BankImport FinTS: TAN-Modus gesetzt, starte fints->login()...", LOG_DEBUG); // Perform login $login = $this->fints->login(); + dol_syslog("BankImport FinTS: fints->login() abgeschlossen, needsTan=".($login->needsTan() ? 'JA' : 'NEIN'), LOG_DEBUG); if ($login->needsTan()) { $this->pendingAction = $login; $tanRequest = $login->getTanRequest(); $this->tanChallenge = $tanRequest->getChallenge(); + dol_syslog("BankImport FinTS: TAN benoetigt, Challenge-Laenge=".strlen($this->tanChallenge), LOG_DEBUG); return 0; // TAN required } + dol_syslog("BankImport FinTS: Login erfolgreich (kein TAN benoetigt)", LOG_DEBUG); return 1; } catch (Exception $e) { $this->error = $e->getMessage(); + dol_syslog("BankImport FinTS: Login EXCEPTION: ".$e->getMessage()."\n".$e->getTraceAsString(), LOG_ERR); return -1; } } @@ -417,7 +439,10 @@ class BankImportFinTS */ public function getBankParameters() { + dol_syslog("BankImport FinTS: getBankParameters() aufgerufen", LOG_DEBUG); + if ($this->fints === null) { + dol_syslog("BankImport FinTS: getBankParameters() - fints===null", LOG_WARNING); return array('error' => 'Not connected'); } @@ -429,22 +454,30 @@ class BankImportFinTS $bpd = $bpdProperty->getValue($this->fints); if ($bpd === null) { + dol_syslog("BankImport FinTS: getBankParameters() - BPD ist null (noch kein Login?)", LOG_WARNING); return array('error' => 'BPD not available'); } + dol_syslog("BankImport FinTS: BPD-Klasse: ".get_class($bpd), LOG_DEBUG); + // Get parameters property from BPD $bpdReflection = new \ReflectionClass($bpd); $paramsProperty = $bpdReflection->getProperty('parameters'); $paramsProperty->setAccessible(true); $parameters = $paramsProperty->getValue($bpd); + dol_syslog("BankImport FinTS: BPD enthaelt ".count($parameters)." Segment-Typen", LOG_DEBUG); + $result = array(); foreach ($parameters as $type => $versions) { $result[$type] = array_keys($versions); } + dol_syslog("BankImport FinTS: BPD-Segmente: ".implode(', ', array_keys($result)), LOG_DEBUG); + return $result; } catch (Exception $e) { + dol_syslog("BankImport FinTS: getBankParameters() Exception: ".$e->getMessage(), LOG_ERR); return array('error' => $e->getMessage()); } } @@ -910,6 +943,224 @@ class BankImportFinTS } } + /** + * Prueft ob die Bank elektronische Kontoauszuege (PDF) unterstuetzt + * + * Prueft sowohl HKEKP (HIEPS) als auch HKEKA (HIEKAS). + * + * @return bool True wenn HIEPS oder HIEKAS in den BPD vorhanden + */ + public function supportsStatementPdf() + { + if ($this->fints === null) { + return false; + } + + try { + $params = $this->getBankParameters(); + return isset($params['HIEPS']) || isset($params['HIEKAS']); + } catch (Exception $e) { + return false; + } + } + + /** + * Elektronische Kontoauszuege als PDF von der Bank abrufen (HKEKP) + * + * @param string|null $statementNumber Optionale Auszugsnummer + * @param string|null $year Optionales Jahr (JJJJ) + * @return array|int Array mit PDF-Daten oder -1 bei Fehler, 0 wenn TAN benoetigt + */ + public function fetchBankStatements($statementNumber = null, $year = null) + { + dol_syslog("BankImport HKEKP: ===== fetchBankStatements() START =====", LOG_DEBUG); + dol_syslog("BankImport HKEKP: Parameter: statementNumber=".($statementNumber ?: 'null').", year=".($year ?: 'null'), LOG_DEBUG); + + if (!$this->isConfigured()) { + $this->error = 'Konfiguration unvollstaendig'; + dol_syslog("BankImport HKEKP: ABBRUCH - nicht konfiguriert", LOG_ERR); + return -1; + } + + if ($this->fints === null) { + $this->error = 'Nicht verbunden. Bitte zuerst login() aufrufen.'; + dol_syslog("BankImport HKEKP: ABBRUCH - fints===null, kein Login", LOG_ERR); + return -1; + } + + try { + // Konten abrufen + dol_syslog("BankImport HKEKP: Rufe GetSEPAAccounts ab...", LOG_DEBUG); + $getAccounts = GetSEPAAccounts::create(); + $this->fints->execute($getAccounts); + dol_syslog("BankImport HKEKP: GetSEPAAccounts ausgefuehrt", LOG_DEBUG); + + if ($getAccounts->needsTan()) { + dol_syslog("BankImport HKEKP: GetSEPAAccounts benoetigt TAN", LOG_DEBUG); + $this->pendingAction = $getAccounts; + $tanRequest = $getAccounts->getTanRequest(); + $this->tanChallenge = $tanRequest->getChallenge(); + return 0; + } + + $accounts = $getAccounts->getAccounts(); + dol_syslog("BankImport HKEKP: ".count($accounts)." SEPA-Konten gefunden", LOG_DEBUG); + + foreach ($accounts as $idx => $acc) { + dol_syslog("BankImport HKEKP: Konto ".($idx+1).": IBAN=".$acc->getIban() + .", BIC=".$acc->getBic() + .", Ktonr=".$acc->getAccountNumber() + .", BLZ=".$acc->getSubAccount(), LOG_DEBUG); + } + + // Passendes Konto per IBAN finden + $selectedAccount = null; + dol_syslog("BankImport HKEKP: Suche Konto mit IBAN=".$this->iban, LOG_DEBUG); + foreach ($accounts as $account) { + if ($account->getIban() === $this->iban) { + $selectedAccount = $account; + dol_syslog("BankImport HKEKP: IBAN-Match gefunden!", LOG_DEBUG); + break; + } + } + + if ($selectedAccount === null) { + if (!empty($accounts)) { + $selectedAccount = $accounts[0]; + dol_syslog("BankImport HKEKP: KEIN IBAN-Match! Verwende erstes Konto: ".$selectedAccount->getIban(), LOG_WARNING); + } else { + $this->error = 'Keine Konten gefunden'; + dol_syslog("BankImport HKEKP: ABBRUCH - keine Konten gefunden", LOG_ERR); + return -1; + } + } + + // BPD (Bank Parameter Data) abfragen und loggen + dol_syslog("BankImport HKEKP: Rufe getBankParameters() ab...", LOG_DEBUG); + $params = $this->getBankParameters(); + dol_syslog("BankImport HKEKP: BPD enthaelt ".count($params)." Geschaeftsvorfaelle", LOG_DEBUG); + dol_syslog("BankImport HKEKP: BPD-Segmente: ".implode(', ', array_keys($params)), LOG_DEBUG); + + // Detailliert loggen welche Versionen unterstuetzt werden + foreach ($params as $segName => $versions) { + if (in_array($segName, ['HIEPS', 'HIEKAS', 'HIKEP', 'HIKAS', 'HIKAZS', 'HICAZS', 'HIPINS'])) { + dol_syslog("BankImport: BPD Detail: ".$segName." Versionen=[".implode(',', $versions)."]", LOG_DEBUG); + } + } + + // Strategie: HKEKP (PDF-spezifisch) bevorzugen, Fallback auf HKEKA (generisch) + $useHkekp = isset($params['HIEPS']); + $useHkeka = isset($params['HIEKAS']); + + dol_syslog("BankImport: HIEPS (HKEKP)=".($useHkekp ? 'JA' : 'NEIN') + .", HIEKAS (HKEKA)=".($useHkeka ? 'JA' : 'NEIN'), LOG_DEBUG); + + if (!$useHkekp && !$useHkeka) { + $this->error = 'Die Bank unterstuetzt keine elektronischen Kontoauszuege (weder HKEKP/HIEPS noch HKEKA/HIEKAS in BPD)'; + dol_syslog("BankImport: Weder HIEPS noch HIEKAS in BPD! Kontoauszuege nicht unterstuetzt.", LOG_WARNING); + dol_syslog("BankImport: Alle verfuegbaren BPD-Parameter: ".implode(', ', array_keys($params)), LOG_WARNING); + return -1; + } + + dol_syslog("BankImport: Starte Abruf fuer ".$selectedAccount->getIban() + .($statementNumber ? " Nr.".$statementNumber : " (alle)") + .($year ? " Jahr ".$year : " (alle Jahre)"), LOG_DEBUG); + + $pdfStatements = []; + + if ($useHkekp) { + // === HKEKP: PDF-spezifischer Kontoauszug === + dol_syslog("BankImport HKEKP: HIEPS gefunden! Versionen: [".implode(',', $params['HIEPS'])."]", LOG_DEBUG); + dol_syslog("BankImport HKEKP: Erstelle GetBankStatement Action...", LOG_DEBUG); + $getBankStatement = GetBankStatement::create($selectedAccount, $statementNumber, $year); + dol_syslog("BankImport HKEKP: Fuehre GetBankStatement aus (fints->execute)...", LOG_DEBUG); + $this->fints->execute($getBankStatement); + dol_syslog("BankImport HKEKP: GetBankStatement ausgefuehrt", LOG_DEBUG); + + if ($getBankStatement->needsTan()) { + dol_syslog("BankImport HKEKP: GetBankStatement benoetigt TAN", LOG_DEBUG); + $this->pendingAction = $getBankStatement; + $tanRequest = $getBankStatement->getTanRequest(); + $this->tanChallenge = $tanRequest->getChallenge(); + return 0; + } + + $pdfStatements = $getBankStatement->getPdfStatements(); + dol_syslog("BankImport HKEKP: ".count($pdfStatements)." PDFs empfangen", LOG_DEBUG); + } else { + // === HKEKA: Generischer Kontoauszug (mit Format=PDF) === + dol_syslog("BankImport HKEKA: HIEKAS gefunden! Versionen: [".implode(',', $params['HIEKAS'])."]", LOG_DEBUG); + dol_syslog("BankImport HKEKA: Verwende HKEKA mit Format=3 (PDF)", LOG_DEBUG); + dol_syslog("BankImport HKEKA: Erstelle GetElectronicStatement Action...", LOG_DEBUG); + + $getStatement = GetElectronicStatement::create( + $selectedAccount, + GetElectronicStatement::FORMAT_PDF, + $statementNumber, + $year + ); + + dol_syslog("BankImport HKEKA: Fuehre GetElectronicStatement aus...", LOG_DEBUG); + $this->fints->execute($getStatement); + dol_syslog("BankImport HKEKA: GetElectronicStatement ausgefuehrt", LOG_DEBUG); + + if ($getStatement->needsTan()) { + dol_syslog("BankImport HKEKA: GetElectronicStatement benoetigt TAN", LOG_DEBUG); + $this->pendingAction = $getStatement; + $tanRequest = $getStatement->getTanRequest(); + $this->tanChallenge = $tanRequest->getChallenge(); + return 0; + } + + // Alle Statements holen, nach PDF filtern + $allStatements = $getStatement->getStatements(); + dol_syslog("BankImport HKEKA: ".count($allStatements)." Statements empfangen", LOG_DEBUG); + + foreach ($allStatements as $sIdx => $stmt) { + $format = $stmt['format'] ?? 'unbekannt'; + $data = $stmt['data']; + dol_syslog("BankImport HKEKA: Statement ".($sIdx+1).": Format=".$format + .", ".strlen($data)." Bytes, Anfang=".substr($data, 0, 10), LOG_DEBUG); + } + + // PDFs extrahieren (getPdfStatements filtert nach Format=3 oder %PDF-) + $pdfStatements = $getStatement->getPdfStatements(); + dol_syslog("BankImport HKEKA: Davon ".count($pdfStatements)." PDFs", LOG_DEBUG); + + // Falls keine PDFs, aber andere Formate: Hinweis + if (empty($pdfStatements) && !empty($allStatements)) { + $formats = array_map(function($s) { return $s['format'] ?? '?'; }, $allStatements); + dol_syslog("BankImport HKEKA: Keine PDFs! Empfangene Formate: ".implode(', ', $formats), LOG_WARNING); + $this->error = 'Kontoauszuege empfangen, aber nicht im PDF-Format (Formate: '.implode(', ', $formats).')'; + return -1; + } + } + + foreach ($pdfStatements as $pIdx => $pdf) { + dol_syslog("BankImport: PDF ".($pIdx+1).": ".strlen($pdf)." Bytes, beginnt mit: ".substr($pdf, 0, 10), LOG_DEBUG); + } + + dol_syslog("BankImport: ===== fetchBankStatements() ERFOLG - ".count($pdfStatements)." PDFs =====", LOG_DEBUG); + + return array( + 'count' => count($pdfStatements), + 'pdfs' => $pdfStatements, + 'iban' => $selectedAccount->getIban(), + ); + } catch (\Fhp\Protocol\UnexpectedResponseException $e) { + // Bank unterstuetzt den Geschaeftsvorfall nicht + $this->error = 'Kontoauszug-Abruf nicht unterstuetzt: '.$e->getMessage(); + dol_syslog("BankImport HKEKP: UnexpectedResponseException: ".$e->getMessage(), LOG_WARNING); + dol_syslog("BankImport HKEKP: Stack-Trace: ".$e->getTraceAsString(), LOG_DEBUG); + return -1; + } catch (Exception $e) { + $this->error = 'Fehler beim Kontoauszug-Abruf: '.$e->getMessage(); + dol_syslog("BankImport HKEKP: Exception (".get_class($e)."): ".$e->getMessage(), LOG_ERR); + dol_syslog("BankImport HKEKP: Stack-Trace: ".$e->getTraceAsString(), LOG_DEBUG); + return -1; + } + } + /** * Close FinTS connection * @@ -1019,301 +1270,4 @@ class BankImportFinTS { return $this->iban; } - - /** - * Get PDF bank statement via HKEKP - * - * @param int $accountIndex Index of account to use (default 0) - * @param int|null $statementNumber Optional: specific statement number - * @param int|null $statementYear Optional: statement year - * @return array|int Array with 'pdfData' and 'info', or 0 if TAN required, or -1 on error - */ - public function getStatementPDF($accountIndex = 0, $statementNumber = null, $statementYear = null) - { - global $conf; - - $this->error = ''; - - if (!$this->fints) { - $this->error = 'Not connected'; - return -1; - } - - try { - // Get accounts if not cached - if (empty($this->accounts)) { - $getAccounts = GetSEPAAccounts::create(); - $this->fints->execute($getAccounts); - - if ($getAccounts->needsTan()) { - $this->pendingAction = $getAccounts; - $tanRequest = $getAccounts->getTanRequest(); - $this->tanChallenge = $tanRequest->getChallenge(); - return 0; - } - - $this->accounts = $getAccounts->getAccounts(); - } - - if (empty($this->accounts) || !isset($this->accounts[$accountIndex])) { - $this->error = 'No accounts available or invalid account index'; - return -1; - } - - $selectedAccount = $this->accounts[$accountIndex]; - - dol_syslog("BankImport: Fetching PDF statement via HKEKP", LOG_DEBUG); - - $getPdf = GetStatementPDF::create( - $selectedAccount, - $statementNumber, - $statementYear - ); - - $this->fints->execute($getPdf); - - if ($getPdf->needsTan()) { - $this->pendingAction = $getPdf; - $tanRequest = $getPdf->getTanRequest(); - $this->tanChallenge = $tanRequest->getChallenge(); - return 0; - } - - $pdfData = $getPdf->getPdfData(); - $info = $getPdf->getStatementInfo(); - - if (empty($pdfData)) { - dol_syslog("BankImport: No PDF data received (no new statements available)", LOG_DEBUG); - return array( - 'pdfData' => '', - 'info' => array(), - 'message' => 'No new statements available' - ); - } - - dol_syslog("BankImport: Received PDF statement #".$info['statementNumber'].'/'.$info['statementYear'], LOG_DEBUG); - - return array( - 'pdfData' => $pdfData, - 'info' => $info - ); - - } catch (Exception $e) { - $this->error = $e->getMessage(); - dol_syslog("BankImport: HKEKP failed: ".$this->error, LOG_ERR); - - // Check if bank doesn't support HKEKP - if (stripos($this->error, 'HKEKP') !== false || stripos($this->error, 'not support') !== false) { - $this->error = 'Bank does not support PDF statements (HKEKP)'; - } - - return -1; - } - } - - /** - * Check if bank supports PDF statements (HKEKP) - * - * @return bool - */ - public function supportsPdfStatements() - { - if (!$this->fints) { - return false; - } - - try { - // Try to get BPD and check for HIEKPS - $reflection = new ReflectionClass($this->fints); - $bpdProperty = $reflection->getProperty('bpd'); - $bpdProperty->setAccessible(true); - $bpd = $bpdProperty->getValue($this->fints); - - if ($bpd === null) { - return false; - } - - $hiekps = $bpd->getLatestSupportedParameters('HIEKPS'); - return $hiekps !== null; - - } catch (Exception $e) { - return false; - } - } - - /** - * Check if bank supports archive statements (HKKAA) with PDF format - * - * @return bool - */ - public function supportsArchiveStatements() - { - if (!$this->fints) { - return false; - } - - try { - $reflection = new ReflectionClass($this->fints); - $bpdProperty = $reflection->getProperty('bpd'); - $bpdProperty->setAccessible(true); - $bpd = $bpdProperty->getValue($this->fints); - - if ($bpd === null) { - return false; - } - - $hikaas = $bpd->getLatestSupportedParameters('HIKAAS'); - if ($hikaas === null) { - return false; - } - - // Check if PDF format is supported - $param = $hikaas->getParameter(); - return $param->supportsPdf(); - - } catch (Exception $e) { - dol_syslog("BankImport: supportsArchiveStatements exception: ".$e->getMessage(), LOG_DEBUG); - return false; - } - } - - /** - * Check if bank supports any PDF statement method (HKEKP or HKKAA) - * - * @return string|false Method name ('HKEKP', 'HKKAA') or false if none supported - */ - public function getPdfStatementMethod() - { - // First try HKEKP (direct PDF) - if ($this->supportsPdfStatements()) { - return 'HKEKP'; - } - - // Fallback to HKKAA (archive) - if ($this->supportsArchiveStatements()) { - return 'HKKAA'; - } - - return false; - } - - /** - * Get PDF bank statement from archive via HKKAA - * - * @param int $accountIndex Index of account to use (default 0) - * @param \DateTime|null $fromDate Optional: start date - * @param \DateTime|null $toDate Optional: end date - * @return array|int Array with 'pdfData' and 'info', or 0 if TAN required, or -1 on error - */ - public function getStatementFromArchive($accountIndex = 0, $fromDate = null, $toDate = null) - { - global $conf; - - $this->error = ''; - - if (!$this->fints) { - $this->error = 'Not connected'; - return -1; - } - - try { - // Get accounts if not cached - if (empty($this->accounts)) { - $getAccounts = GetSEPAAccounts::create(); - $this->fints->execute($getAccounts); - - if ($getAccounts->needsTan()) { - $this->pendingAction = $getAccounts; - $tanRequest = $getAccounts->getTanRequest(); - $this->tanChallenge = $tanRequest->getChallenge(); - return 0; - } - - $this->accounts = $getAccounts->getAccounts(); - } - - if (empty($this->accounts) || !isset($this->accounts[$accountIndex])) { - $this->error = 'No accounts available or invalid account index'; - return -1; - } - - $selectedAccount = $this->accounts[$accountIndex]; - - dol_syslog("BankImport: Fetching PDF statement from archive via HKKAA", LOG_DEBUG); - - $getArchive = GetStatementFromArchive::create( - $selectedAccount, - GetStatementFromArchive::FORMAT_PDF, - $fromDate, - $toDate - ); - - $this->fints->execute($getArchive); - - if ($getArchive->needsTan()) { - $this->pendingAction = $getArchive; - $tanRequest = $getArchive->getTanRequest(); - $this->tanChallenge = $tanRequest->getChallenge(); - return 0; - } - - $pdfData = $getArchive->getPdfData(); - $info = $getArchive->getStatementInfo(); - - if (empty($pdfData)) { - dol_syslog("BankImport: No PDF data received from archive", LOG_DEBUG); - return array( - 'pdfData' => '', - 'info' => array(), - 'message' => 'No statements available in archive' - ); - } - - dol_syslog("BankImport: Received PDF statement from archive #".($info['statementNumber'] ?? '?').'/'.($info['statementYear'] ?? '?'), LOG_DEBUG); - - return array( - 'pdfData' => $pdfData, - 'info' => $info - ); - - } catch (Exception $e) { - $this->error = $e->getMessage(); - dol_syslog("BankImport: HKKAA failed: ".$this->error, LOG_ERR); - dol_syslog("BankImport: HKKAA Exception class: ".get_class($e), LOG_DEBUG); - - // Keep original error message for better debugging - return -1; - } - } - - /** - * Get PDF statement using best available method (HKEKP or HKKAA) - * - * @param int $accountIndex Index of account to use (default 0) - * @param int|null $statementNumber Optional: specific statement number (only for HKEKP) - * @param int|null $statementYear Optional: statement year (only for HKEKP) - * @return array|int Array with 'pdfData', 'info' and 'method', or 0 if TAN required, or -1 on error - */ - public function getStatementPDFAuto($accountIndex = 0, $statementNumber = null, $statementYear = null) - { - $method = $this->getPdfStatementMethod(); - - if ($method === false) { - $this->error = 'Bank does not support PDF statements (neither HKEKP nor HKKAA)'; - return -1; - } - - if ($method === 'HKEKP') { - $result = $this->getStatementPDF($accountIndex, $statementNumber, $statementYear); - } else { - // HKKAA doesn't support statement number, use date range instead - $result = $this->getStatementFromArchive($accountIndex); - } - - if (is_array($result)) { - $result['method'] = $method; - } - - return $result; - } } diff --git a/composer.json b/composer.json index 85f0bb9..d77bfa8 100755 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "license": "GPL-3.0-or-later", "require": { "php": ">=8.0", - "nemiah/php-fints": "^4.0" + "nemiah/php-fints": "^3.2" }, "replace": { "psr/log": "*" diff --git a/composer.lock b/composer.lock index ca4143e..4f0aff3 100755 --- a/composer.lock +++ b/composer.lock @@ -4,26 +4,26 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "32eb1d84f3157a4dee83ef5a81763257", + "content-hash": "cfc07b7e6c4a3dcfdcd6e754983b1a9b", "packages": [ { "name": "nemiah/php-fints", - "version": "4.0.0", + "version": "3.7.0", "source": { "type": "git", "url": "https://github.com/nemiah/phpFinTS.git", - "reference": "b37e6df7efd39b4e757537e782241d5abb6b2bb5" + "reference": "08257e10229db2d4ca8c54ed7fec0f390b332519" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nemiah/phpFinTS/zipball/b37e6df7efd39b4e757537e782241d5abb6b2bb5", - "reference": "b37e6df7efd39b4e757537e782241d5abb6b2bb5", + "url": "https://api.github.com/repos/nemiah/phpFinTS/zipball/08257e10229db2d4ca8c54ed7fec0f390b332519", + "reference": "08257e10229db2d4ca8c54ed7fec0f390b332519", "shasum": "" }, "require": { "ext-curl": "*", "ext-mbstring": "*", - "php": ">=8.3", + "php": ">=8.0", "psr/log": "^1|^2|^3" }, "require-dev": { @@ -51,9 +51,9 @@ "homepage": "https://github.com/nemiah/phpFinTS", "support": { "issues": "https://github.com/nemiah/phpFinTS/issues", - "source": "https://github.com/nemiah/phpFinTS/tree/4.0" + "source": "https://github.com/nemiah/phpFinTS/tree/3.7" }, - "time": "2026-01-16T07:56:30+00:00" + "time": "2025-10-14T15:05:56+00:00" } ], "packages-dev": [], diff --git a/core/modules/modBankImport.class.php b/core/modules/modBankImport.class.php index 981fd06..8c4aa20 100755 --- a/core/modules/modBankImport.class.php +++ b/core/modules/modBankImport.class.php @@ -76,7 +76,7 @@ class modBankImport extends DolibarrModules $this->editor_squarred_logo = ''; // Must be image filename into the module/img directory followed with @modulename. Example: 'myimage.png@bankimport' // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated', 'experimental_deprecated' or a version string like 'x.y.z' - $this->version = '3.5'; + $this->version = '3.4'; // Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; @@ -281,20 +281,6 @@ class modBankImport extends DolibarrModules 'test' => 'isModEnabled("bankimport") && getDolGlobalInt("BANKIMPORT_AUTO_ENABLED")', 'priority' => 50, ), - 1 => array( - 'label' => 'BankImportPdfFetch', - 'jobtype' => 'method', - 'class' => '/bankimport/class/bankimportcron.class.php', - 'objectname' => 'BankImportCron', - 'method' => 'doAutoFetchPdf', - 'parameters' => '', - 'comment' => 'Automatic PDF statement fetch via HKEKP', - 'frequency' => 1, - 'unitfrequency' => 86400, // Daily - 'status' => 0, // Disabled by default - 'test' => 'isModEnabled("bankimport") && getDolGlobalInt("BANKIMPORT_PDF_AUTO_ENABLED")', - 'priority' => 51, - ), ); /* END MODULEBUILDER CRON */ // Example: $this->cronjobs=array( diff --git a/langs/de_DE/bankimport.lang b/langs/de_DE/bankimport.lang index 7e1d68d..f9de815 100755 --- a/langs/de_DE/bankimport.lang +++ b/langs/de_DE/bankimport.lang @@ -55,10 +55,10 @@ SecurityInfo = Sicherheitshinweis SecurityInfoText = Die PIN wird verschlüsselt in der Datenbank gespeichert. Für zusätzliche Sicherheit sollte Ihre Dolibarr-Installation HTTPS verwenden. # -# Kontoauszüge Seite +# Umsaetze Seite # -BankStatements = Kontoauszüge -FetchStatements = Kontoauszüge abrufen +BankStatements = Umsätze +FetchStatements = Umsätze abrufen Transactions = Buchungen TransactionsFound = %s Buchungen gefunden NoTransactionsFound = Keine Buchungen im ausgewählten Zeitraum gefunden @@ -377,26 +377,22 @@ Open = Öffnen CashDiscount = Skonto # -# PDF Statement Fetch (HKEKP) +# FinTS Kontoauszug-Abruf (HKEKP) # +AutoFetchStatements = Kontoauszüge automatisch von der Bank abrufen +AutoFetchStatementsDesc = Lädt die neuesten elektronischen Kontoauszüge (PDF) direkt von der Bank per FinTS herunter. FetchFromBank = Von Bank abrufen -FetchNewStatements = Neue Auszüge abrufen -FetchNewStatementsDesc = Ruft alle noch nicht abgerufenen PDF-Kontoauszüge von der Bank ab -FetchSpecificStatement = Bestimmten Auszug abrufen -Fetch = Abrufen -ErrorFinTSNotConfigured = FinTS-Verbindung nicht konfiguriert -ErrorFinTSConnection = FinTS-Verbindungsfehler -ErrorBankDoesNotSupportPdfStatements = Bank unterstützt keine PDF-Kontoauszüge (HKEKP) -ErrorFetchingPdfStatement = Fehler beim Abrufen des PDF-Kontoauszugs -NoPdfStatementsAvailable = Keine neuen PDF-Kontoauszüge verfügbar -PdfStatementFetched = PDF-Kontoauszug %s erfolgreich abgerufen -ErrorSavingPdfFile = Fehler beim Speichern der PDF-Datei -FinTSNotConfiguredForPdf = FinTS nicht konfiguriert - PDF-Abruf nicht möglich -AutoPdfFetchDisabled = Automatischer PDF-Abruf ist deaktiviert -BankImportPdfFetch = PDF-Kontoauszüge abrufen -PdfFetchCronDescription = Automatischer Abruf von PDF-Kontoauszügen via FinTS (HKEKP) -PdfStatementsFetched = %s PDF-Kontoauszüge abgerufen -ManualUpload = Manuell hochladen -Source = Quelle -SourceUpload = Hochgeladen -SourceFinTS = FinTS-Abruf +FinTSLibraryMissing = phpFinTS-Bibliothek nicht installiert +WaitingForTanConfirmation = Warte auf TAN-Bestätigung in der SecureGo Plus App... +TanCheckFailed = TAN-Prüfung fehlgeschlagen +TanTimeout = TAN-Bestätigung: Zeitüberschreitung (2 Minuten) +TanRequiredForStatements = TAN-Bestätigung für Kontoauszug-Abruf erforderlich +FetchStatementsFailed = Kontoauszug-Abruf fehlgeschlagen +NoStatementsAvailable = Keine neuen Kontoauszüge bei der Bank verfügbar +StatementsDownloaded = %s von %s Kontoauszügen erfolgreich heruntergeladen und gespeichert +StatementsDownloadErrors = %s Kontoauszüge konnten nicht gespeichert werden +StatementsSkippedNoNumber = %s PDF(s) ohne Auszugsnummer übersprungen (vermutlich Saldenmitteilungen) +StatementsNotPdfFormat = Kontoauszüge empfangen, aber nicht im PDF-Format +StatementsUsingHKEKA = Nutze HKEKA (generischer Kontoauszug) statt HKEKP +StatementsUsingHKEKP = Nutze HKEKP (PDF-Kontoauszug) +NeitherHKEKPnorHKEKA = Die Bank unterstützt weder HKEKP noch HKEKA für elektronische Kontoauszüge diff --git a/langs/en_US/bankimport.lang b/langs/en_US/bankimport.lang index e4c5c3d..6be3788 100755 --- a/langs/en_US/bankimport.lang +++ b/langs/en_US/bankimport.lang @@ -55,10 +55,10 @@ SecurityInfo = Security Information SecurityInfoText = The PIN is stored encrypted in the database. For additional security, ensure your Dolibarr installation uses HTTPS. # -# Statements page +# Transactions page # -BankStatements = Bank Statements -FetchStatements = Fetch Statements +BankStatements = Transactions +FetchStatements = Fetch Transactions Transactions = Transactions TransactionsFound = %s transactions found NoTransactionsFound = No transactions found in the selected period @@ -271,3 +271,24 @@ Open = Open # Cash Discount / Skonto # CashDiscount = Cash Discount + +# +# FinTS Bank Statement Retrieval (HKEKP) +# +AutoFetchStatements = Automatically fetch bank statements +AutoFetchStatementsDesc = Downloads the latest electronic bank statements (PDF) directly from the bank via FinTS. +FetchFromBank = Fetch from bank +FinTSLibraryMissing = phpFinTS library not installed +WaitingForTanConfirmation = Waiting for TAN confirmation in SecureGo Plus app... +TanCheckFailed = TAN check failed +TanTimeout = TAN confirmation: Timeout (2 minutes) +TanRequiredForStatements = TAN confirmation required for statement retrieval +FetchStatementsFailed = Bank statement retrieval failed +NoStatementsAvailable = No new bank statements available at the bank +StatementsDownloaded = %s of %s bank statements successfully downloaded and saved +StatementsDownloadErrors = %s bank statements could not be saved +StatementsSkippedNoNumber = %s PDF(s) without statement number skipped (probably balance notifications) +StatementsNotPdfFormat = Bank statements received but not in PDF format +StatementsUsingHKEKA = Using HKEKA (generic statement) instead of HKEKP +StatementsUsingHKEKP = Using HKEKP (PDF statement) +NeitherHKEKPnorHKEKA = The bank supports neither HKEKP nor HKEKA for electronic statements diff --git a/pdfstatements.php b/pdfstatements.php index b7c7c30..2c6549d 100755 --- a/pdfstatements.php +++ b/pdfstatements.php @@ -73,103 +73,296 @@ if (!$user->hasRight('bankimport', 'read')) { $statement = new BankImportStatement($db); -// Fetch PDF statement from bank via HKEKP -if ($action == 'fetchpdf' || $action == 'fetchpdf_single') { +// FinTS: Elektronische Kontoauszuege automatisch abrufen (HKEKP) +if ($action == 'fetchfints') { + dol_syslog("BankImport HKEKP: ========== START fetchfints Action ==========", LOG_DEBUG); + dol_syslog("BankImport HKEKP: User=".$user->login." (ID ".$user->id."), Zeitpunkt=".date('Y-m-d H:i:s'), LOG_DEBUG); + if (!$user->hasRight('bankimport', 'write')) { + dol_syslog("BankImport HKEKP: Zugriff verweigert - User hat kein Schreibrecht", LOG_WARNING); accessforbidden(); } - $fetchNumber = ($action == 'fetchpdf_single') ? GETPOSTINT('fetch_number') : null; - $fetchYear = ($action == 'fetchpdf_single') ? GETPOSTINT('fetch_year') : null; + $fints = new BankImportFinTS($db); - // Check FinTS configuration - $fintsUrl = getDolGlobalString('BANKIMPORT_FINTS_URL'); - $fintsBlz = getDolGlobalString('BANKIMPORT_FINTS_BLZ'); - $fintsUser = getDolGlobalString('BANKIMPORT_FINTS_USERNAME'); - $fintsPin = getDolGlobalString('BANKIMPORT_FINTS_PIN'); + dol_syslog("BankImport HKEKP: FinTS-Objekt erstellt, isConfigured=".($fints->isConfigured() ? 'JA' : 'NEIN') + .", isLibraryAvailable=".($fints->isLibraryAvailable() ? 'JA' : 'NEIN'), LOG_DEBUG); + dol_syslog("BankImport HKEKP: Konfiguration - URL=".getDolGlobalString('BANKIMPORT_FINTS_URL') + .", BLZ=".getDolGlobalString('BANKIMPORT_FINTS_BLZ') + .", IBAN=".getDolGlobalString('BANKIMPORT_FINTS_IBAN') + .", User=".getDolGlobalString('BANKIMPORT_FINTS_USERNAME'), LOG_DEBUG); - if (empty($fintsUrl) || empty($fintsBlz) || empty($fintsUser) || empty($fintsPin)) { - setEventMessages($langs->trans("ErrorFinTSNotConfigured"), null, 'errors'); + if (!$fints->isConfigured()) { + dol_syslog("BankImport HKEKP: ABBRUCH - FinTS nicht konfiguriert", LOG_WARNING); + setEventMessages($langs->trans("FinTSNotConfigured"), null, 'errors'); + } elseif (!$fints->isLibraryAvailable()) { + dol_syslog("BankImport HKEKP: ABBRUCH - phpFinTS Library fehlt", LOG_WARNING); + setEventMessages($langs->trans("FinTSLibraryMissing"), null, 'errors'); } else { - $fints = new BankImportFinTS($db); + // Login + dol_syslog("BankImport HKEKP: Starte login()...", LOG_DEBUG); $loginResult = $fints->login(); + dol_syslog("BankImport HKEKP: login() Ergebnis=".$loginResult." (1=OK, 0=TAN, -1=Fehler)", LOG_DEBUG); - if ($loginResult < 0) { - setEventMessages($langs->trans("ErrorFinTSConnection").': '.$fints->error, null, 'errors'); - } elseif ($loginResult === 0) { - // TAN required for login - setEventMessages($langs->trans("TANRequired").($fints->tanChallenge ? ': '.$fints->tanChallenge : ''), null, 'warnings'); - $fints->close(); - } else { - // Check if bank supports any PDF statement method (HKEKP or HKKAA) - $pdfMethod = $fints->getPdfStatementMethod(); - if ($pdfMethod === false) { - setEventMessages($langs->trans("ErrorBankDoesNotSupportPdfStatements"), null, 'errors'); - $fints->close(); + if ($loginResult == -1) { + dol_syslog("BankImport HKEKP: Login FEHLGESCHLAGEN - ".$fints->error, LOG_ERR); + setEventMessages('FinTS Login fehlgeschlagen: '.$fints->error, null, 'errors'); + } + + if ($loginResult == 0) { + // TAN benoetigt - Decoupled-Polling + $tanConfirmed = false; + $maxWait = 120; // Max 2 Minuten warten + $waited = 0; + + if ($fints->selectedTanMode && $fints->selectedTanMode->isDecoupled()) { + dol_syslog("BankImport HKEKP: TAN-Modus: ".$fints->selectedTanMode->getName() + ." (ID ".$fints->selectedTanMode->getId().", Decoupled=JA)", LOG_DEBUG); + dol_syslog("BankImport HKEKP: Starte Decoupled-TAN-Polling (max ".$maxWait."s, Intervall 3s)...", LOG_DEBUG); + setEventMessages($langs->trans("WaitingForTanConfirmation"), null, 'mesgs'); + + while ($waited < $maxWait) { + sleep(3); + $waited += 3; + $tanStatus = $fints->checkDecoupledTan(); + dol_syslog("BankImport HKEKP: TAN-Poll nach ".$waited."s - Status=".$tanStatus." (1=OK, 0=Wartend, -1=Fehler)", LOG_DEBUG); + + if ($tanStatus == 1) { + $tanConfirmed = true; + dol_syslog("BankImport HKEKP: TAN BESTAETIGT nach ".$waited."s", LOG_DEBUG); + break; + } elseif ($tanStatus < 0) { + dol_syslog("BankImport HKEKP: TAN-Pruefung FEHLGESCHLAGEN: ".$fints->error, LOG_ERR); + setEventMessages($langs->trans("TanCheckFailed").': '.$fints->error, null, 'errors'); + break; + } + } + + if (!$tanConfirmed && $waited >= $maxWait) { + dol_syslog("BankImport HKEKP: TAN-TIMEOUT nach ".$waited."s", LOG_WARNING); + setEventMessages($langs->trans("TanTimeout"), null, 'errors'); + } } else { - dol_syslog("BankImport: Using PDF method: ".$pdfMethod, LOG_DEBUG); + $tanModeName = $fints->selectedTanMode ? $fints->selectedTanMode->getName() : 'UNBEKANNT'; + $tanModeDecoupled = $fints->selectedTanMode ? ($fints->selectedTanMode->isDecoupled() ? 'JA' : 'NEIN') : '?'; + dol_syslog("BankImport HKEKP: TAN-Modus: ".$tanModeName." (Decoupled=".$tanModeDecoupled.") - Manuell benoetigt!", LOG_DEBUG); + dol_syslog("BankImport HKEKP: TAN-Challenge: ".$fints->tanChallenge, LOG_DEBUG); + setEventMessages($langs->trans("TanRequired").': '.$fints->tanChallenge, null, 'warnings'); + } - // Fetch PDF using auto method (tries HKEKP first, falls back to HKKAA) - $pdfResult = $fints->getStatementPDFAuto(0, $fetchNumber, $fetchYear); + if (!$tanConfirmed) { + dol_syslog("BankImport HKEKP: TAN nicht bestaetigt, schliesse Verbindung", LOG_DEBUG); + $fints->close(); + $action = ''; + } else { + $loginResult = 1; // Weiter mit Abruf + } + } - if ($pdfResult === 0) { - // TAN required - save to session and show TAN form - $_SESSION['bankimport_pending_action'] = serialize($fints); - setEventMessages($langs->trans("TANRequired").': '.$fints->tanChallenge, null, 'warnings'); - } elseif ($pdfResult === -1) { - setEventMessages($langs->trans("ErrorFetchingPdfStatement").': '.$fints->error, null, 'errors'); - } elseif (empty($pdfResult['pdfData'])) { - setEventMessages($langs->trans("NoPdfStatementsAvailable"), null, 'warnings'); + if ($loginResult == 1) { + // Kontoauszuege abrufen + $fetchYear = GETPOST('fetch_year', 'alpha') ?: null; + dol_syslog("BankImport HKEKP: Login erfolgreich, starte fetchBankStatements(year=" + .($fetchYear ?: 'ALLE').")", LOG_DEBUG); + + $result = $fints->fetchBankStatements(null, $fetchYear); + dol_syslog("BankImport HKEKP: fetchBankStatements() Ergebnis-Typ=".gettype($result) + .(is_array($result) ? " count=".$result['count'] : " val=".$result), LOG_DEBUG); + + if ($result === 0) { + dol_syslog("BankImport HKEKP: fetchBankStatements benoetigt TAN", LOG_WARNING); + setEventMessages($langs->trans("TanRequiredForStatements"), null, 'warnings'); + } elseif ($result === -1) { + dol_syslog("BankImport HKEKP: fetchBankStatements FEHLGESCHLAGEN: ".$fints->error, LOG_ERR); + setEventMessages($langs->trans("FetchStatementsFailed").': '.$fints->error, null, 'errors'); + } elseif (is_array($result)) { + $pdfCount = $result['count']; + $savedCount = 0; + $errorCountFints = 0; + + dol_syslog("BankImport HKEKP: ".$pdfCount." PDFs empfangen, IBAN=".$result['iban'], LOG_DEBUG); + + if ($pdfCount == 0) { + dol_syslog("BankImport HKEKP: Keine Auszuege verfuegbar", LOG_DEBUG); + setEventMessages($langs->trans("NoStatementsAvailable"), null, 'warnings'); } else { - // Save PDF - $info = $pdfResult['info']; - $pdfData = $pdfResult['pdfData']; + // PDFs speichern ueber die bestehende bankstatement-Logik + $dir = BankImportStatement::getStorageDir(); + dol_syslog("BankImport HKEKP: Speicher-Verzeichnis: ".$dir, LOG_DEBUG); - // Check if statement already exists - $stmt = new BankImportStatement($db); - $stmt->statement_number = $info['statementNumber']; - $stmt->statement_year = $info['statementYear']; - $stmt->iban = $info['iban'] ?: getDolGlobalString('BANKIMPORT_IBAN'); - - if ($stmt->exists()) { - setEventMessages($langs->trans("StatementAlreadyExists").': '.$stmt->statement_number.'/'.$stmt->statement_year, null, 'warnings'); - } else { - // Save PDF to file - $dir = BankImportStatement::getStorageDir(); - $ibanPart = preg_replace('/[^A-Z0-9]/', '', strtoupper($stmt->iban ?: 'KONTO')); - $filename = sprintf('Kontoauszug_%s_%d_%s.pdf', - $ibanPart, - $stmt->statement_year, - str_pad($stmt->statement_number, 3, '0', STR_PAD_LEFT) - ); - - $filepath = $dir.'/'.$filename; - if (file_put_contents($filepath, $pdfData) !== false) { - $stmt->filename = $filename; - $stmt->filepath = $filepath; - $stmt->filesize = strlen($pdfData); - $stmt->statement_date = $info['creationDate'] ? $info['creationDate']->getTimestamp() : dol_now(); - $stmt->import_key = 'fints_'.date('YmdHis'); - - $result = $stmt->create($user); - if ($result > 0) { - setEventMessages($langs->trans("PdfStatementFetched", $stmt->statement_number.'/'.$stmt->statement_year), null, 'mesgs'); - $year = $stmt->statement_year; - } else { - setEventMessages($stmt->error, null, 'errors'); - @unlink($filepath); - } + // Identische PDFs deduplizieren (Bank sendet teilweise Duplikate) + $seenHashes = []; + $uniquePdfs = []; + foreach ($result['pdfs'] as $pdfData) { + $hash = md5($pdfData); + if (!isset($seenHashes[$hash])) { + $seenHashes[$hash] = true; + $uniquePdfs[] = $pdfData; } else { - setEventMessages($langs->trans("ErrorSavingPdfFile"), null, 'errors'); + dol_syslog("BankImport HKEKP: Duplikat-PDF uebersprungen (Hash=".substr($hash, 0, 8)."...)", LOG_DEBUG); } } + $result['pdfs'] = $uniquePdfs; + $pdfCount = count($uniquePdfs); + $skippedCount = 0; + + foreach ($result['pdfs'] as $idx => $pdfData) { + dol_syslog("BankImport HKEKP: --- PDF ".($idx+1)."/".$pdfCount." ---", LOG_DEBUG); + dol_syslog("BankImport HKEKP: PDF-Groesse=".strlen($pdfData)." Bytes, Erste 20 Bytes=".bin2hex(substr($pdfData, 0, 20)), LOG_DEBUG); + dol_syslog("BankImport HKEKP: PDF startet mit: ".substr($pdfData, 0, 10), LOG_DEBUG); + + // PDF in Temp-Datei schreiben fuer Metadaten-Extraktion + $tmpFile = tempnam(sys_get_temp_dir(), 'fints_stmt_'); + file_put_contents($tmpFile, $pdfData); + dol_syslog("BankImport HKEKP: Temp-Datei: ".$tmpFile." (".filesize($tmpFile)." Bytes)", LOG_DEBUG); + + // Metadaten aus PDF parsen + dol_syslog("BankImport HKEKP: Starte parsePdfMetadata()...", LOG_DEBUG); + $parsed = BankImportStatement::parsePdfMetadata($tmpFile); + + if ($parsed) { + dol_syslog("BankImport HKEKP: Metadaten erkannt: IBAN=".$parsed['iban'] + .", Nr=".$parsed['statement_number'].", Jahr=".$parsed['statement_year'] + .", Datum=".$parsed['statement_date'] + .", Von=".$parsed['date_from'].", Bis=".$parsed['date_to'] + .", Saldo_Start=".$parsed['opening_balance'].", Saldo_Ende=".$parsed['closing_balance'], LOG_DEBUG); + } else { + dol_syslog("BankImport HKEKP: Metadaten NICHT erkannt - verwende Fallback", LOG_WARNING); + } + + $stmt = new BankImportStatement($db); + if ($parsed && !empty($parsed['statement_number'])) { + // Vollstaendige Metadaten mit Auszugsnummer + $stmt->iban = $parsed['iban'] ?: $result['iban']; + $stmt->statement_number = $parsed['statement_number']; + $stmt->statement_year = $parsed['statement_year']; + $stmt->statement_date = $parsed['statement_date']; + $stmt->date_from = $parsed['date_from']; + $stmt->date_to = $parsed['date_to']; + $stmt->opening_balance = $parsed['opening_balance']; + $stmt->closing_balance = $parsed['closing_balance']; + } elseif ($parsed && !empty($parsed['iban'])) { + // IBAN erkannt aber keine Auszugsnummer (z.B. Saldenmitteilung) + // Ueberspringe solche PDFs - ohne Nummer nicht sinnvoll speicherbar + dol_syslog("BankImport HKEKP: PDF uebersprungen - IBAN erkannt aber keine Auszugsnummer (wahrscheinlich Saldenmitteilung)", LOG_WARNING); + $skippedCount++; + @unlink($tmpFile); + continue; + } else { + // Keinerlei Metadaten - Fallback mit Index + $stmt->iban = $result['iban']; + $stmt->statement_number = (string) ($idx + 1); + $stmt->statement_year = (int) date('Y'); + } + + $stmt->import_key = 'fints_'.date('YmdHis').'_'.$user->id; + dol_syslog("BankImport HKEKP: import_key=".$stmt->import_key, LOG_DEBUG); + + // Duplikat-Pruefung + if ($stmt->statement_number && $stmt->exists()) { + dol_syslog("BankImport HKEKP: DUPLIKAT - Auszug ".$stmt->statement_number."/".$stmt->statement_year." existiert bereits, ueberspringe", LOG_DEBUG); + @unlink($tmpFile); + continue; + } + + // Dateiname generieren + if ($parsed) { + $newFilename = BankImportStatement::generateFilename($parsed); + } else { + $newFilename = sprintf('Kontoauszug_FinTS_%s_%d_%03d.pdf', + preg_replace('/[^A-Z0-9]/', '', strtoupper($stmt->iban)), + $stmt->statement_year, + $idx + 1 + ); + } + dol_syslog("BankImport HKEKP: Dateiname=".$newFilename, LOG_DEBUG); + + $stmt->filepath = $dir.'/'.$newFilename; + + // Kollisionsvermeidung + if (file_exists($stmt->filepath)) { + $newFilename = pathinfo($newFilename, PATHINFO_FILENAME).'_'.date('His').'.pdf'; + $stmt->filepath = $dir.'/'.$newFilename; + dol_syslog("BankImport HKEKP: Datei existiert bereits, neuer Name: ".$newFilename, LOG_DEBUG); + } + + $stmt->filename = $newFilename; + + // PDF von Temp nach Ziel verschieben + if (!rename($tmpFile, $stmt->filepath)) { + dol_syslog("BankImport HKEKP: rename() fehlgeschlagen, verwende copy()", LOG_DEBUG); + copy($tmpFile, $stmt->filepath); + @unlink($tmpFile); + } + + $stmt->filesize = filesize($stmt->filepath); + dol_syslog("BankImport HKEKP: Datei gespeichert: ".$stmt->filepath." (".$stmt->filesize." Bytes)", LOG_DEBUG); + + // In DB speichern + dol_syslog("BankImport HKEKP: Starte DB create()...", LOG_DEBUG); + $dbResult = $stmt->create($user); + dol_syslog("BankImport HKEKP: DB create() Ergebnis=".$dbResult." (>0=ID, <0=Fehler)", LOG_DEBUG); + + if ($dbResult > 0) { + dol_syslog("BankImport HKEKP: DB-Eintrag erstellt mit ID=".$dbResult, LOG_DEBUG); + + // FinTS-Transaktionen verknuepfen + dol_syslog("BankImport HKEKP: Starte linkTransactions()...", LOG_DEBUG); + $linkResult = $stmt->linkTransactions(); + dol_syslog("BankImport HKEKP: linkTransactions() Ergebnis=".$linkResult, LOG_DEBUG); + + // PDF-Einzelbuchungen parsen + dol_syslog("BankImport HKEKP: Starte parsePdfTransactions()...", LOG_DEBUG); + $pdfLines = $stmt->parsePdfTransactions(); + dol_syslog("BankImport HKEKP: parsePdfTransactions() ergab ".(is_array($pdfLines) ? count($pdfLines) : 0)." Buchungszeilen", LOG_DEBUG); + if (!empty($pdfLines)) { + $stmt->saveStatementLines($pdfLines); + dol_syslog("BankImport HKEKP: saveStatementLines() abgeschlossen", LOG_DEBUG); + } + + // PDF in Dolibarr Bank-Verzeichnis kopieren + $uploadBankAccountId = getDolGlobalInt('BANKIMPORT_BANK_ACCOUNT_ID'); + dol_syslog("BankImport HKEKP: BANKIMPORT_BANK_ACCOUNT_ID=".$uploadBankAccountId, LOG_DEBUG); + if ($uploadBankAccountId > 0) { + dol_syslog("BankImport HKEKP: Starte copyToDolibarrStatementDir()...", LOG_DEBUG); + $stmt->copyToDolibarrStatementDir($uploadBankAccountId); + dol_syslog("BankImport HKEKP: Starte reconcileBankEntries()...", LOG_DEBUG); + $reconcileResult = $stmt->reconcileBankEntries($user, $uploadBankAccountId); + dol_syslog("BankImport HKEKP: reconcileBankEntries() Ergebnis=".$reconcileResult, LOG_DEBUG); + } + + $savedCount++; + } else { + $errorCountFints++; + dol_syslog("BankImport HKEKP: DB-FEHLER bei create(): ".$stmt->error, LOG_ERR); + if (file_exists($stmt->filepath)) { + @unlink($stmt->filepath); + } + } + } + + dol_syslog("BankImport HKEKP: Zusammenfassung: ".$savedCount." gespeichert, ".$errorCountFints." Fehler, ".$skippedCount." uebersprungen von ".$pdfCount." PDFs", LOG_DEBUG); + + if ($savedCount > 0) { + setEventMessages($langs->trans("StatementsDownloaded", $savedCount, $pdfCount), null, 'mesgs'); + } + if ($errorCountFints > 0) { + setEventMessages($langs->trans("StatementsDownloadErrors", $errorCountFints), null, 'warnings'); + } + if ($skippedCount > 0) { + setEventMessages($langs->trans("StatementsSkippedNoNumber", $skippedCount), null, 'warnings'); + } } } $fints->close(); + dol_syslog("BankImport HKEKP: FinTS-Verbindung geschlossen", LOG_DEBUG); } + + dol_syslog("BankImport HKEKP: ========== ENDE fetchfints Action ==========", LOG_DEBUG); + header("Location: ".$_SERVER['PHP_SELF']."?year=".date('Y')); + exit; } - $action = ''; } // Upload PDF (supports multiple files) @@ -622,6 +815,18 @@ print ''.$langs->trans("PDFStatementsInfo").'
'; print $langs->trans("PDFStatementsInfoDesc"); print ''; +// FinTS-Abruf Button (wenn konfiguriert) +$fintsCheck = new BankImportFinTS($db); +if ($fintsCheck->isConfigured() && $fintsCheck->isLibraryAvailable() && $user->hasRight('bankimport', 'write')) { + print '
'; + print ''.img_picto('', 'bank', 'class="pictofixedwidth"').$langs->trans("AutoFetchStatements").'
'; + print ''.$langs->trans("AutoFetchStatementsDesc").'

'; + print ''; + print img_picto('', 'download', 'class="pictofixedwidth"').$langs->trans("FetchFromBank"); + print ''; + print '
'; +} + // Delete confirmation dialog if ($action == 'delete') { $id = GETPOSTINT('id'); @@ -640,76 +845,20 @@ if ($action == 'delete') { print $formconfirm; } -// Check if FinTS is configured for PDF fetch -$fintsConfigured = !empty(getDolGlobalString('BANKIMPORT_FINTS_URL')) - && !empty(getDolGlobalString('BANKIMPORT_FINTS_BLZ')) - && !empty(getDolGlobalString('BANKIMPORT_FINTS_USERNAME')) - && !empty(getDolGlobalString('BANKIMPORT_FINTS_PIN')); - -print '
'; - -// Left side: Fetch from bank (if FinTS configured) -print '
'; - -if ($fintsConfigured) { - print ''; - print ''; - print ''; - print ''; - - // Fetch all new statements - print ''; - print ''; - print ''; - - // Fetch specific statement - print ''; - print ''; - print ''; - - print '
'.img_picto('', 'download', 'class="pictofixedwidth"').$langs->trans("FetchFromBank").'
'; - print ''; - print img_picto('', 'refresh', 'class="pictofixedwidth"').$langs->trans("FetchNewStatements"); - print ''; - print '
'.$langs->trans("FetchNewStatementsDesc").''; - print '
'; - print '
'; - print ''; - print ''; - print $langs->trans("FetchSpecificStatement").': '; - print ''; - print ' / '; - $years = array(); - for ($y = (int) date('Y'); $y >= ((int) date('Y') - 5); $y--) { - $years[$y] = $y; - } - print $form->selectarray('fetch_year', $years, (int) date('Y'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth75'); - print ' '; - print '
'; - print '
'; -} else { - print '
'; - print img_warning().' '.$langs->trans("FinTSNotConfiguredForPdf"); - print ' '.$langs->trans("GoToSetup").''; - print '
'; -} - -print '
'; // fichehalfleft - -// Right side: Manual upload -print '
'; - // Upload form $defaultMode = getDolGlobalString('BANKIMPORT_UPLOAD_MODE') ?: 'auto'; $uploadMode = GETPOST('upload_mode', 'alpha') ?: $defaultMode; +print '
'; +print '
'; + print '
'; print ''; print ''; print ''; print ''; -print ''; +print ''; print ''; // Upload mode selection @@ -834,7 +983,7 @@ function toggleUploadMode() { document.addEventListener("DOMContentLoaded", function() { toggleUploadMode(); }); '; -print ''; // fichehalfright (upload form) +print ''; // fichehalfleft print ''; // fichecenter print '

'; diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index c3d39e6..a46b42a 100755 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -6,9 +6,6 @@ $vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( - 'BankImportCron' => $baseDir . '/class/bankimportcron.class.php', 'BankImportFinTS' => $baseDir . '/class/fints.class.php', - 'BankImportStatement' => $baseDir . '/class/bankstatement.class.php', - 'BankImportTransaction' => $baseDir . '/class/banktransaction.class.php', 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', ); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 80787f4..5ec4db2 100755 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -24,10 +24,7 @@ class ComposerStaticInitcfc07b7e6c4a3dcfdcd6e754983b1a9b ); public static $classMap = array ( - 'BankImportCron' => __DIR__ . '/../..' . '/class/bankimportcron.class.php', 'BankImportFinTS' => __DIR__ . '/../..' . '/class/fints.class.php', - 'BankImportStatement' => __DIR__ . '/../..' . '/class/bankstatement.class.php', - 'BankImportTransaction' => __DIR__ . '/../..' . '/class/banktransaction.class.php', 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', ); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 7970181..88c07eb 100755 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -2,23 +2,23 @@ "packages": [ { "name": "nemiah/php-fints", - "version": "4.0.0", - "version_normalized": "4.0.0.0", + "version": "3.7.0", + "version_normalized": "3.7.0.0", "source": { "type": "git", "url": "https://github.com/nemiah/phpFinTS.git", - "reference": "b37e6df7efd39b4e757537e782241d5abb6b2bb5" + "reference": "08257e10229db2d4ca8c54ed7fec0f390b332519" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nemiah/phpFinTS/zipball/b37e6df7efd39b4e757537e782241d5abb6b2bb5", - "reference": "b37e6df7efd39b4e757537e782241d5abb6b2bb5", + "url": "https://api.github.com/repos/nemiah/phpFinTS/zipball/08257e10229db2d4ca8c54ed7fec0f390b332519", + "reference": "08257e10229db2d4ca8c54ed7fec0f390b332519", "shasum": "" }, "require": { "ext-curl": "*", "ext-mbstring": "*", - "php": ">=8.3", + "php": ">=8.0", "psr/log": "^1|^2|^3" }, "require-dev": { @@ -31,7 +31,7 @@ "monolog/monolog": "Allow sending log messages to a variety of different handlers", "nemiah/php-sepa-xml": "dev-master" }, - "time": "2026-01-16T07:56:30+00:00", + "time": "2025-10-14T15:05:56+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -48,7 +48,7 @@ "homepage": "https://github.com/nemiah/phpFinTS", "support": { "issues": "https://github.com/nemiah/phpFinTS/issues", - "source": "https://github.com/nemiah/phpFinTS/tree/4.0" + "source": "https://github.com/nemiah/phpFinTS/tree/3.7" }, "install-path": "../nemiah/php-fints" } diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 1055767..31e768d 100755 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -1,9 +1,9 @@ array( 'name' => 'dolibarr/bankimport', - 'pretty_version' => 'dev-main', - 'version' => 'dev-main', - 'reference' => 'fc380892f035d3a48038c3c0cedef76fd0fec404', + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'reference' => null, 'type' => 'dolibarr-module', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -11,18 +11,18 @@ ), 'versions' => array( 'dolibarr/bankimport' => array( - 'pretty_version' => 'dev-main', - 'version' => 'dev-main', - 'reference' => 'fc380892f035d3a48038c3c0cedef76fd0fec404', + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'reference' => null, 'type' => 'dolibarr-module', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => false, ), 'nemiah/php-fints' => array( - 'pretty_version' => '4.0.0', - 'version' => '4.0.0.0', - 'reference' => 'b37e6df7efd39b4e757537e782241d5abb6b2bb5', + 'pretty_version' => '3.7.0', + 'version' => '3.7.0.0', + 'reference' => '08257e10229db2d4ca8c54ed7fec0f390b332519', 'type' => 'library', 'install_path' => __DIR__ . '/../nemiah/php-fints', 'aliases' => array(), diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php index af033b9..a70ba47 100755 --- a/vendor/composer/platform_check.php +++ b/vendor/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 80300)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 8.3.0". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 80000)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.0.0". You are running ' . PHP_VERSION . '.'; } if ($issues) { diff --git a/vendor/nemiah/php-fints/.github/workflows/tests.yml b/vendor/nemiah/php-fints/.github/workflows/tests.yml deleted file mode 100644 index 228d6d5..0000000 --- a/vendor/nemiah/php-fints/.github/workflows/tests.yml +++ /dev/null @@ -1,50 +0,0 @@ -# .github/workflows/tests.yml -name: tests - -on: - push: - branches: - - master - pull_request: - -jobs: - phpunit: - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - php: [ '8.0', '8.1', '8.2', '8.3', '8.4' ] - - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: mbstring - - - name: Install dependencies - run: composer install --no-interaction --prefer-dist --no-progress - - - name: Run PHPUnit - run: ./vendor/bin/phpunit - - php-cs-fixer: - name: PHP-CS-Fixer - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - uses: actions/cache@v4 - with: - path: .php-cs-fixer.cache - key: ${{ runner.OS }}-${{ github.repository }}-phpcsfixer-${{ github.sha }} - restore-keys: | - ${{ runner.OS }}-${{ github.repository }}-phpcsfixer- - - - name: PHP-CS-Fixer - uses: docker://oskarstark/php-cs-fixer-ga - with: - args: -v --diff --dry-run diff --git a/vendor/nemiah/php-fints/.gitignore b/vendor/nemiah/php-fints/.gitignore deleted file mode 100644 index ebd1a7a..0000000 --- a/vendor/nemiah/php-fints/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -.DS_Store -.idea/ -.vscode/ -vendor/ -develop/ -coverage/ -test.php -/nbproject/private/ -/nbproject/ -/composer.lock -/composer.phar -/Samples/tan.txt -/Samples/*.test.php -/Samples/*.log -/Samples/analyzeLogs.php -/Samplesstate.txt -/Samples/state.txt -/Samples/session_* -/doc/ -.phpunit.result.cache -.php_cs.cache -.php-cs-fixer.cache \ No newline at end of file diff --git a/vendor/nemiah/php-fints/.php-cs-fixer.php b/vendor/nemiah/php-fints/.php-cs-fixer.php old mode 100644 new mode 100755 index 9171a9a..9eb8056 --- a/vendor/nemiah/php-fints/.php-cs-fixer.php +++ b/vendor/nemiah/php-fints/.php-cs-fixer.php @@ -12,19 +12,19 @@ return (new PhpCsFixer\Config()) // But then we have some exclusions, i.e. we disable some of the checks/rules from Symfony: // Logic - 'yoda_style' => false, // Allow both Yoda-style and regular comparisons. + 'yoda_style' => FALSE, // Allow both Yoda-style and regular comparisons. // Whitespace - 'blank_line_before_statement' => false, // Don't put blank lines before `return` statements. - 'concat_space' => false, // Allow spaces around string concatenation operator. - 'blank_line_after_opening_tag' => false, // Allow file-level @noinspection suppressions to live on the ` false, // Allow `throw` statements to span multiple lines. + 'blank_line_before_statement' => FALSE, // Don't put blank lines before `return` statements. + 'concat_space' => FALSE, // Allow spaces around string concatenation operator. + 'blank_line_after_opening_tag' => FALSE, // Allow file-level @noinspection suppressions to live on the ` FALSE, // Allow `throw` statements to span multiple lines. // phpDoc - 'phpdoc_align' => false, // Don't add spaces within phpDoc just to make parameter names / descriptions align. - 'phpdoc_annotation_without_dot' => false, // Allow terminating dot on @param and such. - 'phpdoc_no_alias_tag' => false, // Allow @link in addition to @see. - 'phpdoc_separation' => false, // Don't put blank line between @params, @throws and @return. - 'phpdoc_summary' => false, // Don't force terminating dot on the first line. + 'phpdoc_align' => FALSE, // Don't add spaces within phpDoc just to make parameter names / descriptions align. + 'phpdoc_annotation_without_dot' => FALSE, // Allow terminating dot on @param and such. + 'phpdoc_no_alias_tag' => FALSE, // Allow @link in addition to @see. + 'phpdoc_separation' => FALSE, // Don't put blank line between @params, @throws and @return. + 'phpdoc_summary' => FALSE, // Don't force terminating dot on the first line. ]) ->setFinder($finder); diff --git a/vendor/nemiah/php-fints/.travis.yml b/vendor/nemiah/php-fints/.travis.yml new file mode 100755 index 0000000..1db343e --- /dev/null +++ b/vendor/nemiah/php-fints/.travis.yml @@ -0,0 +1,12 @@ +language: php +install: composer install +script: + - ./disallowtabs.sh + - ./csfixer-check.sh + - ./phplint.sh ./lib/ + - ./vendor/bin/phpunit +dist: bionic +php: + - '8.0' + - '8.1.0' + - '8.2.0' diff --git a/vendor/nemiah/php-fints/DEVELOPER-GUIDE.md b/vendor/nemiah/php-fints/DEVELOPER-GUIDE.md old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/LICENSE b/vendor/nemiah/php-fints/LICENSE old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/README.md b/vendor/nemiah/php-fints/README.md old mode 100644 new mode 100755 index 84c3e1d..c14ea9d --- a/vendor/nemiah/php-fints/README.md +++ b/vendor/nemiah/php-fints/README.md @@ -1,6 +1,6 @@ # PHP FinTS/HBCI library -[![CI status](https://github.com/nemiah/phpFinTS/actions/workflows/tests.yml/badge.svg)](https://github.com/nemiah/phpFinTS/actions/workflows/tests.yml) +[![Build Status](https://travis-ci.org/nemiah/phpFinTS.svg?branch=master)](https://travis-ci.org/nemiah/phpFinTS) A PHP library implementing the following functions of the FinTS/HBCI protocol: diff --git a/vendor/nemiah/php-fints/Samples/accounts.php b/vendor/nemiah/php-fints/Samples/accounts.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/Samples/balance.php b/vendor/nemiah/php-fints/Samples/balance.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/Samples/bpd.php b/vendor/nemiah/php-fints/Samples/bpd.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/Samples/browser.php b/vendor/nemiah/php-fints/Samples/browser.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/Samples/directDebit_Sephpa.php b/vendor/nemiah/php-fints/Samples/directDebit_Sephpa.php old mode 100644 new mode 100755 index 171d0fc..a3c076d --- a/vendor/nemiah/php-fints/Samples/directDebit_Sephpa.php +++ b/vendor/nemiah/php-fints/Samples/directDebit_Sephpa.php @@ -46,9 +46,6 @@ $xml = $directDebitFile->generateOutput(['zipToOneFile' => false])[0]['data']; $sendSEPADirectDebit = \Fhp\Action\SendSEPADirectDebit::create($oneAccount, $xml); $fints->execute($sendSEPADirectDebit); - -require_once 'vop.php'; -handleVopAndAuthentication($sendSEPADirectDebit); - -// Debit requests don't produce any result we could receive through a getter, but we still need to make sure it's done. -$sendSEPADirectDebit->ensureDone(); +if ($sendSEPADirectDebit->needsTan()) { + handleStrongAuthentication($sendSEPADirectDebit); // See login.php for the implementation. +} diff --git a/vendor/nemiah/php-fints/Samples/directDebit_phpSepaXml.php b/vendor/nemiah/php-fints/Samples/directDebit_phpSepaXml.php old mode 100644 new mode 100755 index aaa41bc..2748592 --- a/vendor/nemiah/php-fints/Samples/directDebit_phpSepaXml.php +++ b/vendor/nemiah/php-fints/Samples/directDebit_phpSepaXml.php @@ -62,9 +62,6 @@ $oneAccount = $getSepaAccounts->getAccounts()[0]; $sendSEPADirectDebit = \Fhp\Action\SendSEPADirectDebit::create($oneAccount, $sepaDD->toXML('pain.008.001.02')); $fints->execute($sendSEPADirectDebit); - -require_once 'vop.php'; -handleVopAndAuthentication($sendSEPADirectDebit); - -// Debit requests don't produce any result we could receive through a getter, but we still need to make sure it's done. -$sendSEPADirectDebit->ensureDone(); +if ($sendSEPADirectDebit->needsTan()) { + handleStrongAuthentication($sendSEPADirectDebit); // See login.php for the implementation. +} diff --git a/vendor/nemiah/php-fints/Samples/init.php b/vendor/nemiah/php-fints/Samples/init.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/Samples/login.php b/vendor/nemiah/php-fints/Samples/login.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/Samples/statementOfAccount.php b/vendor/nemiah/php-fints/Samples/statementOfAccount.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/Samples/statementOfHoldings.php b/vendor/nemiah/php-fints/Samples/statementOfHoldings.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/Samples/tanModesAndMedia.php b/vendor/nemiah/php-fints/Samples/tanModesAndMedia.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/Samples/transfer.php b/vendor/nemiah/php-fints/Samples/transfer.php old mode 100644 new mode 100755 index 6aae181..083d8e6 --- a/vendor/nemiah/php-fints/Samples/transfer.php +++ b/vendor/nemiah/php-fints/Samples/transfer.php @@ -21,15 +21,6 @@ use nemiah\phpSepaXml\SEPATransfer; /** @var \Fhp\FinTs $fints */ $fints = require_once 'login.php'; -// Just pick the first account, for demonstration purposes. You could also have the user choose, or have SEPAAccount -// hard-coded and not call getSEPAAccounts() at all. -$getSepaAccounts = \Fhp\Action\GetSEPAAccounts::create(); -$fints->execute($getSepaAccounts); -if ($getSepaAccounts->needsTan()) { - handleStrongAuthentication($getSepaAccounts); // See login.php for the implementation. -} -$oneAccount = $getSepaAccounts->getAccounts()[0]; - $dt = new \DateTime(); $dt->add(new \DateInterval('P1D')); @@ -58,9 +49,6 @@ $sepaDD->addCreditor(new SEPACreditor([ //this is who you want to send money to $sendSEPATransfer = \Fhp\Action\SendSEPATransfer::create($oneAccount, $sepaDD->toXML()); $fints->execute($sendSEPATransfer); - -require_once 'vop.php'; -handleVopAndAuthentication($sendSEPATransfer); - -// SEPA transfers don't produce any result we could receive through a getter, but we still need to make sure it's done. -$sendSEPATransfer->ensureDone(); +if ($sendSEPATransfer->needsTan()) { + handleStrongAuthentication($sendSEPATransfer); // See login.php for the implementation. +} diff --git a/vendor/nemiah/php-fints/Samples/vop.php b/vendor/nemiah/php-fints/Samples/vop.php deleted file mode 100644 index 2864e5c..0000000 --- a/vendor/nemiah/php-fints/Samples/vop.php +++ /dev/null @@ -1,138 +0,0 @@ -isDone()) { - if ($action->needsTan()) { - handleStrongAuthentication($action); // See login.php for the implementation. - } elseif ($action->needsPollingWait()) { - handlePollingWait($action); - } elseif ($action->needsVopConfirmation()) { - handleVopConfirmation($action); - } else { - throw new \AssertionError( - 'Action is not done but also does not need anything to be done. Did you execute() it?' - ); - } - } -} - -/** - * Waits for the amount of time that the bank prescribed and then polls the server for a status update. - * @param \Fhp\BaseAction $action An action for which {@link \Fhp\BaseAction::needsPollingWait()} returns true. - * @throws CurlException|UnexpectedResponseException|ServerException See {@link FinTs::execute()} for details. - */ -function handlePollingWait(\Fhp\BaseAction $action): void -{ - global $fints, $options, $credentials; // From login.php - - // Tell the user what the bank had to say (if anything). - $pollingInfo = $action->getPollingInfo(); - if ($infoText = $pollingInfo->getInformationForUser()) { - echo $infoText . PHP_EOL; - } - - // Optional: If the wait is too long for your PHP process to remain alive (i.e. your server would kill the process), - // you can persist the state as shown here and instead send a response to the client-side application indicating - // that the operation is still ongoing. Then after an appropriate amount of time, the client can send another - // request, spawning a new PHP process, where you can restore the state as shown below. - if ($optionallyPersistEverything = false) { - $persistedAction = serialize($action); - $persistedFints = $fints->persist(); - - // These are two strings (watch out, they are NOT necessarily UTF-8 encoded), which you can store anywhere. - // This example code stores them in a text file, but you might write them to your database (use a BLOB, not a - // CHAR/TEXT field to allow for arbitrary encoding) or in some other storage (possibly base64-encoded to make it - // ASCII). - file_put_contents(__DIR__ . '/state.txt', serialize([$persistedFints, $persistedAction])); - } - - // Wait for (at least) the prescribed amount of time. -------------------------------------------------------------- - // Note: In your real application, you may be doing this waiting on the client and then send a fresh request to your - // server. - $waitSecs = $pollingInfo->getNextAttemptInSeconds() ?: 5; - echo "Waiting for $waitSecs seconds before polling the bank server again..." . PHP_EOL; - sleep($waitSecs); - - // Optional: If the state was persisted above, we can restore it now (imagine this is a new PHP process). - if ($optionallyPersistEverything) { - $restoredState = file_get_contents(__DIR__ . '/state.txt'); - list($persistedInstance, $persistedAction) = unserialize($restoredState); - $fints = \Fhp\FinTs::new($options, $credentials, $persistedInstance); - $action = unserialize($persistedAction); - } - - $fints->pollAction($action); - // Now the action is in a new state, which the caller of this function (handleVopAndAuthentication) will deal with. -} - -/** - * Asks the user to confirm - * @param \Fhp\BaseAction $action An action for which {@link \Fhp\BaseAction::needsVopConfirmation()} returns true. - * @throws CurlException|UnexpectedResponseException|ServerException See {@link FinTs::execute()} for details. - */ -function handleVopConfirmation(\Fhp\BaseAction $action): void -{ - global $fints, $options, $credentials; // From login.php - - $vopConfirmationRequest = $action->getVopConfirmationRequest(); - if ($infoText = $vopConfirmationRequest->getInformationForUser()) { - echo $infoText . PHP_EOL; - } - echo match ($vopConfirmationRequest->getVerificationResult()) { - \Fhp\Model\VopVerificationResult::CompletedFullMatch => - 'The bank says the payee information matched perfectly, but still wants you to confirm.', - \Fhp\Model\VopVerificationResult::CompletedCloseMatch => - 'The bank says the payee information does not match exactly, so please confirm.', - \Fhp\Model\VopVerificationResult::CompletedPartialMatch => - 'The bank says the payee information does not match for all transfers, so please confirm.', - \Fhp\Model\VopVerificationResult::CompletedNoMatch => - 'The bank says the payee information does not match, but you can still confirm the transfer if you want.', - \Fhp\Model\VopVerificationResult::NotApplicable => - $vopConfirmationRequest->getVerificationNotApplicableReason() == null - ? 'The bank did not provide any information about payee verification, but you can still confirm.' - : 'The bank says: ' . $vopConfirmationRequest->getVerificationNotApplicableReason(), - default => 'The bank failed to provide information about payee verification, but you can still confirm.', - } . PHP_EOL; - - // Just like in handleTan(), handleDecoupledSubmission() or handlePollingWait(), we have the option to interrupt the - // PHP process at this point, so that we can ask the user in a client application for their confirmation. - if ($optionallyPersistEverything = false) { - $persistedAction = serialize($action); - $persistedFints = $fints->persist(); - // See handlePollingWait() for how to deal with this in practice. - file_put_contents(__DIR__ . '/state.txt', serialize([$persistedFints, $persistedAction])); - } - - echo "In light of the information provided above, do you want to confirm the execution of the transfer?" . PHP_EOL; - // Note: We currently have no way canceling the transfer; the only thing we can do is never to confirm it. - echo "If so, please type 'confirm' and hit Return. Otherwise, please kill this PHP process." . PHP_EOL; - while (trim(fgets(STDIN)) !== 'confirm') { - echo "Try again." . PHP_EOL; - } - echo "Confirming the transfer." . PHP_EOL; - $fints->confirmVop($action); - echo "Confirmed" . PHP_EOL; - // Now the action is in a new state, which the caller of this function (handleVopAndAuthentication) will deal with. -} diff --git a/vendor/nemiah/php-fints/composer.json b/vendor/nemiah/php-fints/composer.json old mode 100644 new mode 100755 index a1863bd..0da3b32 --- a/vendor/nemiah/php-fints/composer.json +++ b/vendor/nemiah/php-fints/composer.json @@ -2,7 +2,7 @@ "name": "nemiah/php-fints", "description": "PHP Library for the protocols fints and hbci", "homepage": "https://github.com/nemiah/phpFinTS", - "version": "4.0.0", + "version": "3.7.0", "license": "MIT", "autoload": { "psr-0": { @@ -11,7 +11,7 @@ } }, "require": { - "php": ">=8.3", + "php": ">=8.0", "psr/log": "^1|^2|^3", "ext-curl": "*", "ext-mbstring": "*" diff --git a/vendor/nemiah/php-fints/csfixer-check.sh b/vendor/nemiah/php-fints/csfixer-check.sh new file mode 100755 index 0000000..9c76ae3 --- /dev/null +++ b/vendor/nemiah/php-fints/csfixer-check.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# +# When this is run as part of a Travis test for a pull request, then it ensures that none of the touched files has any +# PHP CS Fixer warnings. +# From: https://github.com/FriendsOfPHP/PHP-CS-Fixer#using-php-cs-fixer-on-ci + +if [ -z "$TRAVIS_COMMIT_RANGE" ] +then +# TRAVIS_COMMIT_RANGE "is empty for builds triggered by the initial commit of a new branch" +# From: https://docs.travis-ci.com/user/environment-variables/ + echo "Variable TRAVIS_COMMIT_RANGE not set, falling back to full git diff" + TRAVIS_COMMIT_RANGE=. +fi + +IFS=' +' +CHANGED_FILES=$(git diff --name-only --diff-filter=ACMRTUXB "$TRAVIS_COMMIT_RANGE") +if [ "$?" -ne "0" ] +then + echo "Error: git diff response code > 0, aborting" + exit 1 +fi + +if [ -z "${CHANGED_FILES}" ] +then + echo "0 changed files found, exiting" + exit 0 +fi + +# February 2022: PHP CS FIXER is currently not PHP 8.1 compatible: +# "you may experience code modified in a wrong way" +# "To ignore this requirement please set `PHP_CS_FIXER_IGNORE_ENV`." +export PHP_CS_FIXER_IGNORE_ENV="1" + +if ! echo "${CHANGED_FILES}" | grep -qE "^(\\.php_cs(\\.dist)?|composer\\.lock)$"; then EXTRA_ARGS=$(printf -- '--path-mode=intersection\n--\n%s' "${CHANGED_FILES}"); else EXTRA_ARGS=''; fi +vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php -v --dry-run --stop-on-violation --using-cache=no ${EXTRA_ARGS} || (echo "php-cs-fixer failed" && exit 1) \ No newline at end of file diff --git a/vendor/nemiah/php-fints/disallowtabs.sh b/vendor/nemiah/php-fints/disallowtabs.sh new file mode 100755 index 0000000..3d91702 --- /dev/null +++ b/vendor/nemiah/php-fints/disallowtabs.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# +# When this is run as part of a Travis test for a pull request, then it ensures that none of the added lines (compared +# to the base branch of the pull request) use tabs for indentations. +# Adapted from https://github.com/mrc/git-hook-library/blob/master/pre-commit.no-tabs + +# Abort if any of the inner commands (particularly the git commands) fails. +set -e +set -o pipefail + +if [ -z ${TRAVIS_PULL_REQUEST} ]; then + echo "Expected environment variable TRAVIS_PULL_REQUEST" + exit 2 +elif [ "${TRAVIS_PULL_REQUEST}" == "false" ]; then + echo "Not a Travis pull request, skipping." + exit 0 +fi + +# Make sure that we have a local copy of the relevant commits (otherwise git diff won't work). +git remote set-branches --add origin ${TRAVIS_BRNACH} +git fetch + +# Compute the diff from the PR's target branch to its HEAD commit. +target_branch="origin/${TRAVIS_BRANCH}" +the_diff=$(git diff "${target_branch}...HEAD") + +# Make sure that there are no tabs in the indentation part of added lines. +if echo "${the_diff}" | egrep '^\+\s* ' >/dev/null; then + echo -e "\e[31mError: The changes contain a tab for indentation\e[0m, which is against this repo's policy." + echo "Target branch: origin/${TRAVIS_BRANCH}" + echo "Commit range: ${TRAVIS_COMMIT_RANGE}" + echo "The following tabs were detected:" + echo "${the_diff}" | egrep '^(\+\s* |\+\+\+|@@)' + exit 1 +else + echo "No new tabs detected." +fi diff --git a/vendor/nemiah/php-fints/lib/Fhp/Action/GetBalance.php b/vendor/nemiah/php-fints/lib/Fhp/Action/GetBalance.php old mode 100644 new mode 100755 index 00d8f81..00c053f --- a/vendor/nemiah/php-fints/lib/Fhp/Action/GetBalance.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Action/GetBalance.php @@ -24,7 +24,7 @@ use Fhp\UnsupportedException; */ class GetBalance extends PaginateableAction { - // Request (if you add a field here, update __serialize() and __unserialize() as well). + // Request (not available after serialization, i.e. not available in processResponse()). /** @var SEPAAccount */ private $account; /** @var bool */ @@ -79,7 +79,7 @@ class GetBalance extends PaginateableAction { list( $parentSerialized, - $this->account, $this->allAccounts, + $this->account, $this->allAccounts ) = $serialized; is_array($parentSerialized) ? @@ -96,6 +96,7 @@ class GetBalance extends PaginateableAction return $this->response; } + /** {@inheritdoc} */ protected function createRequest(BPD $bpd, ?UPD $upd) { /** @var BaseSegment $hisals */ @@ -114,6 +115,7 @@ class GetBalance extends PaginateableAction } } + /** {@inheritdoc} */ public function processResponse(Message $response) { parent::processResponse($response); diff --git a/vendor/nemiah/php-fints/lib/Fhp/Action/GetBankStatement.php b/vendor/nemiah/php-fints/lib/Fhp/Action/GetBankStatement.php new file mode 100755 index 0000000..2da3f83 --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Action/GetBankStatement.php @@ -0,0 +1,211 @@ +account = $account; + $result->statementNumber = $statementNumber; + $result->year = $year; + return $result; + } + + /** + * @deprecated + */ + public function serialize(): string + { + return serialize($this->__serialize()); + } + + public function __serialize(): array + { + return [ + parent::__serialize(), + $this->account, + $this->statementNumber, + $this->year, + ]; + } + + /** + * @deprecated + */ + public function unserialize($serialized) + { + self::__unserialize(unserialize($serialized)); + } + + public function __unserialize(array $serialized): void + { + list( + $parentSerialized, + $this->account, + $this->statementNumber, + $this->year + ) = $serialized; + + is_array($parentSerialized) ? + parent::__unserialize($parentSerialized) : + parent::unserialize($parentSerialized); + } + + /** + * @return string[] Array von PDF-Binaerdaten (ein Eintrag pro Kontoauszug). + */ + public function getPdfStatements(): array + { + $this->ensureDone(); + return $this->pdfStatements; + } + + /** {@inheritdoc} */ + protected function createRequest(BPD $bpd, ?UPD $upd) + { + error_log("[BankImport HKEKP] createRequest() aufgerufen"); + + /** @var HIEPS $hieps */ + $hieps = $bpd->requireLatestSupportedParameters('HIEPS'); + $version = $hieps->getVersion(); + error_log("[BankImport HKEKP] HIEPS Version=".$version); + error_log("[BankImport HKEKP] Account IBAN=".$this->account->getIban().", BIC=".$this->account->getBic()); + error_log("[BankImport HKEKP] Auszugsnummer=".($this->statementNumber ?: 'null').", Jahr=".($this->year ?: 'null')); + + switch ($version) { + case 1: + error_log("[BankImport HKEKP] Erstelle HKEKPv1 (KtvV3-basiert, BLZ)"); + return HKEKPv1::create( + KtvV3::fromAccount($this->account), + $this->statementNumber, + $this->year + ); + case 2: + error_log("[BankImport HKEKP] Erstelle HKEKPv2 (Kti-basiert, IBAN/BIC)"); + return HKEKPv2::create( + Kti::fromAccount($this->account), + $this->statementNumber, + $this->year + ); + default: + error_log("[BankImport HKEKP] FEHLER: Nicht unterstuetzte Version ".$version); + throw new UnsupportedException('Nicht unterstuetzte HKEKP-Version: ' . $version); + } + } + + /** {@inheritdoc} */ + public function processResponse(Message $response) + { + error_log("[BankImport HKEKP] processResponse() aufgerufen"); + + parent::processResponse($response); + + // Bank sendet 3010 wenn keine Auszuege verfuegbar + $isUnavailable = $response->findRueckmeldung(Rueckmeldungscode::NICHT_VERFUEGBAR) !== null; + $responseSegments = $response->findSegments(HIKEP::class); + + error_log("[BankImport HKEKP] isUnavailable=".($isUnavailable ? 'JA' : 'NEIN') + .", HIKEP-Segmente=".count($responseSegments) + .", Request-Segment-Nummern=".implode(',', $this->getRequestSegmentNumbers())); + + // Alle Rueckmeldungen loggen + try { + $rueckmeldungen = $response->findSegments(\Fhp\Segment\HIRMS\HIRMSv2::class); + foreach ($rueckmeldungen as $hirms) { + foreach ($hirms->rueckmeldung as $rm) { + error_log("[BankImport HKEKP] Rueckmeldung: Code=".$rm->rueckmeldungscode + ." Ref=".$rm->bezugsdatenelement + ." Text=".$rm->rueckmeldungstext); + } + } + } catch (\Throwable $e) { + error_log("[BankImport HKEKP] Rueckmeldungen konnten nicht gelesen werden: ".$e->getMessage()); + } + + if (!$isUnavailable && count($responseSegments) === 0 && count($this->getRequestSegmentNumbers()) > 0) { + error_log("[BankImport HKEKP] FEHLER: Keine HIKEP-Segmente in Antwort!"); + throw new UnexpectedResponseException('Keine HIKEP-Antwort-Segmente erhalten!'); + } + + /** @var HIKEP $hikep */ + foreach ($responseSegments as $segIdx => $hikep) { + error_log("[BankImport HKEKP] Verarbeite HIKEP-Segment ".($segIdx+1)."/".count($responseSegments)); + + $pdfData = $hikep->getKontoauszug()->getData(); + $rawLen = strlen($pdfData); + $rawStart = substr($pdfData, 0, 20); + error_log("[BankImport HKEKP] Rohdaten: ".$rawLen." Bytes, Anfang='".$rawStart."', Hex=".bin2hex(substr($pdfData, 0, 10))); + + // Pruefen ob Base64-kodiert (beginnt nicht mit %PDF-) + if (!str_starts_with($pdfData, '%PDF-')) { + error_log("[BankImport HKEKP] Daten beginnen NICHT mit %PDF-, pruefe Base64..."); + $decoded = base64_decode($pdfData, true); + if ($decoded !== false && str_starts_with($decoded, '%PDF-')) { + error_log("[BankImport HKEKP] Base64-Dekodierung erfolgreich! ".strlen($decoded)." Bytes nach Dekodierung"); + $pdfData = $decoded; + } else { + error_log("[BankImport HKEKP] WARNUNG: Weder PDF noch Base64-PDF erkannt! decoded=".($decoded !== false ? 'ja' : 'nein')); + } + } else { + error_log("[BankImport HKEKP] Daten sind direkt PDF (kein Base64)"); + } + + // Quittung pruefen + $quittung = $hikep->getQuittung(); + if ($quittung !== null) { + error_log("[BankImport HKEKP] Quittung vorhanden: ".strlen($quittung->getData())." Bytes"); + } + + if (!empty($pdfData)) { + $this->pdfStatements[] = $pdfData; + error_log("[BankImport HKEKP] PDF hinzugefuegt (gesamt: ".count($this->pdfStatements).")"); + } else { + error_log("[BankImport HKEKP] WARNUNG: Leere PDF-Daten, uebersprungen"); + } + } + + error_log("[BankImport HKEKP] processResponse() fertig, ".count($this->pdfStatements)." PDFs gesammelt"); + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Action/GetDepotAufstellung.php b/vendor/nemiah/php-fints/lib/Fhp/Action/GetDepotAufstellung.php old mode 100644 new mode 100755 index 17e644e..3f32987 --- a/vendor/nemiah/php-fints/lib/Fhp/Action/GetDepotAufstellung.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Action/GetDepotAufstellung.php @@ -24,7 +24,7 @@ use Fhp\UnsupportedException; */ class GetDepotAufstellung extends PaginateableAction { - // Request (if you add a field here, update __serialize() and __unserialize() as well). + // Request (not available after serialization, i.e. not available in processResponse()). /** @var SEPAAccount */ private $account; @@ -81,7 +81,7 @@ class GetDepotAufstellung extends PaginateableAction { list( $parentSerialized, - $this->account, + $this->account ) = $serialized; is_array($parentSerialized) ? @@ -111,6 +111,7 @@ class GetDepotAufstellung extends PaginateableAction return $this->depotWert; } + /** {@inheritdoc} */ protected function createRequest(BPD $bpd, ?UPD $upd) { /** @var HIWPDS $hiwpds */ @@ -124,6 +125,7 @@ class GetDepotAufstellung extends PaginateableAction } } + /** {@inheritdoc} */ public function processResponse(Message $response) { parent::processResponse($response); diff --git a/vendor/nemiah/php-fints/lib/Fhp/Action/GetElectronicStatement.php b/vendor/nemiah/php-fints/lib/Fhp/Action/GetElectronicStatement.php old mode 100644 new mode 100755 index bdc6b44..7ac9013 --- a/vendor/nemiah/php-fints/lib/Fhp/Action/GetElectronicStatement.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Action/GetElectronicStatement.php @@ -6,173 +6,354 @@ use Fhp\Model\SEPAAccount; use Fhp\PaginateableAction; use Fhp\Protocol\BPD; use Fhp\Protocol\Message; +use Fhp\Protocol\UnexpectedResponseException; use Fhp\Protocol\UPD; +use Fhp\Segment\AnonymousSegment; use Fhp\Segment\Common\Kti; +use Fhp\Segment\Common\KtvV3; use Fhp\Segment\EKA\HIEKA; -use Fhp\Segment\EKA\HIEKASv5; +use Fhp\Segment\EKA\HIEKAS; +use Fhp\Segment\EKA\HKEKAv3; +use Fhp\Segment\EKA\HKEKAv4; use Fhp\Segment\EKA\HKEKAv5; use Fhp\Segment\HIRMS\Rueckmeldungscode; use Fhp\UnsupportedException; /** - * Retrieves electronic bank statements (Elektronischer Kontoauszug) via HKEKA. + * Ruft elektronische Kontoauszuege von der Bank ab (HKEKA). * - * This supports both MT940 and PDF formats depending on what the bank offers. + * Im Gegensatz zu GetBankStatement (HKEKP, nur PDF) unterstuetzt HKEKA + * verschiedene Formate: 1=MT940, 2=ISO8583, 3=PDF. + * Das gewuenschte Format wird im Request mitgesendet. */ class GetElectronicStatement extends PaginateableAction { - // Format codes - public const FORMAT_MT940 = 1; - public const FORMAT_PDF = 2; + // Kontoauszugsformate + const FORMAT_MT940 = '1'; + const FORMAT_ISO8583 = '2'; + const FORMAT_PDF = '3'; + // Request-Parameter /** @var SEPAAccount */ private $account; - - /** @var int|null Format to request (1=MT940, 2=PDF, null=default) */ + /** @var string|null Gewuenschtes Format (1=MT940, 2=ISO8583, 3=PDF) */ private $format; + /** @var string|null Auszugsnummer */ + private $statementNumber; + /** @var string|null Jahr (JJJJ) */ + private $year; - /** @var string|null Optional: from date YYYYMMDD */ - private $fromDate; - - /** @var string|null Optional: to date YYYYMMDD */ - private $toDate; - - // Response data - /** @var string Raw data (MT940 or PDF binary) */ - private $data = ''; - - /** @var array Statement metadata from response */ - private $statementInfo = []; + // Response: Gesammelte Daten + /** @var array Array von ['data' => string, 'format' => string|null] */ + private $statements = []; /** - * @param SEPAAccount $account The account to get statements for - * @param int|null $format Format code (1=MT940, 2=PDF, null=bank default) - * @param \DateTime|null $fromDate Optional: Start date for statement range - * @param \DateTime|null $toDate Optional: End date for statement range + * @param SEPAAccount $account Das Konto fuer das Auszuege abgerufen werden sollen. + * @param string|null $format Gewuenschtes Format (FORMAT_MT940/FORMAT_ISO8583/FORMAT_PDF), null=Bank-Standard. + * @param string|null $statementNumber Optionale Auszugsnummer. + * @param string|null $year Optionales Jahr (JJJJ). * @return GetElectronicStatement */ public static function create( SEPAAccount $account, - ?int $format = null, - ?\DateTime $fromDate = null, - ?\DateTime $toDate = null + ?string $format = null, + ?string $statementNumber = null, + ?string $year = null ): GetElectronicStatement { $result = new GetElectronicStatement(); $result->account = $account; $result->format = $format; - $result->fromDate = $fromDate ? $fromDate->format('Ymd') : null; - $result->toDate = $toDate ? $toDate->format('Ymd') : null; + $result->statementNumber = $statementNumber; + $result->year = $year; return $result; } + /** + * @deprecated + */ + public function serialize(): string + { + return serialize($this->__serialize()); + } + public function __serialize(): array { return [ parent::__serialize(), $this->account, $this->format, - $this->fromDate, - $this->toDate, + $this->statementNumber, + $this->year, ]; } + /** + * @deprecated + */ + public function unserialize($serialized) + { + self::__unserialize(unserialize($serialized)); + } + public function __unserialize(array $serialized): void { list( $parentSerialized, $this->account, $this->format, - $this->fromDate, - $this->toDate + $this->statementNumber, + $this->year ) = $serialized; - is_array($parentSerialized) - ? parent::__unserialize($parentSerialized) - : parent::unserialize($parentSerialized); + is_array($parentSerialized) ? + parent::__unserialize($parentSerialized) : + parent::unserialize($parentSerialized); } /** - * @return string The raw data (MT940 text or PDF binary) + * @return array Array von ['data' => string, 'format' => string|null] pro Kontoauszug. */ - public function getData(): string + public function getStatements(): array { $this->ensureDone(); - return $this->data; + return $this->statements; } /** - * @return array Statement metadata (number, year, iban, date, format) + * Hilfsfunktion: Gibt nur die PDF-Daten zurueck (filtert nach Format=3 oder erkennt %PDF-). + * @return string[] Array von PDF-Binaerdaten. */ - public function getStatementInfo(): array + public function getPdfStatements(): array { $this->ensureDone(); - return $this->statementInfo; + $pdfs = []; + foreach ($this->statements as $stmt) { + $data = $stmt['data']; + $format = $stmt['format'] ?? null; + + // PDF wenn Format=3 oder Daten mit %PDF- beginnen + if ($format === self::FORMAT_PDF || str_starts_with($data, '%PDF-')) { + $pdfs[] = $data; + } + } + return $pdfs; } /** - * @return bool Whether receipt confirmation is needed + * Ermittelt die hoechste unterstuetzte HIEKAS-Version aus den BPD. + * Funktioniert auch mit AnonymousSegments (wenn unsere typisierten Klassen + * nicht zur Bank-Antwort passen). */ - public function needsReceipt(): bool + private function resolveHiekasVersion(BPD $bpd): int { - $this->ensureDone(); - return !empty($this->statementInfo['receiptCode']); + // Erst typisierte Segmente versuchen + $hiekas = $bpd->getLatestSupportedParameters('HIEKAS'); + if ($hiekas !== null) { + return $hiekas->getVersion(); + } + + // Fallback: Version aus anonymen BPD-Segmenten lesen + if (isset($bpd->parameters['HIEKAS'])) { + $versions = array_keys($bpd->parameters['HIEKAS']); + // Bereits absteigend sortiert (krsort in BPD::extractFromResponse) + $version = reset($versions); + error_log("[BankImport HKEKA] HIEKAS nur als AnonymousSegment verfuegbar, Version=" . $version); + return (int) $version; + } + + throw new UnsupportedException('HIEKAS nicht in BPD gefunden'); } /** {@inheritdoc} */ protected function createRequest(BPD $bpd, ?UPD $upd) { - /** @var HIEKASv5|null $hiekas */ - $hiekas = $bpd->getLatestSupportedParameters('HIEKAS'); + error_log("[BankImport HKEKA] createRequest() aufgerufen"); - if ($hiekas === null) { - throw new UnsupportedException('The bank does not support electronic statements (HKEKA).'); + $version = $this->resolveHiekasVersion($bpd); + error_log("[BankImport HKEKA] HIEKAS Version=" . $version); + error_log("[BankImport HKEKA] Account IBAN=" . $this->account->getIban() . ", BIC=" . $this->account->getBic()); + error_log("[BankImport HKEKA] Format=" . ($this->format ?: 'null (Bank-Standard)') + . ", Auszugsnummer=" . ($this->statementNumber ?: 'null') + . ", Jahr=" . ($this->year ?: 'null')); + + switch ($version) { + case 3: + error_log("[BankImport HKEKA] Erstelle HKEKAv3 (KtvV3-basiert, BLZ)"); + return HKEKAv3::create( + KtvV3::fromAccount($this->account), + $this->format, + $this->statementNumber, + $this->year + ); + case 4: + error_log("[BankImport HKEKA] Erstelle HKEKAv4 (Kti-basiert, IBAN/BIC)"); + return HKEKAv4::create( + Kti::fromAccount($this->account), + $this->format, + $this->statementNumber, + $this->year + ); + case 5: + error_log("[BankImport HKEKA] Erstelle HKEKAv5 (Kti-basiert, IBAN/BIC)"); + return HKEKAv5::create( + Kti::fromAccount($this->account), + $this->format, + $this->statementNumber, + $this->year + ); + default: + error_log("[BankImport HKEKA] FEHLER: Nicht unterstuetzte Version " . $version); + throw new UnsupportedException('Nicht unterstuetzte HKEKA-Version: ' . $version); } + } - $param = $hiekas->getParameter(); + /** + * Loggt Diagnose-Informationen ueber anonyme HIEKA-Segmente in der Antwort. + * Wird aufgerufen wenn findSegments(HIEKA::class) leer ist, um die tatsaechliche + * Segment-Struktur der Bank zu analysieren. + */ + private function logAnonymousHiekaSegments(Message $response): void + { + foreach ($response->plainSegments as $seg) { + $name = $seg->getName(); + if ($name !== 'HIEKA') { + continue; + } + $version = $seg->getVersion(); + $class = get_class($seg); + error_log("[BankImport HKEKA] DIAGNOSE: Segment {$name}v{$version} class={$class}"); - // Check if requested format is supported - if ($this->format === self::FORMAT_PDF && !$param->supportsPdf()) { - throw new UnsupportedException('The bank does not support PDF format for electronic statements.'); + if ($seg instanceof AnonymousSegment) { + // Reflection um private 'elements' zu lesen + try { + $ref = new \ReflectionClass($seg); + $elProp = $ref->getProperty('elements'); + $elProp->setAccessible(true); + $elements = $elProp->getValue($seg); + error_log("[BankImport HKEKA] DIAGNOSE: " . count($elements) . " Elemente im Segment"); + foreach ($elements as $idx => $el) { + if ($el === null) { + error_log("[BankImport HKEKA] [{$idx}] NULL (leer)"); + } elseif (is_array($el)) { + // DEG (Data Element Group) + $parts = array_map(function ($v) { + if ($v === null) return 'NULL'; + $s = (string) $v; + return strlen($s) > 40 ? substr($s, 0, 40) . '...(' . strlen($s) . 'B)' : $s; + }, $el); + error_log("[BankImport HKEKA] [{$idx}] DEG: " . implode(' : ', $parts)); + } else { + $val = (string) $el; + if (strlen($val) > 80) { + // Binaerdaten oder lange Strings kuerzen + $hex = bin2hex(substr($val, 0, 16)); + error_log("[BankImport HKEKA] [{$idx}] BIN/LANG: " . strlen($val) + . " Bytes, Hex-Start=" . $hex + . ", Text-Start=" . substr($val, 0, 30)); + } else { + error_log("[BankImport HKEKA] [{$idx}] " . $val); + } + } + } + } catch (\Throwable $e) { + error_log("[BankImport HKEKA] DIAGNOSE: Reflection fehlgeschlagen: " . $e->getMessage()); + } + } } - - // Use Kti (IBAN/BIC) for version 5 - $kti = Kti::fromAccount($this->account); - return HKEKAv5::create($kti, $this->format, $this->fromDate, $this->toDate); } /** {@inheritdoc} */ public function processResponse(Message $response) { + error_log("[BankImport HKEKA] processResponse() aufgerufen"); + parent::processResponse($response); - // Check if no statements available - if ($response->findRueckmeldung(Rueckmeldungscode::NICHT_VERFUEGBAR) !== null) { - return; - } - - /** @var HIEKA[] $responseSegments */ + // Bank sendet 3010 wenn keine Auszuege verfuegbar + $isUnavailable = $response->findRueckmeldung(Rueckmeldungscode::NICHT_VERFUEGBAR) !== null; $responseSegments = $response->findSegments(HIEKA::class); - if (empty($responseSegments)) { - // No segments but also no error = empty response - return; + error_log("[BankImport HKEKA] isUnavailable=" . ($isUnavailable ? 'JA' : 'NEIN') + . ", HIEKA-Segmente=" . count($responseSegments) + . ", Request-Segment-Nummern=" . implode(',', $this->getRequestSegmentNumbers())); + + // Alle Rueckmeldungen loggen + try { + $rueckmeldungen = $response->findSegments(\Fhp\Segment\HIRMS\HIRMSv2::class); + foreach ($rueckmeldungen as $hirms) { + foreach ($hirms->rueckmeldung as $rm) { + error_log("[BankImport HKEKA] Rueckmeldung: Code=" . $rm->rueckmeldungscode + . " Ref=" . $rm->bezugsdatenelement + . " Text=" . $rm->rueckmeldungstext); + } + } + } catch (\Throwable $e) { + error_log("[BankImport HKEKA] Rueckmeldungen konnten nicht gelesen werden: " . $e->getMessage()); } - foreach ($responseSegments as $hieka) { - // Append data (for pagination) - $this->data .= $hieka->getData(); + // Wenn keine typisierten HIEKA-Segmente gefunden: Diagnose-Logging + if (count($responseSegments) === 0) { + error_log("[BankImport HKEKA] Keine typisierten HIEKA-Segmente, pruefe anonyme..."); + $this->logAnonymousHiekaSegments($response); + } - // Store metadata from first segment - if (empty($this->statementInfo)) { - $this->statementInfo = [ - 'statementNumber' => $hieka->getStatementNumber(), - 'statementYear' => $hieka->getStatementYear(), - 'iban' => $hieka->getIban(), - 'creationDate' => $hieka->getCreationDate(), - 'format' => $hieka->getFormat(), - 'receiptCode' => $hieka->needsReceipt() ? $hieka->getReceiptCode() : null, + if (!$isUnavailable && count($responseSegments) === 0 && count($this->getRequestSegmentNumbers()) > 0) { + error_log("[BankImport HKEKA] FEHLER: Keine HIEKA-Segmente in Antwort!"); + throw new UnexpectedResponseException('Keine HIEKA-Antwort-Segmente erhalten!'); + } + + /** @var HIEKA $hieka */ + foreach ($responseSegments as $segIdx => $hieka) { + error_log("[BankImport HKEKA] Verarbeite HIEKA-Segment " . ($segIdx + 1) . "/" . count($responseSegments)); + + $format = $hieka->getKontoauszugsformat(); + error_log("[BankImport HKEKA] Format=" . ($format ?: 'null') + . " (1=MT940, 2=ISO8583, 3=PDF)"); + + $data = $hieka->getKontoauszug()->getData(); + $rawLen = strlen($data); + $rawStart = substr($data, 0, 20); + error_log("[BankImport HKEKA] Rohdaten: " . $rawLen . " Bytes, Anfang='" . $rawStart + . "', Hex=" . bin2hex(substr($data, 0, 10))); + + // Pruefen ob Base64-kodiert + if ($format === self::FORMAT_PDF && !str_starts_with($data, '%PDF-')) { + error_log("[BankImport HKEKA] PDF-Format aber beginnt NICHT mit %PDF-, pruefe Base64..."); + $decoded = base64_decode($data, true); + if ($decoded !== false && str_starts_with($decoded, '%PDF-')) { + error_log("[BankImport HKEKA] Base64-Dekodierung erfolgreich! " . strlen($decoded) . " Bytes"); + $data = $decoded; + } else { + error_log("[BankImport HKEKA] WARNUNG: Base64-Dekodierung fehlgeschlagen, verwende Rohdaten"); + } + } elseif ($format === null && !str_starts_with($data, '%PDF-')) { + // Kein Format angegeben, trotzdem Base64 pruefen + $decoded = base64_decode($data, true); + if ($decoded !== false && str_starts_with($decoded, '%PDF-')) { + error_log("[BankImport HKEKA] Ohne Format-Angabe: Base64-PDF erkannt! " . strlen($decoded) . " Bytes"); + $data = $decoded; + $format = self::FORMAT_PDF; + } + } + + // Quittung pruefen + $quittung = $hieka->getQuittung(); + if ($quittung !== null) { + error_log("[BankImport HKEKA] Quittung vorhanden: " . strlen($quittung->getData()) . " Bytes"); + } + + if (!empty($data)) { + $this->statements[] = [ + 'data' => $data, + 'format' => $format, ]; + error_log("[BankImport HKEKA] Statement hinzugefuegt (Format=" . ($format ?: 'unbekannt') + . ", gesamt: " . count($this->statements) . ")"); + } else { + error_log("[BankImport HKEKA] WARNUNG: Leere Daten, uebersprungen"); } } + + error_log("[BankImport HKEKA] processResponse() fertig, " . count($this->statements) . " Statements gesammelt"); } } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Action/GetSEPAAccounts.php b/vendor/nemiah/php-fints/lib/Fhp/Action/GetSEPAAccounts.php old mode 100644 new mode 100755 index 1101075..92e876d --- a/vendor/nemiah/php-fints/lib/Fhp/Action/GetSEPAAccounts.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Action/GetSEPAAccounts.php @@ -47,6 +47,7 @@ class GetSEPAAccounts extends PaginateableAction return $this->accounts; } + /** {@inheritdoc} */ protected function createRequest(BPD $bpd, ?UPD $upd) { /** @var BaseSegment $hispas */ @@ -63,6 +64,7 @@ class GetSEPAAccounts extends PaginateableAction } } + /** {@inheritdoc} */ public function processResponse(Message $response) { parent::processResponse($response); diff --git a/vendor/nemiah/php-fints/lib/Fhp/Action/GetSEPADirectDebitParameters.php b/vendor/nemiah/php-fints/lib/Fhp/Action/GetSEPADirectDebitParameters.php old mode 100644 new mode 100755 index 80b8767..5530317 --- a/vendor/nemiah/php-fints/lib/Fhp/Action/GetSEPADirectDebitParameters.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Action/GetSEPADirectDebitParameters.php @@ -16,11 +16,12 @@ class GetSEPADirectDebitParameters extends BaseAction public const SEQUENCE_TYPES = ['FRST', 'OOFF', 'FNAL', 'RCUR']; public const DIRECT_DEBIT_TYPES = ['CORE', 'COR1', 'B2B']; - // Request (if you add a field here, update __serialize() and __unserialize() as well). /** @var string */ private $directDebitType; + /** @var string */ private $seqType; + /** @var bool */ private $singleDirectDebit; @@ -42,45 +43,6 @@ class GetSEPADirectDebitParameters extends BaseAction return $result; } - /** - * @deprecated Beginning from PHP7.4 __unserialize is used for new generated strings, then this method is only used for previously generated strings - remove after May 2023 - */ - public function serialize(): string - { - return serialize($this->__serialize()); - } - - public function __serialize(): array - { - return [ - parent::__serialize(), - $this->directDebitType, $this->seqType, $this->singleDirectDebit, - ]; - } - - /** - * @deprecated Beginning from PHP7.4 __unserialize is used for new generated strings, then this method is only used for previously generated strings - remove after May 2023 - * - * @param string $serialized - * @return void - */ - public function unserialize($serialized) - { - self::__unserialize(unserialize($serialized)); - } - - public function __unserialize(array $serialized): void - { - list( - $parentSerialized, - $this->directDebitType, $this->seqType, $this->singleDirectDebit, - ) = $serialized; - - is_array($parentSerialized) ? - parent::__unserialize($parentSerialized) : - parent::unserialize($parentSerialized); - } - public static function getHixxesSegmentName(string $directDebitType, bool $singleDirectDebit): string { switch ($directDebitType) { @@ -94,6 +56,7 @@ class GetSEPADirectDebitParameters extends BaseAction } } + /** {@inheritdoc} */ protected function createRequest(BPD $bpd, ?UPD $upd) { $this->hidxes = $bpd->requireLatestSupportedParameters(static::getHixxesSegmentName($this->directDebitType, $this->singleDirectDebit)); diff --git a/vendor/nemiah/php-fints/lib/Fhp/Action/GetStatementFromArchive.php b/vendor/nemiah/php-fints/lib/Fhp/Action/GetStatementFromArchive.php deleted file mode 100644 index 5f36078..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Action/GetStatementFromArchive.php +++ /dev/null @@ -1,194 +0,0 @@ -account = $account; - $result->format = $format; - $result->fromDate = $fromDate ? $fromDate->format('Ymd') : null; - $result->toDate = $toDate ? $toDate->format('Ymd') : null; - return $result; - } - - public function __serialize(): array - { - return [ - parent::__serialize(), - $this->account, - $this->format, - $this->fromDate, - $this->toDate, - ]; - } - - public function __unserialize(array $serialized): void - { - list( - $parentSerialized, - $this->account, - $this->format, - $this->fromDate, - $this->toDate - ) = $serialized; - - is_array($parentSerialized) - ? parent::__unserialize($parentSerialized) - : parent::unserialize($parentSerialized); - } - - /** - * @return string The raw PDF data - */ - public function getPdfData(): string - { - $this->ensureDone(); - return $this->pdfData; - } - - /** - * @return array Statement metadata (number, year, iban, date, filename) - */ - public function getStatementInfo(): array - { - $this->ensureDone(); - return $this->statementInfo; - } - - /** - * @return bool Whether receipt confirmation is needed - */ - public function needsReceipt(): bool - { - $this->ensureDone(); - return !empty($this->statementInfo['receiptCode']); - } - - /** {@inheritdoc} */ - protected function createRequest(BPD $bpd, ?UPD $upd) - { - /** @var HIKAASv1|null $hikaas */ - $hikaas = $bpd->getLatestSupportedParameters('HIKAAS'); - - if ($hikaas === null) { - throw new UnsupportedException('The bank does not support archive statements (HKKAA).'); - } - - $param = $hikaas->getParameter(); - - // Check if PDF format is supported - if ($this->format === self::FORMAT_PDF && !$param->supportsPdf()) { - throw new UnsupportedException('The bank does not support PDF format for archive statements.'); - } - - // Check if date range queries are supported - if (($this->fromDate !== null || $this->toDate !== null) && !$param->canFetchByDateRange()) { - throw new UnsupportedException('The bank does not support date range queries for archive statements.'); - } - - // Use the correct HKKAA version based on HIKAAS version in BPD - $hikaasVersion = $hikaas->getVersion(); - - // Use Kti with IBAN/BIC only (not the full account details) - $kti = Kti::create($this->account->getIban(), $this->account->getBic()); - - if ($hikaasVersion >= 2) { - return HKKAAv2::create($kti, $this->format, $this->fromDate, $this->toDate); - } else { - return HKKAAv1::create($kti, $this->format, $this->fromDate, $this->toDate); - } - } - - /** {@inheritdoc} */ - public function processResponse(Message $response) - { - parent::processResponse($response); - - // Check if no statements available - if ($response->findRueckmeldung(Rueckmeldungscode::NICHT_VERFUEGBAR) !== null) { - return; - } - - /** @var HIKAA[] $responseSegments */ - $responseSegments = $response->findSegments(HIKAA::class); - - if (empty($responseSegments)) { - // No segments but also no error = empty response - return; - } - - foreach ($responseSegments as $hikaa) { - // Append PDF data (for pagination) - $this->pdfData .= $hikaa->getPdfData(); - - // Store metadata from first segment - if (empty($this->statementInfo)) { - $this->statementInfo = [ - 'statementNumber' => $hikaa->getStatementNumber(), - 'statementYear' => $hikaa->getStatementYear(), - 'iban' => $hikaa->getIban(), - 'creationDate' => $hikaa->getCreationDate(), - 'filename' => $hikaa->getFilename(), - 'format' => $hikaa->getFormat(), - 'receiptCode' => $hikaa->needsReceipt() ? $hikaa->getReceiptCode() : null, - ]; - } - } - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Action/GetStatementOfAccount.php b/vendor/nemiah/php-fints/lib/Fhp/Action/GetStatementOfAccount.php old mode 100644 new mode 100755 index 8f623ec..8529ec5 --- a/vendor/nemiah/php-fints/lib/Fhp/Action/GetStatementOfAccount.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Action/GetStatementOfAccount.php @@ -31,7 +31,7 @@ use Fhp\UnsupportedException; */ class GetStatementOfAccount extends PaginateableAction { - // Request (if you add a field here, update __serialize() and __unserialize() as well). + // Request (not available after serialization, i.e. not available in processResponse()). /** @var SEPAAccount */ private $account; /** @var \DateTime */ @@ -93,7 +93,7 @@ class GetStatementOfAccount extends PaginateableAction { return [ parent::__serialize(), - $this->account, $this->from, $this->to, $this->allAccounts, $this->includeUnbooked, + $this->account, $this->from, $this->to, $this->allAccounts, $this->bankName, ]; } @@ -113,8 +113,8 @@ class GetStatementOfAccount extends PaginateableAction { list( $parentSerialized, - $this->account, $this->from, $this->to, $this->allAccounts, $this->includeUnbooked, - $this->bankName, + $this->account, $this->from, $this->to, $this->allAccounts, + $this->bankName ) = $serialized; is_array($parentSerialized) ? @@ -147,6 +147,7 @@ class GetStatementOfAccount extends PaginateableAction return $this->statement; } + /** {@inheritdoc} */ protected function createRequest(BPD $bpd, ?UPD $upd) { $this->bankName = $bpd->getBankName(); @@ -170,6 +171,7 @@ class GetStatementOfAccount extends PaginateableAction } } + /** {@inheritdoc} */ public function processResponse(Message $response) { parent::processResponse($response); diff --git a/vendor/nemiah/php-fints/lib/Fhp/Action/GetStatementOfAccountXML.php b/vendor/nemiah/php-fints/lib/Fhp/Action/GetStatementOfAccountXML.php old mode 100644 new mode 100755 index f4ee1a5..71d20cb --- a/vendor/nemiah/php-fints/lib/Fhp/Action/GetStatementOfAccountXML.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Action/GetStatementOfAccountXML.php @@ -24,7 +24,7 @@ use Fhp\UnsupportedException; */ class GetStatementOfAccountXML extends PaginateableAction { - // Request (if you add a field here, update __serialize() and __unserialize() as well). + // Request (not available after serialization, i.e. not available in processResponse()). /** @var SEPAAccount */ private $account; /** @var \DateTime */ @@ -98,7 +98,7 @@ class GetStatementOfAccountXML extends PaginateableAction { list( $parentSerialized, - $this->account, $this->camtURN, $this->from, $this->to, $this->allAccounts, + $this->account, $this->camtURN, $this->from, $this->to, $this->allAccounts ) = $serialized; is_array($parentSerialized) ? @@ -115,6 +115,7 @@ class GetStatementOfAccountXML extends PaginateableAction return $this->xml; } + /** {@inheritdoc} */ protected function createRequest(BPD $bpd, ?UPD $upd) { if ($upd === null) { @@ -148,6 +149,7 @@ class GetStatementOfAccountXML extends PaginateableAction } } + /** {@inheritdoc} */ public function processResponse(Message $response) { parent::processResponse($response); diff --git a/vendor/nemiah/php-fints/lib/Fhp/Action/SendInternationalCreditTransfer.php b/vendor/nemiah/php-fints/lib/Fhp/Action/SendInternationalCreditTransfer.php old mode 100644 new mode 100755 index 73416fc..2634f24 --- a/vendor/nemiah/php-fints/lib/Fhp/Action/SendInternationalCreditTransfer.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Action/SendInternationalCreditTransfer.php @@ -13,11 +13,12 @@ use Fhp\Syntax\Bin; class SendInternationalCreditTransfer extends BaseAction { - // Request (if you add a field here, update __serialize() and __unserialize() as well). /** @var SEPAAccount */ protected $account; + /** @var string */ protected $dtavzData; + /** @var string|null */ protected $dtavzVersion; @@ -35,45 +36,6 @@ class SendInternationalCreditTransfer extends BaseAction return $result; } - /** - * @deprecated Beginning from PHP7.4 __unserialize is used for new generated strings, then this method is only used for previously generated strings - remove after May 2023 - */ - public function serialize(): string - { - return serialize($this->__serialize()); - } - - public function __serialize(): array - { - return [ - parent::__serialize(), - $this->account, $this->dtavzData, $this->dtavzVersion, - ]; - } - - /** - * @deprecated Beginning from PHP7.4 __unserialize is used for new generated strings, then this method is only used for previously generated strings - remove after May 2023 - * - * @param string $serialized - * @return void - */ - public function unserialize($serialized) - { - self::__unserialize(unserialize($serialized)); - } - - public function __unserialize(array $serialized): void - { - list( - $parentSerialized, - $this->account, $this->dtavzData, $this->dtavzVersion, - ) = $serialized; - - is_array($parentSerialized) ? - parent::__unserialize($parentSerialized) : - parent::unserialize($parentSerialized); - } - protected function createRequest(BPD $bpd, ?UPD $upd) { /** @var HIAUBSv9 $hiaubs */ diff --git a/vendor/nemiah/php-fints/lib/Fhp/Action/SendSEPADirectDebit.php b/vendor/nemiah/php-fints/lib/Fhp/Action/SendSEPADirectDebit.php old mode 100644 new mode 100755 index 0976ed4..1c9fe59 --- a/vendor/nemiah/php-fints/lib/Fhp/Action/SendSEPADirectDebit.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Action/SendSEPADirectDebit.php @@ -11,10 +11,8 @@ use Fhp\Segment\Common\Btg; use Fhp\Segment\Common\Kti; use Fhp\Segment\DME\HIDMESv1; use Fhp\Segment\DME\HIDMESv2; -use Fhp\Segment\DME\HKDMEv2; use Fhp\Segment\DSE\HIDSESv2; use Fhp\Segment\DSE\HIDXES; -use Fhp\Segment\DSE\HKDSEv2; use Fhp\Segment\SPA\HISPAS; use Fhp\Syntax\Bin; use Fhp\UnsupportedException; @@ -24,24 +22,27 @@ use Fhp\UnsupportedException; */ class SendSEPADirectDebit extends BaseAction { - // Request (if you add a field here, update __serialize() and __unserialize() as well). /** @var SEPAAccount */ protected $account; + /** @var string */ protected $painMessage; + /** @var string */ protected $painNamespace; + /** @var float */ protected $ctrlSum; + /** @var bool */ protected $singleDirectDebit = false; + /** @var bool */ protected $tryToUseControlSumForSingleTransactions = false; + /** @var string */ private $coreType; - // There are no result fields. This action is simply marked as done to indicate that the transfer was executed. - public static function create(SEPAAccount $account, string $painMessage, bool $tryToUseControlSumForSingleTransactions = false): SendSEPADirectDebit { if (preg_match('/xmlns="(?[^"]+)"/s', $painMessage, $matches) === 1) { @@ -113,7 +114,7 @@ class SendSEPADirectDebit extends BaseAction { list( $parentSerialized, - $this->singleDirectDebit, $this->tryToUseControlSumForSingleTransactions, $this->ctrlSum, $this->coreType, $this->painMessage, $this->painNamespace, $this->account, + $this->singleDirectDebit, $this->tryToUseControlSumForSingleTransactions, $this->ctrlSum, $this->coreType, $this->painMessage, $this->painNamespace, $this->account ) = $serialized; is_array($parentSerialized) ? @@ -150,7 +151,7 @@ class SendSEPADirectDebit extends BaseAction // Sometimes the Bank reports supported schemas with a "_GBIC_X" postfix. // GIBC_X stands for German Banking Industry Committee and a version counter. $xmlSchema = $this->painNamespace; - $matchingSchemas = array_filter($supportedPainNamespaces, function ($value) use ($xmlSchema) { + $matchingSchemas = array_filter($supportedPainNamespaces, function($value) use ($xmlSchema) { // For example urn:iso:std:iso:20022:tech:xsd:pain.008.001.08 from the xml matches // urn:iso:std:iso:20022:tech:xsd:pain.008.001.08_GBIC_4 return str_starts_with($value, $xmlSchema); @@ -161,7 +162,7 @@ class SendSEPADirectDebit extends BaseAction . implode(', ', $supportedPainNamespaces)); } - /** @var HKDMEv2|HKDSEv2|HIDXES $hkdxe */ + /** @var mixed $hkdxe */ // TODO Put a new interface type here. $hkdxe = $hidxes->createRequestSegment(); $hkdxe->kontoverbindungInternational = Kti::fromAccount($this->account); $hkdxe->sepaDescriptor = $this->painNamespace; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Action/SendSEPARealtimeTransfer.php b/vendor/nemiah/php-fints/lib/Fhp/Action/SendSEPARealtimeTransfer.php old mode 100644 new mode 100755 index c3bd960..22dfda3 --- a/vendor/nemiah/php-fints/lib/Fhp/Action/SendSEPARealtimeTransfer.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Action/SendSEPARealtimeTransfer.php @@ -23,16 +23,14 @@ use Fhp\UnsupportedException; */ class SendSEPARealtimeTransfer extends BaseAction { - // Request (if you add a field here, update __serialize() and __unserialize() as well). /** @var SEPAAccount */ private $account; /** @var string */ private $painMessage; /** @var string */ private $xmlSchema; - private bool $allowConversionToSEPATransfer = true; - // There are no result fields. This action is simply marked as done to indicate that the transfer was executed. + private bool $allowConversionToSEPATransfer = true; /** * @param SEPAAccount $account The account from which the transfer will be sent. @@ -54,45 +52,7 @@ class SendSEPARealtimeTransfer extends BaseAction return $result; } - /** - * @deprecated Beginning from PHP7.4 __unserialize is used for new generated strings, then this method is only used for previously generated strings - remove after May 2023 - */ - public function serialize(): string - { - return serialize($this->__serialize()); - } - - public function __serialize(): array - { - return [ - parent::__serialize(), - $this->account, $this->painMessage, $this->xmlSchema, $this->allowConversionToSEPATransfer, - ]; - } - - /** - * @deprecated Beginning from PHP7.4 __unserialize is used for new generated strings, then this method is only used for previously generated strings - remove after May 2023 - * - * @param string $serialized - * @return void - */ - public function unserialize($serialized) - { - self::__unserialize(unserialize($serialized)); - } - - public function __unserialize(array $serialized): void - { - list( - $parentSerialized, - $this->account, $this->painMessage, $this->xmlSchema, $this->allowConversionToSEPATransfer, - ) = $serialized; - - is_array($parentSerialized) ? - parent::__unserialize($parentSerialized) : - parent::unserialize($parentSerialized); - } - + /** {@inheritdoc} */ protected function createRequest(BPD $bpd, ?UPD $upd) { /** @var HIIPZSv1|HIIPZSv2 $hiipzs */ @@ -110,7 +70,7 @@ class SendSEPARealtimeTransfer extends BaseAction // Sometimes the Bank reports supported schemas with a "_GBIC_X" postfix. // GIBC_X stands for German Banking Industry Committee and a version counter. $xmlSchema = $this->xmlSchema; - $matchingSchemas = array_filter($supportedSchemas, function ($value) use ($xmlSchema) { + $matchingSchemas = array_filter($supportedSchemas, function($value) use ($xmlSchema) { // For example urn:iso:std:iso:20022:tech:xsd:pain.001.001.09 from the xml matches // urn:iso:std:iso:20022:tech:xsd:pain.001.001.09_GBIC_4 return str_starts_with($value, $xmlSchema); @@ -132,6 +92,7 @@ class SendSEPARealtimeTransfer extends BaseAction return $hkipz; } + /** {@inheritdoc} */ public function processResponse(Message $response) { parent::processResponse($response); @@ -145,8 +106,8 @@ class SendSEPARealtimeTransfer extends BaseAction return; } - if ($response->findRueckmeldung(Rueckmeldungscode::ENTGEGENGENOMMEN) === null - && $response->findRueckmeldung(Rueckmeldungscode::AUSGEFUEHRT) === null) { + if ($response->findRueckmeldung(Rueckmeldungscode::ENTGEGENGENOMMEN) === null && + $response->findRueckmeldung(Rueckmeldungscode::AUSGEFUEHRT) === null) { throw new UnexpectedResponseException('Bank did not confirm SEPATransfer execution'); } } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Action/SendSEPATransfer.php b/vendor/nemiah/php-fints/lib/Fhp/Action/SendSEPATransfer.php old mode 100644 new mode 100755 index a7ce104..68de23b --- a/vendor/nemiah/php-fints/lib/Fhp/Action/SendSEPATransfer.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Action/SendSEPATransfer.php @@ -19,17 +19,12 @@ use Fhp\UnsupportedException; */ class SendSEPATransfer extends BaseAction { - // Request (if you add a field here, update __serialize() and __unserialize() as well). /** @var SEPAAccount */ private $account; /** @var string */ private $painMessage; /** @var string */ private $xmlSchema; - /** @var bool */ - private $singleBookingRequested = false; - - // There are no result fields. This action is simply marked as done to indicate that the transfer was executed. /** * @param SEPAAccount $account The account from which the transfer will be sent. @@ -49,62 +44,11 @@ class SendSEPATransfer extends BaseAction return $result; } - /** - * Request individual bookings instead of a batch booking on the bank statement. - * Only applicable for batch transfers (Sammelüberweisung). - * - * @param bool $singleBookingRequested If true, each transaction appears separately on the statement. - * @return $this - */ - public function setSingleBookingRequested(bool $singleBookingRequested): self - { - $this->singleBookingRequested = $singleBookingRequested; - return $this; - } - - /** - * @deprecated Beginning from PHP7.4 __unserialize is used for new generated strings, then this method is only used for previously generated strings - remove after May 2023 - */ - public function serialize(): string - { - return serialize($this->__serialize()); - } - - public function __serialize(): array - { - return [ - parent::__serialize(), - $this->account, $this->painMessage, $this->xmlSchema, $this->singleBookingRequested, - ]; - } - - /** - * @deprecated Beginning from PHP7.4 __unserialize is used for new generated strings, then this method is only used for previously generated strings - remove after May 2023 - * - * @param string $serialized - * @return void - */ - public function unserialize($serialized) - { - self::__unserialize(unserialize($serialized)); - } - - public function __unserialize(array $serialized): void - { - list( - $parentSerialized, - $this->account, $this->painMessage, $this->xmlSchema, $this->singleBookingRequested, - ) = $serialized; - - is_array($parentSerialized) ? - parent::__unserialize($parentSerialized) : - parent::unserialize($parentSerialized); - } - + /** {@inheritdoc} */ protected function createRequest(BPD $bpd, ?UPD $upd) { - // ANALYSE XML FOR RECEIPTS AND PAYMENT DATE - $xmlAsObject = simplexml_load_string($this->painMessage, 'SimpleXMLElement', LIBXML_NOCDATA); + //ANALYSE XML FOR RECEIPTS AND PAYMENT DATE + $xmlAsObject = simplexml_load_string($this->painMessage, "SimpleXMLElement", LIBXML_NOCDATA); $numberOfTransactions = $xmlAsObject->CstmrCdtTrfInitn->GrpHdr->NbOfTxs; $hasReqdExDates = false; foreach ($xmlAsObject->CstmrCdtTrfInitn?->PmtInf as $pmtInfo) { @@ -115,21 +59,25 @@ class SendSEPATransfer extends BaseAction } } - // NOW READ OUT, WICH SEGMENT SHOULD BE USED: + //NOW READ OUT, WICH SEGMENT SHOULD BE USED: if ($numberOfTransactions > 1 && $hasReqdExDates) { + // Terminierte SEPA-Sammelüberweisung (Segment HKCME / Kennung HICMES) $segmentID = 'HICMES'; $segment = \Fhp\Segment\CME\HKCMEv1::createEmpty(); } elseif ($numberOfTransactions == 1 && $hasReqdExDates) { + // Terminierte SEPA-Überweisung (Segment HKCSE / Kennung HICSES) $segmentID = 'HICSES'; $segment = \Fhp\Segment\CSE\HKCSEv1::createEmpty(); } elseif ($numberOfTransactions > 1 && !$hasReqdExDates) { + // SEPA-Sammelüberweisungen (Segment HKCCM / Kennung HICSES) $segmentID = 'HICSES'; $segment = \Fhp\Segment\CCM\HKCCMv1::createEmpty(); } else { - // SEPA Einzelüberweisung (Segment HKCCS / Kennung HICCSS). + + //SEPA Einzelüberweisung (Segment HKCCS / Kennung HICCSS). $segmentID = 'HICCSS'; $segment = \Fhp\Segment\CCS\HKCCSv1::createEmpty(); } @@ -145,7 +93,7 @@ class SendSEPATransfer extends BaseAction // Sometimes the Bank reports supported schemas with a "_GBIC_X" postfix. // GIBC_X stands for German Banking Industry Committee and a version counter. $xmlSchema = $this->xmlSchema; - $matchingSchemas = array_filter($supportedSchemas, function ($value) use ($xmlSchema) { + $matchingSchemas = array_filter($supportedSchemas, function($value) use ($xmlSchema) { // For example urn:iso:std:iso:20022:tech:xsd:pain.001.001.09 from the xml matches // urn:iso:std:iso:20022:tech:xsd:pain.001.001.09_GBIC_4 return str_starts_with($value, $xmlSchema); @@ -159,19 +107,10 @@ class SendSEPATransfer extends BaseAction $segment->kontoverbindungInternational = Kti::fromAccount($this->account); $segment->sepaDescriptor = $this->xmlSchema; $segment->sepaPainMessage = new Bin($this->painMessage); - - // For batch transfers: set einzelbuchungGewuenscht if bank allows it - if ($numberOfTransactions > 1) { - $paramSegmentId = $hasReqdExDates ? 'HICMES' : 'HICCMS'; - $paramSegment = $bpd->getLatestSupportedParameters($paramSegmentId); - if ($paramSegment !== null && $paramSegment->getParameter()->einzelbuchungErlaubt) { - $segment->einzelbuchungGewuenscht = $this->singleBookingRequested; - } - } - return $segment; } + /** {@inheritdoc} */ public function processResponse(Message $response) { parent::processResponse($response); diff --git a/vendor/nemiah/php-fints/lib/Fhp/BaseAction.php b/vendor/nemiah/php-fints/lib/Fhp/BaseAction.php old mode 100644 new mode 100755 index 735b390..d36dec6 --- a/vendor/nemiah/php-fints/lib/Fhp/BaseAction.php +++ b/vendor/nemiah/php-fints/lib/Fhp/BaseAction.php @@ -4,17 +4,13 @@ namespace Fhp; -use Fhp\Model\PollingInfo; use Fhp\Model\TanRequest; -use Fhp\Model\VopConfirmationRequest; use Fhp\Protocol\ActionIncompleteException; -use Fhp\Protocol\ActionPendingException; use Fhp\Protocol\BPD; use Fhp\Protocol\Message; use Fhp\Protocol\TanRequiredException; use Fhp\Protocol\UnexpectedResponseException; use Fhp\Protocol\UPD; -use Fhp\Protocol\VopConfirmationRequiredException; use Fhp\Segment\BaseSegment; use Fhp\Segment\HIRMS\Rueckmeldung; use Fhp\Segment\HIRMS\Rueckmeldungscode; @@ -41,37 +37,37 @@ use Fhp\Segment\HIRMS\Rueckmeldungscode; abstract class BaseAction implements \Serializable { /** @var int[] Stores segment numbers that were assigned to the segments returned from {@link createRequest()}. */ - protected ?array $requestSegmentNumbers = null; + protected $requestSegmentNumbers; /** - * Contains the name of the segment, that might need a tan, used by FinTs::execute to signal + * @var string|null Contains the name of the segment, that might need a tan, used by FinTs::execute to signal * to the bank that supplying a tan is supported. */ - protected ?string $needTanForSegment = null; + protected $needTanForSegment = null; - /** If set, the last response from the server regarding this action asked for a TAN from the user. */ - protected ?TanRequest $tanRequest = null; + /** + * If set, the last response from the server regarding this action asked for a TAN from the user. + * @var TanRequest|null + */ + protected $tanRequest; - /** If set, this action is currently waiting for a long-running operation on the server to complete. */ - protected ?PollingInfo $pollingInfo = null; - - /** If set, this action needs the user's confirmation to be completed. */ - protected ?VopConfirmationRequest $vopConfirmationRequest = null; - - protected bool $isDone = false; + /** @var bool */ + protected $isDone = false; /** * Will be populated with the message the bank sent along with the success indication, can be used to show to * the user. + * @var string */ - public ?string $successMessage = null; + public $successMessage; /** * @deprecated Beginning from PHP7.4 __unserialize is used for new generated strings, then this method is only used for previously generated strings - remove after May 2023 * * NOTE: A common mistake is to call this function directly. Instead, you probably want `serialize($instance)`. * - * An action can only be serialized before it was completed. + * An action can only be serialized *after* it has been executed in case it needs a TAN, i.e. when the result is not + * present yet. * If a sub-class overrides this, it should call the parent function and include it in its result. * @return string The serialized action, e.g. for storage in a database. This will not contain sensitive user data. */ @@ -81,23 +77,21 @@ abstract class BaseAction implements \Serializable } /** - * An action can only be serialized before it was completed. + * An action can only be serialized *after* it has been executed in case it needs a TAN, i.e. when the result is not + * present yet. * If a sub-class overrides this, it should call the parent function and include it in its result. * * @return array The serialized action, e.g. for storage in a database. This will not contain sensitive user data. - * Note that this is not necessarily valid UTF-8, so you should store it as a BLOB column or raw bytes. */ public function __serialize(): array { - if ($this->isDone()) { - throw new \RuntimeException('Completed actions cannot be serialized.'); + if (!$this->needsTan()) { + throw new \RuntimeException('Cannot serialize this action, because it is not waiting for a TAN.'); } return [ $this->requestSegmentNumbers, $this->tanRequest, $this->needTanForSegment, - $this->pollingInfo, - $this->vopConfirmationRequest, ]; } @@ -117,10 +111,8 @@ abstract class BaseAction implements \Serializable list( $this->requestSegmentNumbers, $this->tanRequest, - $this->needTanForSegment, - $this->pollingInfo, - $this->vopConfirmationRequest, - ) = array_pad($serialized, 5, null); + $this->needTanForSegment + ) = $serialized; } /** @@ -152,54 +144,25 @@ abstract class BaseAction implements \Serializable return $this->tanRequest; } - public function needsPollingWait(): bool - { - return !$this->isDone() && $this->pollingInfo !== null; - } - - public function getPollingInfo(): ?PollingInfo - { - return $this->pollingInfo; - } - - public function needsVopConfirmation(): bool - { - return !$this->isDone() && $this->vopConfirmationRequest !== null; - } - - public function getVopConfirmationRequest(): ?VopConfirmationRequest - { - return $this->vopConfirmationRequest; - } - /** * Throws an exception unless this action has been successfully executed, i.e. in the following cases: * - the action has not been {@link FinTs::execute()}-d at all or the {@link FinTs::execute()} call for it threw an * exception, - * - the action is awaiting a TAN/confirmation (as per {@link BaseAction::needsTan()}, - * - the action is pending a long-running operation on the bank server ({@link BaseAction::needsPollingWait()}), - * - the action is awaiting the user's confirmation of the Verification of Payee result (as per - * {@link BaseAction::needsVopConfirmation()}). + * - the action is awaiting a TAN/confirmation (as per {@link BaseAction::needsTan()}. * * After executing an action, you can use this function to make sure that it succeeded. This is especially useful * for actions that don't have any results (as each result getter would call {@link ensureDone()} internally). * On the other hand, you do not need to call this function if you make sure that (1) you called - * {@link FinTs::execute()} and (2) you checked and resolved all other special outcome states documented there. - * Note that both exception types thrown from this method are sub-classes of {@link \RuntimeException}, so you - * shouldn't need a try-catch block at the call site for this. + * {@link FinTs::execute()} and (2) you checked {@link needsTan()} and, if it returned true, supplied a TAN by + * calling {@ink FinTs::submitTan()}. Note that both exception types thrown from this method are sub-classes of + * {@link \RuntimeException}, so you shouldn't need a try-catch block at the call site for this. * @throws ActionIncompleteException If the action hasn't even been executed. - * @throws ActionPendingException If the action is pending a long-running server operation that needs polling. - * @throws VopConfirmationRequiredException If the action requires the user's confirmation for VOP. * @throws TanRequiredException If the action needs a TAN. */ - public function ensureDone(): void + public function ensureDone() { if ($this->tanRequest !== null) { throw new TanRequiredException($this->tanRequest); - } elseif ($this->pollingInfo !== null) { - throw new ActionPendingException($this->pollingInfo); - } elseif ($this->vopConfirmationRequest !== null) { - throw new VopConfirmationRequiredException($this->vopConfirmationRequest); } elseif (!$this->isDone()) { throw new ActionIncompleteException(); } @@ -268,7 +231,7 @@ abstract class BaseAction implements \Serializable /** @return int[] */ public function getRequestSegmentNumbers(): array { - return $this->requestSegmentNumbers ?? []; + return $this->requestSegmentNumbers; } /** @@ -285,21 +248,11 @@ abstract class BaseAction implements \Serializable $this->requestSegmentNumbers = $requestSegmentNumbers; } - /** To be called only by the FinTs instance that executes this action. */ - final public function setTanRequest(?TanRequest $tanRequest): void + /** + * To be called only by the FinTs instance that executes this action. + */ + final public function setTanRequest(?TanRequest $tanRequest) { $this->tanRequest = $tanRequest; } - - /** To be called only by the FinTs instance that executes this action. */ - final public function setPollingInfo(?PollingInfo $pollingInfo): void - { - $this->pollingInfo = $pollingInfo; - } - - /** To be called only by the FinTs instance that executes this action. */ - final public function setVopConfirmationRequest(?VopConfirmationRequest $vopConfirmationRequest): void - { - $this->vopConfirmationRequest = $vopConfirmationRequest; - } } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Connection.php b/vendor/nemiah/php-fints/lib/Fhp/Connection.php old mode 100644 new mode 100755 index c461473..5b2981d --- a/vendor/nemiah/php-fints/lib/Fhp/Connection.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Connection.php @@ -7,10 +7,25 @@ namespace Fhp; */ class Connection { - protected string $url; - protected ?\CurlHandle $curlHandle = null; - protected int $timeoutConnect = 15; - protected int $timeoutResponse = 30; + /** + * @var string + */ + protected $url; + + /** + * @var resource + */ + protected $curlHandle; + + /** + * @var int + */ + protected $timeoutConnect = 15; + + /** + * @var int + */ + protected $timeoutResponse = 30; public function __construct(string $url, int $timeoutConnect = 15, int $timeoutResponse = 30) { @@ -19,12 +34,9 @@ class Connection $this->timeoutResponse = $timeoutResponse; } - /** - * @throws CurlException When initializing cURL fails. - */ - private function connect(): void + private function connect() { - $this->curlHandle = curl_init() ?: throw new CurlException('Failed initializing cURL.'); + $this->curlHandle = curl_init(); curl_setopt($this->curlHandle, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($this->curlHandle, CURLOPT_SSL_VERIFYHOST, 2); @@ -40,7 +52,7 @@ class Connection curl_setopt($this->curlHandle, CURLOPT_HTTPHEADER, ['cache-control: no-cache', 'Content-Type: text/plain']); } - public function disconnect(): void + public function disconnect() { if ($this->curlHandle !== null) { curl_close($this->curlHandle); @@ -64,7 +76,7 @@ class Connection if (false === $response) { throw new CurlException( - 'Failed sending to ' . $this->url . ': ' . curl_error($this->curlHandle), + 'Failed connection to ' . $this->url . ': ' . curl_error($this->curlHandle), null, curl_errno($this->curlHandle), curl_getinfo($this->curlHandle), diff --git a/vendor/nemiah/php-fints/lib/Fhp/CurlException.php b/vendor/nemiah/php-fints/lib/Fhp/CurlException.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/FinTs.php b/vendor/nemiah/php-fints/lib/Fhp/FinTs.php old mode 100644 new mode 100755 index 24f1b6b..a124c27 --- a/vendor/nemiah/php-fints/lib/Fhp/FinTs.php +++ b/vendor/nemiah/php-fints/lib/Fhp/FinTs.php @@ -5,10 +5,6 @@ namespace Fhp; use Fhp\Model\NoPsd2TanMode; use Fhp\Model\TanMedium; use Fhp\Model\TanMode; -use Fhp\Model\VopConfirmationRequest; -use Fhp\Model\VopConfirmationRequestImpl; -use Fhp\Model\VopPollingInfo; -use Fhp\Model\VopVerificationResult; use Fhp\Options\Credentials; use Fhp\Options\FinTsOptions; use Fhp\Options\SanitizingLogger; @@ -30,8 +26,6 @@ use Fhp\Segment\TAN\HITAN; use Fhp\Segment\TAN\HKTAN; use Fhp\Segment\TAN\HKTANFactory; use Fhp\Segment\TAN\HKTANv6; -use Fhp\Segment\VPP\HKVPPv1; -use Fhp\Segment\VPP\VopHelper; use Fhp\Syntax\InvalidResponseException; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; @@ -165,7 +159,6 @@ class FinTs * carefully (not written to log files, only to a database or other storage system that would normally be used * for user data). The returned string never contains highly sensitive information (not the user's password or * PIN), so it probably does not need to be encrypted. Treat it like a session cookie of the same bank. - * Note that this is not necessarily valid UTF-8, so you should store it as a BLOB column or raw bytes. */ public function persist(bool $minimal = false): string { @@ -208,7 +201,7 @@ class FinTs * * @throws \InvalidArgumentException */ - public function loadPersistedInstance(string $persistedInstance): void + public function loadPersistedInstance(string $persistedInstance) { $unserialized = unserialize($persistedInstance); if (!is_array($unserialized) || count($unserialized) === 0) { @@ -223,7 +216,7 @@ class FinTs } } - private function loadPersistedInstanceVersion2(array $data): void + private function loadPersistedInstanceVersion2(array $data) { list( // This should match persist(). $this->bpd, @@ -233,7 +226,7 @@ class FinTs $this->selectedTanMedium, $this->kundensystemId, $this->dialogId, - $this->messageNumber, + $this->messageNumber ) = $data; } @@ -261,7 +254,7 @@ class FinTs * @param int $responseTimeout The number of seconds to wait before aborting a request to the bank server. * @noinspection PhpUnused */ - public function setTimeouts(int $connectTimeout, int $responseTimeout): void + public function setTimeouts(int $connectTimeout, int $responseTimeout) { $this->options->timeoutConnect = $connectTimeout; $this->options->timeoutResponse = $responseTimeout; @@ -292,7 +285,7 @@ class FinTs /** * Executes an action. Be sure to {@link login()} first. See the `\Fhp\Action` package for actions that can be - * executed with this function. Note that, after this function returns, the action can be in the following states: + * executed with this function. Note that, after this function returns, the action can be in two possible states: * 1. If {@link BaseAction::needsTan()} returns true, the action isn't completed yet because needs a TAN or other * kind of two-factor authentication (2FA). In this case, use {@link BaseAction::getTanRequest()} to get more * information about the TAN/2FA that is needed. Your application then needs to interact with the user to obtain @@ -300,30 +293,9 @@ class FinTs * be verified with {@link checkDecoupledSubmission()}). Both of those functions require passing the same * {@link BaseAction} argument as an argument, and once they succeed, the action will be in the same completed * state as if it had been completed right away. - * 2. If {@link BaseAction::needsPollingWait()} returns true, the action isn't completed yet because the server is - * still running some slow operation. Importantly, the server has not necessarily accepted the action yet, so it - * is absolutely required that the client keeps polling if they don't want the action to be abandoned. - * In this case, use {@link BaseAction::getPollingInfo()} to get more information on how frequently to poll, and - * do the polling through {@link pollAction()}. - * 3. If {@link BaseAction::needsVopConfirmation()} returns true, the action isn't completed yet because the payee - * information couldn't be matched automatically, so an explicit confirmation from the user is required. - * In this case, use {@link BaseAction::getVopConfirmationRequest()} to get more information to display to the - * user, ask the user to confirm that they want to proceed with the action, and then call {@link confirmVop()}. - * 4. If none of the above return true, the action was completed right away. - * Use the respective getters on the action instance to retrieve the result. In case the action fails, the - * corresponding exception will be thrown from this function. - * - * Tip: In practice, polling (2.) and confirmation (3.) are needed only for Verification of Payee. So if your - * application only ever executes read-only actions like account statement fetching, but never executes any - * transfers, instead of handling these cases you could simply assert that {@link BaseAction::needsPollingWait()} - * and {@link BaseAction::needsVopConfirmation()} both return false. - * - * Note that all conditions above that leave the action in an incomplete state require some action from the client - * application. These actions then change the state of the action again, but they don't necessarily complete it. - * In practice, the typical sequence is: Maybe polling, maybe VOP confirmation, maybe TAN, done. That said, you - * should ideally implement your application to deal with any sequence of states. Just execute the action, check - * what's state it's in, resolve that state as appropriate, and then check again (using the same code as before). Do - * this repeatedly until none of the special conditions above happen anymore, at which point the action is done. + * 2. If {@link BaseAction::needsTan()} returns false, the action was completed right away. Use the respective + * getters on the action instance to retrieve the result. In case the action fails, the corresponding exception + * will be thrown from this function. * * @param BaseAction $action The action to be executed. Its {@link BaseAction::isDone()} status will be updated when * this function returns successfully. @@ -332,36 +304,27 @@ class FinTs * @throws ServerException When the server responds with a (FinTS-encoded) error message, which includes most things * that can go wrong with the action itself, like wrong credentials, invalid IBANs, locked accounts, etc. */ - public function execute(BaseAction $action): void + public function execute(BaseAction $action) { if ($this->dialogId === null && !($action instanceof DialogInitialization)) { throw new \RuntimeException('Need to login (DialogInitialization) before executing other actions'); } - // Add the action's main request segments. $requestSegments = $action->getNextRequest($this->bpd, $this->upd); + if (count($requestSegments) === 0) { return; // No request needed. } - $message = MessageBuilder::create()->add($requestSegments); - // Add HKTAN for authentication if necessary. + // Construct the full request message. + $message = MessageBuilder::create()->add($requestSegments); // This fills in the segment numbers. if (!($this->getSelectedTanMode() instanceof NoPsd2TanMode)) { if (($needTanForSegment = $action->getNeedTanForSegment()) !== null) { $message->add(HKTANFactory::createProzessvariante2Step1( $this->requireTanMode(), $this->selectedTanMedium, $needTanForSegment)); } } - - // Add HKVPP for VOP verification if necessary. - $hkvpp = null; - if ($this->bpd?->vopRequiredForRequest($requestSegments) !== null) { - $hkvpp = VopHelper::createHKVPPForInitialRequest($this->bpd); - $message->add($hkvpp); - } - - // Construct the request message and tell the action about the segment numbers that were assigned. - $request = $this->buildMessage($message, $this->getSelectedTanMode()); // This fills in the segment numbers. + $request = $this->buildMessage($message, $this->getSelectedTanMode()); $action->setRequestSegmentNumbers(array_map(function ($segment) { /* @var BaseSegment $segment */ return $segment->getSegmentNumber(); @@ -369,28 +332,11 @@ class FinTs // Execute the request. $response = $this->sendMessage($request); - $this->processServerResponse($action, $response, $hkvpp); - } - - /** - * Updates the state of this FinTs instance and of the `$action` based on the server's response. - * See {@link execute()} for more documentation on the possible outcomes. - * @param BaseAction $action The action for which the request was sent. - * @param Message $response The response we just got from the server. - * @param HKVPPv1|null $hkvpp The HKVPP segment, if any was present in the request. - * @throws CurlException When the connection fails in a layer below the FinTS protocol. - * @throws UnexpectedResponseException When the server responds with a valid but unexpected message. - * @throws ServerException When the server responds with a (FinTS-encoded) error message, which includes most things - * that can go wrong with the action itself, like wrong credentials, invalid IBANs, locked accounts, etc. - */ - private function processServerResponse(BaseAction $action, Message $response, ?HKVPPv1 $hkvpp = null): void - { $this->readBPD($response); // Detect if the bank wants a TAN. /** @var HITAN $hitan */ $hitan = $response->findSegment(HITAN::class); - // Note: Instead of DUMMY_REFERENCE, it's officially the 3076 Rueckmeldungscode that tells we don't need a TAN. if ($hitan !== null && $hitan->getAuftragsreferenz() !== HITAN::DUMMY_REFERENCE) { if ($hitan->tanProzess !== HKTAN::TAN_PROZESS_4) { throw new UnexpectedResponseException("Unsupported TAN request type $hitan->tanProzess"); @@ -404,51 +350,14 @@ class FinTs $action->setDialogId($response->header->dialogId); $action->setMessageNumber($this->messageNumber); } + return; } - // Detect if the bank needs us to do something for Verification of Payee. - if ($hkvpp != null) { - if ($pollingInfo = VopHelper::checkPollingRequired($response, $hkvpp->getSegmentNumber())) { - $action->setPollingInfo($pollingInfo); - if ($action->needsTan()) { - throw new UnexpectedResponseException('Unexpected polling and TAN request in the same response.'); - } - return; - } - if ($confirmationRequest = VopHelper::checkVopConfirmationRequired($response, $hkvpp->getSegmentNumber())) { - $action->setVopConfirmationRequest($confirmationRequest); - if ($action->needsTan()) { - if ($confirmationRequest->getVerificationResult() === VopVerificationResult::CompletedFullMatch) { - // If someone hits this branch in practice, we can implement it. - throw new UnsupportedException('Combined VOP match confirmation and TAN request'); - } else { - throw new UnexpectedResponseException( - 'Unexpected TAN request on VOP result: ' . $confirmationRequest->getVerificationResult() - ); - } - } - } - } - - if ($action->needsVopConfirmation() || $action->needsTan()) { - return; // The action isn't complete yet. - } - - // If no TAN or VOP is needed, process the response normally, and maybe keep going for more pages. + // If no TAN is needed, process the response normally, and maybe keep going for more pages. $this->processActionResponse($action, $response->filterByReferenceSegments($action->getRequestSegmentNumbers())); if ($action instanceof PaginateableAction && $action->hasMorePages()) { $this->execute($action); } - - // Check whether the server requested a Kundensystem-ID refresh. - if ($response->findRueckmeldung(Rueckmeldungscode::NEUE_KUNDENSYSTEM_ID_HOLEN) !== null) { - // TODO Properly implement the refresh here, see https://github.com/nemiah/phpFinTS/issues/458. - $this->logger->warning( - 'The server asked us to refresh the Kundensystem-ID in response to a ' . gettype($action) . - ' action, but that is not implemented yet. This could result in authentication errors or extraneous ' . - ' re-authentication prompts from the bank.' - ); - } } /** @@ -456,9 +365,9 @@ class FinTs * `false`, this function sends the given $tan to the server to complete the action. By using {@link persist()}, * this can be done asynchronously, i.e., not in the same PHP process as the original {@link execute()} call. * - * After this function returns, the `$action` is in any of the same states as after {@link execute()}, see there. - * In practice, the action is fully completed after completing the decoupled submission. - * In case the action fails, the corresponding exception will be thrown from this function. + * After this function returns, the `$action` is completed. That is, its result is available through its getters + * just as if it had been completed by the original call to {@link execute()} right away. In case the action fails, + * the corresponding exception will be thrown from this function. * * @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Security_Sicherheitsverfahren_PINTAN_2020-07-10_final_version.pdf * Section B.4.2.1.1 @@ -470,7 +379,7 @@ class FinTs * @throws ServerException When the server responds with a (FinTS-encoded) error message, which includes most things * that can go wrong with the action itself, like wrong credentials, invalid IBANs, locked accounts, etc. */ - public function submitTan(BaseAction $action, string $tan): void + public function submitTan(BaseAction $action, string $tan) { // Check the action's state. $tanRequest = $action->getTanRequest(); @@ -524,9 +433,7 @@ class FinTs * For an action where {@link BaseAction::needsTan()} returns `true` and {@link TanMode::isDecoupled()} returns * `true`, this function checks with the server whether the second factor authentication has been completed yet on * the secondary device of the user. - * - If so, this function returns `true` and the `$action` is then in any of the same states as after - * {@link execute()} (except {@link BaseAction::needsTan()} won't happen again). See there for documentation. - * In practice, the action is fully completed after completing the decoupled submission. + * - If so, this completes the given action and returns `true`. * - In case the action fails, the corresponding exception will be thrown from this function. * - If the authentication has not been completed yet, this returns `false` and the action remains in its * previous, uncompleted state. @@ -542,10 +449,9 @@ class FinTs * Section B.4.2.2 * * @param BaseAction $action The action to be completed. - * @return bool True if the decoupled authentication is done and the $action was completed or entered one of the - * other states documented on {@link execute()}. - * If false, the {@link TanRequest} inside the action has been updated, which *may* provide new/more - * instructions to the user, though probably it rarely does in practice. + * @return bool True if the decoupled authentication is done and the $action was completed. If false, the + * {@link TanRequest} inside the action has been updated, which *may* provide new/more instructions to the user, + * though probably it rarely does in practice. * @throws CurlException When the connection fails in a layer below the FinTS protocol. * @throws UnexpectedResponseException When the server responds with a valid but unexpected message. * @throws ServerException When the server responds with a (FinTS-encoded) error message, which includes most things @@ -624,99 +530,6 @@ class FinTs return true; } - /** - * For an action where {@link BaseAction::needsPollingWait()} returns `true`, this function polls the server. - * By using {@link persist()}, this can be done asynchronously, i.e., not in the same PHP process as the original - * {@link execute()} call or the previous {@link pollAction()} call. - * - * After this function returns, the `$action` is in any of the same states as after {@link execute()}, see there. In - * particular, it's possible that the long-running operation on the server has not completed yet and thus - * {@link BaseAction::needsPollingWait()} still returns `true`. In practice, actions often require VOP confirmation - * or a TAN after the polling is over, though they can also complete right away. - * In case the action fails, the corresponding exception will be thrown from this function. - * - * @param BaseAction $action The action to be completed. - * @throws CurlException When the connection fails in a layer below the FinTS protocol. - * @throws UnexpectedResponseException When the server responds with a valid but unexpected message. - * @throws ServerException When the server responds with a (FinTS-encoded) error message, which includes most things - * that can go wrong with the action itself, like wrong credentials, invalid IBANs, locked accounts, etc. - * @link FinTS_3.0_Messages_Geschaeftsvorfaelle_VOP_1.01_2025_06_27_FV.pdf - * Section C.10.7.1.1 a) - */ - public function pollAction(BaseAction $action): void - { - $pollingInfo = $action->getPollingInfo(); - if ($pollingInfo === null) { - throw new \InvalidArgumentException('This action is not awaiting polling for a long-running operation'); - } elseif ($pollingInfo instanceof VopPollingInfo) { - // Only send a new HKVPP. - $hkvpp = VopHelper::createHKVPPForPollingRequest($this->bpd, $pollingInfo); - $message = MessageBuilder::create()->add($hkvpp); - - // Execute the request and process the response. - $response = $this->sendMessage($this->buildMessage($message, $this->getSelectedTanMode())); - $action->setPollingInfo(null); - $this->processServerResponse($action, $response, $hkvpp); - } else { - throw new \InvalidArgumentException('Unexpected PollingInfo type: ' . gettype($pollingInfo)); - } - } - - /** - * For an action where {@link BaseAction::needsVopConfirmation()} returns `true`, this function re-submits the - * action with the additional confirmation from the user that they want to execute the transfer(s) after having - * reviewed the information from the {@link VopConfirmationRequest}. - * By using {@link persist()}, this can be done asynchronously, i.e., not in the same PHP process as the original - * {@link execute()} call. - * - * After this function returns, the `$action` is in any of the same states as after {@link execute()}, see there. In - * practice, actions often require a TAN after VOP is confirmed, though they can also complete right away. - * In case the action fails, the corresponding exception will be thrown from this function. - * - * @param BaseAction $action The action to be completed. - * @throws CurlException When the connection fails in a layer below the FinTS protocol. - * @throws UnexpectedResponseException When the server responds with a valid but unexpected message. - * @throws ServerException When the server responds with a (FinTS-encoded) error message, which includes most things - * that can go wrong with the action itself, like wrong credentials, invalid IBANs, locked accounts, etc. - * @link FinTS_3.0_Messages_Geschaeftsvorfaelle_VOP_1.01_2025_06_27_FV.pdf - * Section C.10.7.1.2 a) - */ - public function confirmVop(BaseAction $action): void - { - $vopConfirmationRequest = $action->getVopConfirmationRequest(); - if (!($vopConfirmationRequest instanceof VopConfirmationRequestImpl)) { - throw new \InvalidArgumentException('Unexpected type: ' . gettype($vopConfirmationRequest)); - } - // We need to send the original request again, plus HKVPA as the confirmation. - $requestSegments = $action->getNextRequest($this->bpd, $this->upd); - if (count($requestSegments) === 0) { - throw new \AssertionError('Request unexpectedly became empty upon VOP confirmation'); - } - $message = MessageBuilder::create() - ->add($requestSegments) - ->add(VopHelper::createHKVPAForConfirmation($vopConfirmationRequest)); - - // Add HKTAN for authentication if necessary. - if (!($this->getSelectedTanMode() instanceof NoPsd2TanMode)) { - if (($needTanForSegment = $action->getNeedTanForSegment()) !== null) { - $message->add(HKTANFactory::createProzessvariante2Step1( - $this->requireTanMode(), $this->selectedTanMedium, $needTanForSegment)); - } - } - - // Construct the request message and tell the action about the segment numbers that were assigned. - $request = $this->buildMessage($message, $this->getSelectedTanMode()); // This fills in the segment numbers. - $action->setRequestSegmentNumbers(array_map(function ($segment) { - /* @var BaseSegment $segment */ - return $segment->getSegmentNumber(); - }, $requestSegments)); - - // Execute the request and process the response. - $response = $this->sendMessage($this->buildMessage($message, $this->getSelectedTanMode())); - $action->setVopConfirmationRequest(null); - $this->processServerResponse($action, $response); - } - /** * Closes the session/dialog/connection, if open. This is equivalent to logging out. You should call this function * when you're done with all the actions, but NOT when you're persisting the instance to fulfill the TAN request of @@ -725,7 +538,7 @@ class FinTs * from cached BPD/UPD upon the next {@link login()}, for instance. * @throws ServerException When closing the dialog fails. */ - public function close(): void + public function close() { if ($this->dialogId !== null) { $this->endDialog(); @@ -739,7 +552,7 @@ class FinTs * This can be called by the application using this library when it just restored this FinTs instance from the * persisted format after a long time, during which the session/dialog has most likely expired on the server side. */ - public function forgetDialog(): void + public function forgetDialog() { $this->dialogId = null; } @@ -758,11 +571,9 @@ class FinTs public function getTanModes(): array { $this->ensureTanModesAvailable(); - $result = []; + $result = array(); foreach ($this->allowedTanModes as $tanModeId) { - if (!array_key_exists($tanModeId, $this->bpd->allTanModes)) { - continue; - } + if (!array_key_exists($tanModeId, $this->bpd->allTanModes)) continue; $result[$tanModeId] = $this->bpd->allTanModes[$tanModeId]; } return $result; @@ -813,7 +624,7 @@ class FinTs * must be the value returned from {@link TanMedium::getName()} for one of the TAN media supported with that TAN * mode. Use {@link getTanMedia()} to obtain a list of possible TAN media options. */ - public function selectTanMode($tanMode, $tanMedium = null): void + public function selectTanMode($tanMode, $tanMedium = null) { if (!is_int($tanMode) && !($tanMode instanceof TanMode)) { throw new \InvalidArgumentException('tanMode must be an int or a TanMode'); @@ -853,7 +664,7 @@ class FinTs * @throws UnexpectedResponseException When the server does not send the BPD or close the dialog properly. * @throws ServerException When the server resopnds with an error. */ - private function ensureBpdAvailable(): void + private function ensureBpdAvailable() { if ($this->bpd !== null) { return; // Nothing to do. @@ -900,7 +711,7 @@ class FinTs * like it should according to the protocol, or when the dialog is not closed properly. * @throws ServerException When the server responds with an error. */ - private function ensureTanModesAvailable(): void + private function ensureTanModesAvailable() { if ($this->allowedTanModes === null) { $this->ensureBpdAvailable(); @@ -919,7 +730,7 @@ class FinTs * dialog is not closed properly. * @throws ServerException When the server responds with an error. */ - private function ensureSynchronized(): void + private function ensureSynchronized() { if ($this->kundensystemId === null) { $this->ensureBpdAvailable(); @@ -1009,7 +820,7 @@ class FinTs /** * Closes the physical connection, if necessary. */ - private function disconnect(): void + private function disconnect() { if ($this->connection !== null) { $this->connection->disconnect(); @@ -1023,7 +834,7 @@ class FinTs * @param Message $fakeResponseMessage A messsage that contains the response segments for this action. * @throws UnexpectedResponseException When the server responded with a valid but unexpected message. */ - private function processActionResponse(BaseAction $action, Message $fakeResponseMessage): void + private function processActionResponse(BaseAction $action, Message $fakeResponseMessage) { $action->processResponse($fakeResponseMessage); if ($action instanceof DialogInitialization) { @@ -1053,7 +864,7 @@ class FinTs * properly. * @throws ServerException When the server responds with an error. */ - private function executeWeakDialogInitialization(?string $hktanRef): void + private function executeWeakDialogInitialization(?string $hktanRef) { if ($this->dialogId !== null) { throw new \RuntimeException('Cannot init another dialog.'); @@ -1094,7 +905,7 @@ class FinTs * @throws ServerException When the server responds with an error instead of closing the dialog. This means that * the connection is tainted and can probably not be used for another dialog. */ - protected function endDialog(bool $isAnonymous = false): void + protected function endDialog(bool $isAnonymous = false) { if ($this->connection === null) { $this->dialogId = null; @@ -1132,7 +943,7 @@ class FinTs * @param MessageBuilder $message The message to be built. * @param TanMode|null $tanMode Optionally a TAN mode that will be used when sending this message, defaults to 999 * (single step). - * @param string|null $tan Optionally a TAN to sign this message with. + * @param string|null Optionally a TAN to sign this message with. * @return Message The built message. */ private function buildMessage(MessageBuilder $message, ?TanMode $tanMode = null, ?string $tan = null): Message diff --git a/vendor/nemiah/php-fints/lib/Fhp/MT535/MT535.php b/vendor/nemiah/php-fints/lib/Fhp/MT535/MT535.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/MT940/Dialect/PostbankMT940.php b/vendor/nemiah/php-fints/lib/Fhp/MT940/Dialect/PostbankMT940.php old mode 100644 new mode 100755 index 826c16f..b7d1e91 --- a/vendor/nemiah/php-fints/lib/Fhp/MT940/Dialect/PostbankMT940.php +++ b/vendor/nemiah/php-fints/lib/Fhp/MT940/Dialect/PostbankMT940.php @@ -8,6 +8,7 @@ class PostbankMT940 extends MT940 { public const DIALECT_ID = 'https://hbci.postbank.de/banking/hbci.do'; + /** {@inheritdoc} */ public function extractStructuredDataFromRemittanceLines($descriptionLines, string &$gvc, array &$rawLines, array $transaction): array { // z.B bei Zinsen o.ä. ist alles leer diff --git a/vendor/nemiah/php-fints/lib/Fhp/MT940/Dialect/SpardaMT940.php b/vendor/nemiah/php-fints/lib/Fhp/MT940/Dialect/SpardaMT940.php old mode 100644 new mode 100755 index 24b873b..f1f70f4 --- a/vendor/nemiah/php-fints/lib/Fhp/MT940/Dialect/SpardaMT940.php +++ b/vendor/nemiah/php-fints/lib/Fhp/MT940/Dialect/SpardaMT940.php @@ -8,6 +8,7 @@ class SpardaMT940 extends MT940 { public const DIALECT_ID = 'https://fints.bankingonline.de/fints/FinTs30PinTanHttpGate'; + /** {@inheritdoc} */ public function extractStructuredDataFromRemittanceLines($descriptionLines, string &$gvc, array &$rawLines, array $transaction): array { $otherInfo = []; diff --git a/vendor/nemiah/php-fints/lib/Fhp/MT940/MT940.php b/vendor/nemiah/php-fints/lib/Fhp/MT940/MT940.php old mode 100644 new mode 100755 index 9bf24f7..32c4b03 --- a/vendor/nemiah/php-fints/lib/Fhp/MT940/MT940.php +++ b/vendor/nemiah/php-fints/lib/Fhp/MT940/MT940.php @@ -142,8 +142,8 @@ class MT940 $soaDate = $this->getDate(substr($day[$i], 1, 6)); if (isset($result[$soaDate])) { - // $result[$soaDate] = ['end_balance' => []]; - + #$result[$soaDate] = ['end_balance' => []]; + $amount = str_replace(',', '.', substr($day[$i], 10, -1)); $cdMark = substr($day[$i], 0, 1); if ($cdMark == 'C') { diff --git a/vendor/nemiah/php-fints/lib/Fhp/MT940/MT940Exception.php b/vendor/nemiah/php-fints/lib/Fhp/MT940/MT940Exception.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/Account.php b/vendor/nemiah/php-fints/lib/Fhp/Model/Account.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/FlickerTan/DataElement.php b/vendor/nemiah/php-fints/lib/Fhp/Model/FlickerTan/DataElement.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/FlickerTan/StartCode.php b/vendor/nemiah/php-fints/lib/Fhp/Model/FlickerTan/StartCode.php old mode 100644 new mode 100755 index bcce438..faa0893 --- a/vendor/nemiah/php-fints/lib/Fhp/Model/FlickerTan/StartCode.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Model/FlickerTan/StartCode.php @@ -68,11 +68,17 @@ class StartCode extends DataElement $this->headerHighBit = '1'; } + /** + * {@inheritDoc} + */ public function toHex(): string { return $this->getHeaderHex() . implode('', $this->controlBytes) . $this->getDataHex(); } + /** + * {@inheritDoc} + */ public function getLuhnChecksum(): int { $luhn = 0; @@ -83,6 +89,9 @@ class StartCode extends DataElement return $luhn; } + /** + * {@inheritDoc} + */ public function __debugInfo(): ?array { return [ diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/FlickerTan/SvgRenderer.php b/vendor/nemiah/php-fints/lib/Fhp/Model/FlickerTan/SvgRenderer.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/FlickerTan/TanRequestChallengeFlicker.php b/vendor/nemiah/php-fints/lib/Fhp/Model/FlickerTan/TanRequestChallengeFlicker.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/NoPsd2TanMode.php b/vendor/nemiah/php-fints/lib/Fhp/Model/NoPsd2TanMode.php old mode 100644 new mode 100755 index c6ab6f6..223722f --- a/vendor/nemiah/php-fints/lib/Fhp/Model/NoPsd2TanMode.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Model/NoPsd2TanMode.php @@ -16,11 +16,13 @@ final class NoPsd2TanMode implements TanMode { public const ID = -1; + /** {@inheritdoc} */ public function getId(): int { return self::ID; } + /** {@inheritdoc} */ public function getName(): string { return 'No PSD2/TANs supported'; @@ -31,76 +33,91 @@ final class NoPsd2TanMode implements TanMode return false; } + /** {@inheritdoc} */ public function isDecoupled(): bool { return false; } + /** {@inheritdoc} */ public function getChallengeLabel(): string { return ''; } + /** {@inheritdoc} */ public function getMaxChallengeLength(): int { return 0; } + /** {@inheritdoc} */ public function getMaxTanLength(): int { return 0; } + /** {@inheritdoc} */ public function getTanFormat(): int { return 0; } + /** {@inheritdoc} */ public function needsTanMedium(): bool { return false; } + /** {@inheritdoc} */ public function getSmsAbbuchungskontoErforderlich(): bool { return false; } + /** {@inheritdoc} */ public function getAuftraggeberkontoErforderlich(): bool { return false; } + /** {@inheritdoc} */ public function getChallengeKlasseErforderlich(): bool { return false; } + /** {@inheritdoc} */ public function getAntwortHhdUcErforderlich(): bool { return false; } + /** {@inheritdoc} */ public function getMaxDecoupledChecks(): int { throw new \RuntimeException('Only allowed for decoupled TAN modes'); } + /** {@inheritdoc} */ public function getFirstDecoupledCheckDelaySeconds(): int { throw new \RuntimeException('Only allowed for decoupled TAN modes'); } + /** {@inheritdoc} */ public function getPeriodicDecoupledCheckDelaySeconds(): int { throw new \RuntimeException('Only allowed for decoupled TAN modes'); } + /** {@inheritdoc} */ public function allowsManualConfirmation(): bool { throw new \RuntimeException('Only allowed for decoupled TAN modes'); } + /** {@inheritdoc} */ public function allowsAutomatedPolling(): bool { throw new \RuntimeException('Only allowed for decoupled TAN modes'); diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/PollingInfo.php b/vendor/nemiah/php-fints/lib/Fhp/Model/PollingInfo.php deleted file mode 100644 index 68ff71f..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Model/PollingInfo.php +++ /dev/null @@ -1,23 +0,0 @@ -setStartBalance((float) $statement['start_balance']['amount']); } if (isset($statement['end_balance'])) { - $statementModel->setEndBalance((float) $statement['end_balance']['amount'] * ($statement['end_balance']['credit_debit'] == MT940::CD_CREDIT ? 1 : -1)); + $statementModel->setEndBalance((float) $statement['end_balance']['amount'] * ($statement["end_balance"]['credit_debit'] == MT940::CD_CREDIT ? 1 : -1)); } if (isset($statement['start_balance']['credit_debit'])) { $statementModel->setCreditDebit($statement['start_balance']['credit_debit']); diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/StatementOfAccount/Transaction.php b/vendor/nemiah/php-fints/lib/Fhp/Model/StatementOfAccount/Transaction.php old mode 100644 new mode 100755 index af3151f..1483a30 --- a/vendor/nemiah/php-fints/lib/Fhp/Model/StatementOfAccount/Transaction.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Model/StatementOfAccount/Transaction.php @@ -8,28 +8,86 @@ class Transaction public const CD_CREDIT = 'credit'; public const CD_DEBIT = 'debit'; - protected ?\DateTime $bookingDate = null; - protected ?\DateTime $valutaDate = null; - protected float $amount; - protected string $creditDebit; - protected bool $isStorno; - protected string $bookingCode; - protected string $bookingText; - protected string $description1; - protected string $description2; + /** + * @var \DateTime|null + */ + protected $bookingDate; + + /** + * @var \DateTime|null + */ + protected $valutaDate; + + /** + * @var float + */ + protected $amount; + + /** + * @var string + */ + protected $creditDebit; + + /** + * @var bool + */ + protected $isStorno; + + /** + * @var string + */ + protected $bookingCode; + + /** + * @var string + */ + protected $bookingText; + + /** + * @var string + */ + protected $description1; + + /** + * @var string + */ + protected $description2; /** * Array keys are identifiers like "SVWZ" for the main description. * @var string[] */ - protected array $structuredDescription; + protected $structuredDescription; - protected string $bankCode; - protected string $accountNumber; - protected string $name; - protected bool $booked; - protected int $pn; - protected int $textKeyAddition; + /** + * @var string + */ + protected $bankCode; + + /** + * @var string + */ + protected $accountNumber; + + /** + * @var string + */ + protected $name; + + /** + * @var bool + */ + protected $booked; + + /** + * @var int + */ + protected $pn; + + /** + * @var int + */ + protected $textKeyAddition; /** * Get booking date. @@ -63,9 +121,10 @@ class Transaction * * @return $this */ - public function setBookingDate(?\DateTime $date = null): static + public function setBookingDate(?\DateTime $date = null) { $this->bookingDate = $date; + return $this; } @@ -74,9 +133,10 @@ class Transaction * * @return $this */ - public function setValutaDate(?\DateTime $date = null): static + public function setValutaDate(?\DateTime $date = null) { $this->valutaDate = $date; + return $this; } @@ -93,9 +153,10 @@ class Transaction * * @return $this */ - public function setBooked(bool $booked): static + public function setBooked(bool $booked) { $this->booked = $booked; + return $this; } @@ -104,9 +165,10 @@ class Transaction * * @return $this */ - public function setAmount(float $amount): static + public function setAmount(float $amount) { - $this->amount = $amount; + $this->amount = (float) $amount; + return $this; } @@ -123,9 +185,10 @@ class Transaction * * @return $this */ - public function setCreditDebit(string $creditDebit): static + public function setCreditDebit(string $creditDebit) { $this->creditDebit = $creditDebit; + return $this; } @@ -142,9 +205,10 @@ class Transaction * * @return $this */ - public function setIsStorno(bool $isStorno): static + public function setIsStorno(bool $isStorno) { $this->isStorno = $isStorno; + return $this; } @@ -161,9 +225,10 @@ class Transaction * * @return $this */ - public function setBookingCode(string $bookingCode): static + public function setBookingCode(string $bookingCode) { - $this->bookingCode = $bookingCode; + $this->bookingCode = (string) $bookingCode; + return $this; } @@ -180,9 +245,10 @@ class Transaction * * @return $this */ - public function setBookingText(string $bookingText): static + public function setBookingText(string $bookingText) { - $this->bookingText = $bookingText; + $this->bookingText = (string) $bookingText; + return $this; } @@ -199,9 +265,10 @@ class Transaction * * @return $this */ - public function setDescription1(string $description1): static + public function setDescription1(string $description1) { - $this->description1 = $description1; + $this->description1 = (string) $description1; + return $this; } @@ -218,9 +285,10 @@ class Transaction * * @return $this */ - public function setDescription2(string $description2): static + public function setDescription2(string $description2) { - $this->description2 = $description2; + $this->description2 = (string) $description2; + return $this; } @@ -238,9 +306,10 @@ class Transaction * Set structuredDescription * * @param string[] $structuredDescription + * * @return $this */ - public function setStructuredDescription(array $structuredDescription): static + public function setStructuredDescription(array $structuredDescription) { $this->structuredDescription = $structuredDescription; @@ -284,9 +353,10 @@ class Transaction * * @return $this */ - public function setBankCode(string $bankCode): static + public function setBankCode(string $bankCode) { - $this->bankCode = $bankCode; + $this->bankCode = (string) $bankCode; + return $this; } @@ -303,9 +373,10 @@ class Transaction * * @return $this */ - public function setAccountNumber(string $accountNumber): static + public function setAccountNumber(string $accountNumber) { - $this->accountNumber = $accountNumber; + $this->accountNumber = (string) $accountNumber; + return $this; } @@ -330,9 +401,10 @@ class Transaction * * @return $this */ - public function setName(string $name): static + public function setName(string $name) { - $this->name = $name; + $this->name = (string) $name; + return $this; } @@ -350,7 +422,7 @@ class Transaction * @param int|mixed $nr Will be parsed to an int. * @return $this */ - public function setPN($nr): static + public function setPN($nr) { $this->pn = intval($nr); return $this; @@ -370,7 +442,7 @@ class Transaction * @param int|mixed $textKeyAddition Will be parsed to an int. * @return $this */ - public function setTextKeyAddition($textKeyAddition): static + public function setTextKeyAddition($textKeyAddition) { $this->textKeyAddition = intval($textKeyAddition); return $this; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/StatementOfHoldings/Holding.php b/vendor/nemiah/php-fints/lib/Fhp/Model/StatementOfHoldings/Holding.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/StatementOfHoldings/StatementOfHoldings.php b/vendor/nemiah/php-fints/lib/Fhp/Model/StatementOfHoldings/StatementOfHoldings.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/TanMedium.php b/vendor/nemiah/php-fints/lib/Fhp/Model/TanMedium.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/TanMode.php b/vendor/nemiah/php-fints/lib/Fhp/Model/TanMode.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/TanRequest.php b/vendor/nemiah/php-fints/lib/Fhp/Model/TanRequest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/TanRequestChallengeImage.php b/vendor/nemiah/php-fints/lib/Fhp/Model/TanRequestChallengeImage.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/VopConfirmationRequest.php b/vendor/nemiah/php-fints/lib/Fhp/Model/VopConfirmationRequest.php deleted file mode 100644 index af2e9ca..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Model/VopConfirmationRequest.php +++ /dev/null @@ -1,25 +0,0 @@ -vopId = $vopId; - $this->expiration = $expiration; - $this->informationForUser = $informationForUser; - $this->verificationResult = $verificationResult; - $this->verificationNotApplicableReason = $verificationNotApplicableReason; - } - - public function getVopId(): Bin - { - return $this->vopId; - } - - public function getExpiration(): ?\DateTime - { - return $this->expiration; - } - - public function getInformationForUser(): ?string - { - return $this->informationForUser; - } - - public function getVerificationResult(): ?string - { - return $this->verificationResult; - } - - public function getVerificationNotApplicableReason(): ?string - { - return $this->verificationNotApplicableReason; - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/VopPollingInfo.php b/vendor/nemiah/php-fints/lib/Fhp/Model/VopPollingInfo.php deleted file mode 100644 index 903b345..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Model/VopPollingInfo.php +++ /dev/null @@ -1,50 +0,0 @@ -aufsetzpunkt = $aufsetzpunkt; - $this->pollingId = $pollingId; - $this->nextAttemptInSeconds = $nextAttemptInSeconds; - } - - public function getAufsetzpunkt(): string - { - return $this->aufsetzpunkt; - } - - public function getPollingId(): ?Bin - { - return $this->pollingId; - } - - public function getNextAttemptInSeconds(): ?int - { - return $this->nextAttemptInSeconds; - } - - public function getInformationForUser(): string - { - return 'The bank is verifying payee information...'; - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Model/VopVerificationResult.php b/vendor/nemiah/php-fints/lib/Fhp/Model/VopVerificationResult.php deleted file mode 100644 index f29f569..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Model/VopVerificationResult.php +++ /dev/null @@ -1,51 +0,0 @@ - null, - 'RCVC' => self::CompletedFullMatch, - 'RVMC' => self::CompletedCloseMatch, - 'RVNM' => self::CompletedNoMatch, - 'RVCM' => self::CompletedPartialMatch, - 'RVNA' => self::NotApplicable, - default => throw new UnexpectedResponseException("Unexpected VOP result code: $codeFromBank"), - }; - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Options/Credentials.php b/vendor/nemiah/php-fints/lib/Fhp/Options/Credentials.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Options/FinTsOptions.php b/vendor/nemiah/php-fints/lib/Fhp/Options/FinTsOptions.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Options/SanitizingLogger.php b/vendor/nemiah/php-fints/lib/Fhp/Options/SanitizingLogger.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/PaginateableAction.php b/vendor/nemiah/php-fints/lib/Fhp/PaginateableAction.php old mode 100644 new mode 100755 index 7144f30..b01d480 --- a/vendor/nemiah/php-fints/lib/Fhp/PaginateableAction.php +++ b/vendor/nemiah/php-fints/lib/Fhp/PaginateableAction.php @@ -6,6 +6,7 @@ use Fhp\Protocol\BPD; use Fhp\Protocol\Message; use Fhp\Protocol\UnexpectedResponseException; use Fhp\Protocol\UPD; +use Fhp\Segment\BaseSegment; use Fhp\Segment\HIRMS\Rueckmeldungscode; use Fhp\Segment\Paginateable; @@ -18,20 +19,23 @@ use Fhp\Segment\Paginateable; abstract class PaginateableAction extends BaseAction { /** - * Stores the request created by BaseAction::getNextRequest to be reused in case the bank wants + * @var BaseSegment[] Stores the request created by BaseAction::getNextRequest to be reused in case the bank wants * to split the result over multiple pages e.g. request/response pairs. This avoids the need for {@link BPD} to be * available for paginated requests. */ - protected ?array $requestSegments = null; + protected $requestSegments; /** * If set, the last response from the server regarding this action indicated that there are more results to be * fetched using this pagination token. This is called "Aufsetzpunkt" in the specification. + * @var string|null */ - protected ?string $paginationToken = null; + protected $paginationToken; /** * @deprecated Beginning from PHP7.4 __unserialize is used for new generated strings, then this method is only used for previously generated strings - remove after May 2023 + * + * {@inheritdoc} */ public function serialize(): string { @@ -49,6 +53,8 @@ abstract class PaginateableAction extends BaseAction /** * @deprecated Beginning from PHP7.4 __unserialize is used for new generated strings, then this method is only used for previously generated strings - remove after May 2023 + * + * {@inheritdoc} */ public function unserialize($serialized) { @@ -76,9 +82,10 @@ abstract class PaginateableAction extends BaseAction return !$this->isDone() && $this->paginationToken !== null; } + /** {@inheritdoc} */ public function processResponse(Message $response) { - if (($pagination = $response->findRueckmeldung(Rueckmeldungscode::AUFSETZPUNKT)) !== null) { + if (($pagination = $response->findRueckmeldung(Rueckmeldungscode::PAGINATION)) !== null) { if (count($pagination->rueckmeldungsparameter) !== 1) { throw new UnexpectedResponseException("Unexpected pagination request: $pagination"); } @@ -90,6 +97,7 @@ abstract class PaginateableAction extends BaseAction } } + /** {@inheritdoc} */ public function getNextRequest(?BPD $bpd, ?UPD $upd) { if ($this->requestSegments === null) { diff --git a/vendor/nemiah/php-fints/lib/Fhp/Protocol/ActionIncompleteException.php b/vendor/nemiah/php-fints/lib/Fhp/Protocol/ActionIncompleteException.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Protocol/ActionPendingException.php b/vendor/nemiah/php-fints/lib/Fhp/Protocol/ActionPendingException.php deleted file mode 100644 index 9424dc1..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Protocol/ActionPendingException.php +++ /dev/null @@ -1,26 +0,0 @@ -pollingInfo = $pollingInfo; - } - - public function getPollingInfo(): PollingInfo - { - return $this->pollingInfo; - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Protocol/BPD.php b/vendor/nemiah/php-fints/lib/Fhp/Protocol/BPD.php old mode 100644 new mode 100755 index 5241ab4..de8caf4 --- a/vendor/nemiah/php-fints/lib/Fhp/Protocol/BPD.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Protocol/BPD.php @@ -10,7 +10,6 @@ use Fhp\Segment\HIBPA\HIBPAv3; use Fhp\Segment\HIPINS\HIPINSv1; use Fhp\Segment\SegmentInterface; use Fhp\Segment\TAN\HITANS; -use Fhp\Segment\VPP\HIVPPSv1; /** * Segmentfolge: Bankparameterdaten (Version 3) @@ -153,28 +152,6 @@ class BPD return null; } - /** - * @param SegmentInterface[] $requestSegments The segments that shall be sent to the bank. - * @return string|null Identifier of the (first) segment that requires Verification of Payee according to HIPINS, or - * null if none of the segments require verification. - */ - public function vopRequiredForRequest(array $requestSegments): ?string - { - /** @var HIVPPSv1 $hivpps */ - $hivpps = $this->getLatestSupportedParameters('HIVPPS'); - $vopRequiredTypes = $hivpps?->parameter?->vopPflichtigerZahlungsverkehrsauftrag; - if ($vopRequiredTypes === null) { - return null; - } - - foreach ($requestSegments as $segment) { - if (in_array($segment->getName(), $vopRequiredTypes)) { - return $segment->getName(); - } - } - return null; - } - /** * @return bool Whether the BPD indicates that the bank supports PSD2. */ diff --git a/vendor/nemiah/php-fints/lib/Fhp/Protocol/DialogInitialization.php b/vendor/nemiah/php-fints/lib/Fhp/Protocol/DialogInitialization.php old mode 100644 new mode 100755 index f31fdf9..3e07aec --- a/vendor/nemiah/php-fints/lib/Fhp/Protocol/DialogInitialization.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Protocol/DialogInitialization.php @@ -143,7 +143,7 @@ class DialogInitialization extends BaseAction $this->hktanRef, $this->kundensystemId, $this->messageNumber, - $this->dialogId, + $this->dialogId ) = $serialized; is_array($parentSerialized) ? @@ -151,6 +151,7 @@ class DialogInitialization extends BaseAction parent::unserialize($parentSerialized); } + /** {@inheritdoc} */ protected function createRequest(BPD $bpd, ?UPD $upd) { throw new \AssertionError('DialogInitialization::createRequest should not be used.'); diff --git a/vendor/nemiah/php-fints/lib/Fhp/Protocol/GetTanMedia.php b/vendor/nemiah/php-fints/lib/Fhp/Protocol/GetTanMedia.php old mode 100644 new mode 100755 index 4bb2a75..da0f32f --- a/vendor/nemiah/php-fints/lib/Fhp/Protocol/GetTanMedia.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Protocol/GetTanMedia.php @@ -17,6 +17,7 @@ class GetTanMedia extends BaseAction /** @var TanMediumListe[]|null */ private $tanMedia; + /** {@inheritdoc} */ protected function createRequest(BPD $bpd, ?UPD $upd) { // Prepare the HKTAB request. @@ -31,6 +32,7 @@ class GetTanMedia extends BaseAction } } + /** {@inheritdoc} */ public function processResponse(Message $response) { parent::processResponse($response); diff --git a/vendor/nemiah/php-fints/lib/Fhp/Protocol/Message.php b/vendor/nemiah/php-fints/lib/Fhp/Protocol/Message.php old mode 100644 new mode 100755 index b4babcf..6d18b75 --- a/vendor/nemiah/php-fints/lib/Fhp/Protocol/Message.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Protocol/Message.php @@ -190,17 +190,12 @@ class Message /** * @param int $code The response code to search for. - * @param ?int $requestSegmentNumber If set, only consider Rueckmeldungen that pertain to this request segment. * @return Rueckmeldung|null The corresponding Rueckmeldung instance, or null if not found. */ - public function findRueckmeldung(int $code, ?int $requestSegmentNumber = null): ?Rueckmeldung + public function findRueckmeldung(int $code): ?Rueckmeldung { foreach ($this->plainSegments as $segment) { - if ( - $segment instanceof RueckmeldungContainer && ( - $requestSegmentNumber === null || $segment->segmentkopf->bezugselement === $requestSegmentNumber - ) - ) { + if ($segment instanceof RueckmeldungContainer) { $rueckmeldung = $segment->findRueckmeldung($code); if ($rueckmeldung !== null) { return $rueckmeldung; @@ -222,29 +217,16 @@ class Message return $rueckmeldungen; } - /** - * @param int $requestSegmentNumber Only consider Rueckmeldungen that pertain to this request segment. - * @return int[] The codes of all the Rueckmeldung instances matching the request segment. - */ - public function findRueckmeldungscodesForReferenceSegment(int $requestSegmentNumber): array - { - $codes = []; - foreach ($this->plainSegments as $segment) { - if ($segment instanceof RueckmeldungContainer && $segment->segmentkopf->bezugselement === $requestSegmentNumber) { - foreach ($segment->getAllRueckmeldungen() as $rueckmeldung) { - $codes[] = $rueckmeldung->rueckmeldungscode; - } - } - } - return $codes; - } - /** * @return string The HBCI/FinTS wire format for this message, ISO-8859-1 encoded. */ public function serialize(): string { - return Serializer::serializeSegments($this->wrapperSegments); + $result = ''; + foreach ($this->wrapperSegments as $segment) { + $result .= Serializer::serializeSegment($segment); + } + return $result; } /** @@ -318,16 +300,14 @@ class Message $segments = Parser::parseSegments($rawMessage); // Message header and footer must always be there, or something went badly wrong. + if (!($segments[0] instanceof HNHBKv3)) { + throw new \InvalidArgumentException("Expected first segment to be HNHBK: $rawMessage"); + } + if (!($segments[count($segments) - 1] instanceof HNHBSv1)) { + throw new \InvalidArgumentException("Expected last segment to be HNHBS: $rawMessage"); + } $result->header = $segments[0]; $result->footer = $segments[count($segments) - 1]; - if (!($result->header instanceof HNHBKv3)) { - $actual = $result->header->getName(); - throw new \InvalidArgumentException("Expected first segment to be HNHBK, but got $actual: $rawMessage"); - } - if (!($result->footer instanceof HNHBSv1)) { - $actual = $result->footer->getName(); - throw new \InvalidArgumentException("Expected last segment to be HNHBS, but got $actual: $rawMessage"); - } // Check if there's an encryption header and "encrypted" data. // Section B.8 specifies that there are exactly 4 segments: HNHBK, HNVSK, HNVSD, HNHBS. @@ -371,7 +351,7 @@ class Message * @param int $segmentNumber The number for the *first* segment, subsequent segment get the subsequent integers. * @return BaseSegment[] The same array, for chaining. */ - public static function setSegmentNumbers(array $segments, int $segmentNumber): array + private static function setSegmentNumbers(array $segments, int $segmentNumber): array { foreach ($segments as $segment) { $segment->segmentkopf->segmentnummer = $segmentNumber; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Protocol/MessageBuilder.php b/vendor/nemiah/php-fints/lib/Fhp/Protocol/MessageBuilder.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Protocol/ServerException.php b/vendor/nemiah/php-fints/lib/Fhp/Protocol/ServerException.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Protocol/TanRequiredException.php b/vendor/nemiah/php-fints/lib/Fhp/Protocol/TanRequiredException.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Protocol/UPD.php b/vendor/nemiah/php-fints/lib/Fhp/Protocol/UPD.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Protocol/UnexpectedResponseException.php b/vendor/nemiah/php-fints/lib/Fhp/Protocol/UnexpectedResponseException.php old mode 100644 new mode 100755 index 02b183c..daea608 --- a/vendor/nemiah/php-fints/lib/Fhp/Protocol/UnexpectedResponseException.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Protocol/UnexpectedResponseException.php @@ -8,7 +8,7 @@ namespace Fhp\Protocol; */ class UnexpectedResponseException extends \RuntimeException { - public function __construct(string $message, int $code = 0, ?\Exception $previous = null) + public function __construct(string $message, int $code = 0, \Exception $previous = null) { parent::__construct($message, $code, $previous); } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Protocol/VopConfirmationRequiredException.php b/vendor/nemiah/php-fints/lib/Fhp/Protocol/VopConfirmationRequiredException.php deleted file mode 100644 index 03ec77b..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Protocol/VopConfirmationRequiredException.php +++ /dev/null @@ -1,26 +0,0 @@ -vopConfirmationRequest = $vopConfirmationRequest; - } - - public function getVopConfirmationRequest(): VopConfirmationRequest - { - return $this->vopConfirmationRequest; - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/AUB/HIAUBSv9.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/AUB/HIAUBSv9.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/AUB/HKAUBv9.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/AUB/HKAUBv9.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/AUB/ParameterAuslandsueberweisungV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/AUB/ParameterAuslandsueberweisungV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/AnonymousSegment.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/AnonymousSegment.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BME/HIBMESv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BME/HIBMESv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BME/HIBMESv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BME/HIBMESv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BME/HKBMEv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BME/HKBMEv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BME/HKBMEv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BME/HKBMEv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BME/ParameterTerminierteSEPAFirmenSammellastschriftEinreichenV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BME/ParameterTerminierteSEPAFirmenSammellastschriftEinreichenV1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BME/ParameterTerminierteSEPAFirmenSammellastschriftEinreichenV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BME/ParameterTerminierteSEPAFirmenSammellastschriftEinreichenV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BSE/HIBSESv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BSE/HIBSESv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BSE/HIBSESv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BSE/HIBSESv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BSE/HKBSEv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BSE/HKBSEv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BSE/HKBSEv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BSE/HKBSEv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BSE/ParameterTerminierteSEPAFirmenEinzellastschriftEinreichenV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BSE/ParameterTerminierteSEPAFirmenEinzellastschriftEinreichenV1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BSE/ParameterTerminierteSEPAFirmenEinzellastschriftEinreichenV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BSE/ParameterTerminierteSEPAFirmenEinzellastschriftEinreichenV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BaseDeg.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BaseDeg.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BaseDescriptor.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BaseDescriptor.php old mode 100644 new mode 100755 index b7db851..1234721 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/BaseDescriptor.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/BaseDescriptor.php @@ -32,11 +32,9 @@ abstract class BaseDescriptor protected function __construct(\ReflectionClass $clazz) { // Use reflection to map PHP class fields to elements in the segment/Deg. + $implicitIndex = true; $nextIndex = 0; foreach (static::enumerateProperties($clazz) as $property) { - if ($nextIndex === null) { - throw new \InvalidArgumentException("Disallowed property $property after an @Unlimited field"); - } $docComment = $property->getDocComment() ?: ''; if (static::getBoolAnnotation('Ignore', $docComment)) { continue; // Skip @Ignore-d propeties. @@ -46,35 +44,22 @@ abstract class BaseDescriptor $descriptor = new ElementDescriptor(); $descriptor->field = $property->getName(); $maxCount = static::getIntAnnotation('Max', $docComment); - $unlimitedCount = static::getBoolAnnotation('Unlimited', $docComment); if ($type = static::getVarAnnotation($docComment)) { if (str_ends_with($type, '|null')) { // Nullable field $descriptor->optional = true; $type = substr($type, 0, -5); } if (str_ends_with($type, '[]')) { // Array/repeated field - $type = substr($type, 0, -2); - if ($unlimitedCount) { - $descriptor->repeated = PHP_INT_MAX; - // A repeated field of unlimited size cannot be followed by anything, because it would not be - // clear which of the following values still belong to the repeated field vs to the next field. - $nextIndex = null; - } elseif ($maxCount !== null) { - $descriptor->repeated = $maxCount; - // If there's another field value after this repeated field, then a serialized message will - // contain placeholders (i.e. empty field values separated by possibly hundreds of `+`) to fill - // up to the repeated field's maximum length, after which the next message continues at the next - // index. - $nextIndex += $maxCount; - } else { - throw new \InvalidArgumentException( - "Repeated property $property needs @Max(.) or (rarely) @Unlimited annotation" - ); + if ($maxCount === null) { + throw new \InvalidArgumentException("Repeated property $property needs @Max() annotation"); } + $descriptor->repeated = $maxCount; + $type = substr($type, 0, -2); + // If a repeated field is followed by anything at all, there will be an empty entry for each possible + // repeated value (in extreme cases, there can be hundreds of consecutive `+`, for instance). + $nextIndex += $maxCount; } elseif ($maxCount !== null) { throw new \InvalidArgumentException("@Max() annotation not recognized on single $property"); - } elseif ($unlimitedCount) { - throw new \InvalidArgumentException("@Unlimited annotation not recognized on single $property"); } else { ++$nextIndex; // Singular field, so the index advances by 1. } @@ -105,7 +90,7 @@ abstract class BaseDescriptor throw new \InvalidArgumentException("No fields found in $clazz->name"); } ksort($this->elements); // Make sure elements are parsed in wire-format order. - $this->maxIndex = $nextIndex === null ? PHP_INT_MAX : $nextIndex - 1; + $this->maxIndex = $nextIndex - 1; } /** diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BaseGeschaeftsvorfallparameter.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BaseGeschaeftsvorfallparameter.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BaseGeschaeftsvorfallparameterOld.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BaseGeschaeftsvorfallparameterOld.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/BaseSegment.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/BaseSegment.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CAZ/GebuchteCamtUmsaetze.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CAZ/GebuchteCamtUmsaetze.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CAZ/HICAZSv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CAZ/HICAZSv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CAZ/HICAZv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CAZ/HICAZv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CAZ/HKCAZv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CAZ/HKCAZv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CAZ/ParameterKontoumsaetzeCamt.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CAZ/ParameterKontoumsaetzeCamt.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CAZ/UnterstuetzteCamtMessages.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CAZ/UnterstuetzteCamtMessages.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CCM/HICCMSv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CCM/HICCMSv1.php old mode 100644 new mode 100755 index 3b2c460..f3d23be --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/CCM/HICCMSv1.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/CCM/HICCMSv1.php @@ -14,7 +14,7 @@ class HICCMSv1 extends BaseGeschaeftsvorfallparameter { public ParameterSEPASammelueberweisungV1 $parameter; - public function getParameter(): ParameterSEPASammelueberweisungV1 + public function getParameter() { return $this->parameter; } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CCM/HKCCMv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CCM/HKCCMv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CCM/ParameterSEPASammelueberweisungV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CCM/ParameterSEPASammelueberweisungV1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CCS/HICCSSv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CCS/HICCSSv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CCS/HKCCSv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CCS/HKCCSv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CME/HICMESv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CME/HICMESv1.php old mode 100644 new mode 100755 index 582afd0..833d18b --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/CME/HICMESv1.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/CME/HICMESv1.php @@ -13,9 +13,4 @@ use Fhp\Segment\BaseGeschaeftsvorfallparameter; class HICMESv1 extends BaseGeschaeftsvorfallparameter { public ParameterTerminierteSEPASammelueberweisungEinreichenV1 $parameter; - - public function getParameter(): ParameterTerminierteSEPASammelueberweisungEinreichenV1 - { - return $this->parameter; - } } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CME/HICMEv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CME/HICMEv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CME/HKCMEv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CME/HKCMEv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CME/ParameterTerminierteSEPASammelueberweisungEinreichenV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CME/ParameterTerminierteSEPASammelueberweisungEinreichenV1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CSE/HICSESv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CSE/HICSESv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CSE/HICSEv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CSE/HICSEv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CSE/HKCSEv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CSE/HKCSEv1.php old mode 100644 new mode 100755 index 515e3a3..5861cde --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/CSE/HKCSEv1.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/CSE/HKCSEv1.php @@ -17,7 +17,7 @@ class HKCSEv1 extends BaseSegment public \Fhp\Segment\Common\Kti $kontoverbindungInternational; /** Max length: 256 */ public string $sepaDescriptor; - /** + /** * The PAIN message in XML format. * HISPAS informs which XML schemas are allowed. * The field must be 1999-01-01. diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/CSE/ParameterTerminierteSEPAUeberweisungEinreichenV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/CSE/ParameterTerminierteSEPAUeberweisungEinreichenV1.php old mode 100644 new mode 100755 index 1058223..905aff9 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/CSE/ParameterTerminierteSEPAUeberweisungEinreichenV1.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/CSE/ParameterTerminierteSEPAUeberweisungEinreichenV1.php @@ -9,4 +9,5 @@ class ParameterTerminierteSEPAUeberweisungEinreichenV1 extends BaseDeg /** Must be => 1 */ public int $minimaleVorlaufzeit; public int $maximaleVorlaufzeit; + } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/AccountInfo.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/AccountInfo.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Btg.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Btg.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kik.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kik.php old mode 100644 new mode 100755 index 2caa640..8b8f177 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kik.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kik.php @@ -19,6 +19,7 @@ class Kik extends BaseDeg /** Max length: 30 (Mandatory/absent depending on the country) */ public ?string $kreditinstitutscode = null; + /** {@inheritdoc} */ public function validate() { parent::validate(); diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kti.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kti.php old mode 100644 new mode 100755 index bd10de7..9c47a71 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kti.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kti.php @@ -26,6 +26,7 @@ class Kti extends BaseDeg implements AccountInfo public ?string $unterkontomerkmal = null; public ?Kik $kreditinstitutskennung = null; + /** {@inheritdoc} */ public function validate() { parent::validate(); @@ -57,11 +58,13 @@ class Kti extends BaseDeg implements AccountInfo return $result; } + /** {@inheritdoc} */ public function getAccountNumber(): string { return $this->iban ?? $this->kontonummer; } + /** {@inheritdoc} */ public function getBankIdentifier(): ?string { return $this->bic ?? $this->kreditinstitutskennung->kreditinstitutscode; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kto.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kto.php old mode 100644 new mode 100755 index 46436e3..1671816 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kto.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kto.php @@ -31,11 +31,13 @@ class Kto extends BaseDeg implements AccountInfo return static::create($account->getAccountNumber(), Kik::create($account->getBlz())); } + /** {@inheritdoc} */ public function getAccountNumber(): string { return $this->kontonummer; } + /** {@inheritdoc} */ public function getBankIdentifier(): ?string { return $this->kik->kreditinstitutscode; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/KtvV3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/KtvV3.php old mode 100644 new mode 100755 index b6144ac..194ad43 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/KtvV3.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/KtvV3.php @@ -37,11 +37,13 @@ class KtvV3 extends BaseDeg implements AccountInfo return static::create($account->getAccountNumber(), $account->getSubAccount(), Kik::create($account->getBlz())); } + /** {@inheritdoc} */ public function getAccountNumber(): string { return $this->kontonummer ?: ''; } + /** {@inheritdoc} */ public function getBankIdentifier(): ?string { return $this->kik->kreditinstitutscode; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Ktz.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Ktz.php old mode 100644 new mode 100755 index 34b9592..b5ee4d8 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Ktz.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Ktz.php @@ -24,11 +24,13 @@ class Ktz extends BaseDeg implements AccountInfo public ?string $unterkontomerkmal = null; public Kik $kreditinstitutskennung; + /** {@inheritdoc} */ public function getAccountNumber(): string { return $this->iban ?? $this->kontonummer; } + /** {@inheritdoc} */ public function getBankIdentifier(): ?string { return $this->bic ?? $this->kreditinstitutskennung->kreditinstitutscode; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kursqualitaet.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Kursqualitaet.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Sdo.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Sdo.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Tsp.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/Common/Tsp.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DME/HIDMESv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DME/HIDMESv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DME/HIDMESv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DME/HIDMESv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DME/HKDMEv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DME/HKDMEv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DME/HKDMEv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DME/HKDMEv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DME/ParameterTerminierteSEPASammellastschriftEinreichenV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DME/ParameterTerminierteSEPASammellastschriftEinreichenV1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DME/ParameterTerminierteSEPASammellastschriftEinreichenV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DME/ParameterTerminierteSEPASammellastschriftEinreichenV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/HIDSESv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/HIDSESv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/HIDSESv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/HIDSESv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/HIDXES.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/HIDXES.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/HKDSEv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/HKDSEv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/HKDSEv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/HKDSEv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/MinimaleVorlaufzeitSEPALastschrift.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/MinimaleVorlaufzeitSEPALastschrift.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/ParameterTerminierteSEPAEinzellastschriftEinreichenV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/ParameterTerminierteSEPAEinzellastschriftEinreichenV1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/ParameterTerminierteSEPAEinzellastschriftEinreichenV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/ParameterTerminierteSEPAEinzellastschriftEinreichenV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/SEPADirectDebitMinimalLeadTimeProvider.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DSE/SEPADirectDebitMinimalLeadTimeProvider.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/DegDescriptor.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/DegDescriptor.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/Berichtszeitraum.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/Berichtszeitraum.php new file mode 100755 index 0000000..4ff1533 --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/Berichtszeitraum.php @@ -0,0 +1,28 @@ +startdatum; + } + + public function getEnddatum(): ?string + { + return $this->enddatum; + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKA.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKA.php old mode 100644 new mode 100755 index b3099f1..e9603a1 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKA.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKA.php @@ -2,48 +2,24 @@ namespace Fhp\Segment\EKA; +use Fhp\Segment\SegmentInterface; +use Fhp\Syntax\Bin; + /** - * Interface für HIEKA Segmente (Elektronischer Kontoauszug Antwort) + * Segment: Elektronischer Kontoauszug rueckmelden + * + * Interface fuer HIEKA-Response-Segmente aller Versionen. + * Die Antwort enthaelt den Kontoauszug in einem bestimmten Format + * (MT940, ISO8583 oder PDF). */ -interface HIEKA +interface HIEKA extends SegmentInterface { - /** - * Gibt die Rohdaten des Kontoauszugs zurück (MT940 oder PDF binär) - */ - public function getData(): string; + /** Kontoauszugsformat: 1=MT940, 2=ISO8583, 3=PDF (optional) */ + public function getKontoauszugsformat(): ?string; - /** - * Gibt das Format zurück (1=MT940, 2=PDF) - */ - public function getFormat(): ?int; + /** Kontoauszug-Daten (binaer) */ + public function getKontoauszug(): Bin; - /** - * Gibt die IBAN zurück - */ - public function getIban(): ?string; - - /** - * Gibt die Kontoauszugsnummer zurück - */ - public function getStatementNumber(): ?int; - - /** - * Gibt das Kontoauszugsjahr zurück - */ - public function getStatementYear(): ?int; - - /** - * Gibt das Erstellungsdatum zurück - */ - public function getCreationDate(): ?string; - - /** - * Prüft ob Quittierung benötigt wird - */ - public function needsReceipt(): bool; - - /** - * Gibt den Quittungscode zurück - */ - public function getReceiptCode(): ?string; + /** Quittungscode (optional, muss ggf. zurueckgesendet werden) */ + public function getQuittung(): ?Bin; } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKAS.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKAS.php old mode 100644 new mode 100755 index 875cf77..e3f68a5 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKAS.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKAS.php @@ -2,10 +2,16 @@ namespace Fhp\Segment\EKA; +use Fhp\Segment\SegmentInterface; + /** - * Interface für HIEKAS Segmente (Elektronischer Kontoauszug Parameter) + * Segment: Elektronischer Kontoauszug Parameter + * + * Interface fuer HIEKAS-Parameter-Segmente aller Versionen. + * Die Praesenz dieses Segments in den BPD zeigt an, dass die Bank + * den elektronischen Kontoauszug (HKEKA) unterstuetzt. */ -interface HIEKAS +interface HIEKAS extends SegmentInterface { public function getParameter(): ParameterElektronischerKontoauszug; } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKASv3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKASv3.php new file mode 100755 index 0000000..53d12b7 --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKASv3.php @@ -0,0 +1,21 @@ +parameter; + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKASv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKASv4.php new file mode 100755 index 0000000..d12481c --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKASv4.php @@ -0,0 +1,22 @@ +parameter; + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKASv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKASv5.php old mode 100644 new mode 100755 index d3f8bb4..8a79066 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKASv5.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKASv5.php @@ -3,19 +3,13 @@ namespace Fhp\Segment\EKA; -use Fhp\Segment\BaseGeschaeftsvorfallparameter; - /** * Segment: Elektronischer Kontoauszug Parameter (Version 5) * - * Enthält die Bankparameter für den Geschäftsvorfall HKEKA (Elektronischer Kontoauszug). + * FinTS 3.0: Gleiche Struktur wie v4. + * Korrespondiert mit HKEKAv5 (IBAN/BIC-basiert, erweiterte Antwort). */ -class HIEKASv5 extends BaseGeschaeftsvorfallparameter implements HIEKAS +class HIEKASv5 extends HIEKASv4 implements HIEKAS { - public ParameterElektronischerKontoauszug $parameter; - - public function getParameter(): ParameterElektronischerKontoauszug - { - return $this->parameter; - } + // Gleiche Struktur wie v4 } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKAv3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKAv3.php new file mode 100755 index 0000000..0d5e30b --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKAv3.php @@ -0,0 +1,60 @@ +kontoauszugsformat; + } + + public function getKontoauszug(): Bin + { + return $this->kontoauszug; + } + + public function getQuittung(): ?Bin + { + return $this->quittung; + } + + public function getBerichtszeitraum(): Berichtszeitraum + { + return $this->berichtszeitraum; + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKAv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKAv4.php new file mode 100755 index 0000000..aa66020 --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HIEKAv4.php @@ -0,0 +1,14 @@ +kontoauszug ?? ''; + return $this->kontoauszugsformat; } - /** {@inheritDoc} */ - public function getFormat(): ?int + public function getKontoauszug(): Bin { - return $this->format; + return $this->kontoauszug; } - /** {@inheritDoc} */ - public function getIban(): ?string + public function getQuittung(): ?Bin { - return $this->iban; + return $this->quittung; } - /** {@inheritDoc} */ - public function getStatementNumber(): ?int + public function getBerichtszeitraum(): Berichtszeitraum { - return $this->kontoauszugsnummer; - } - - /** {@inheritDoc} */ - public function getStatementYear(): ?int - { - return $this->kontoauszugsjahr; - } - - /** {@inheritDoc} */ - public function getCreationDate(): ?string - { - return $this->erstellungsdatum; - } - - /** {@inheritDoc} */ - public function needsReceipt(): bool - { - return !empty($this->quittungscode); - } - - /** {@inheritDoc} */ - public function getReceiptCode(): ?string - { - return $this->quittungscode; + return $this->berichtszeitraum; } } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HKEKAv3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HKEKAv3.php new file mode 100755 index 0000000..ff1f48f --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HKEKAv3.php @@ -0,0 +1,51 @@ +kontoverbindungAuftraggeber = $ktv; + $result->kontoauszugsformat = $format; + $result->auszugsnummer = $auszugsnummer; + $result->jahr = $jahr; + $result->maximaleAnzahlEintraege = $maxEntries; + $result->aufsetzpunkt = $aufsetzpunkt; + return $result; + } + + public function setPaginationToken(string $paginationToken) + { + $this->aufsetzpunkt = $paginationToken; + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HKEKAv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HKEKAv4.php new file mode 100755 index 0000000..b9f2d81 --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HKEKAv4.php @@ -0,0 +1,51 @@ +kontoverbindungInternational = $kti; + $result->kontoauszugsformat = $format; + $result->auszugsnummer = $auszugsnummer; + $result->jahr = $jahr; + $result->maximaleAnzahlEintraege = $maxEntries; + $result->aufsetzpunkt = $aufsetzpunkt; + return $result; + } + + public function setPaginationToken(string $paginationToken) + { + $this->aufsetzpunkt = $paginationToken; + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HKEKAv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HKEKAv5.php old mode 100644 new mode 100755 index 891abc4..645fa3e --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HKEKAv5.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/HKEKAv5.php @@ -4,67 +4,46 @@ namespace Fhp\Segment\EKA; use Fhp\Segment\BaseSegment; -use Fhp\Segment\Common\Kti; use Fhp\Segment\Paginateable; /** * Segment: Elektronischer Kontoauszug anfordern (Version 5) * - * Ruft elektronische Kontoauszüge ab (MT940 oder PDF). - * Version 5 verwendet Kti (IBAN/BIC). + * Gleiche Struktur wie v4 (Kti-basiert). */ class HKEKAv5 extends BaseSegment implements Paginateable { - /** Kontoverbindung international (IBAN + BIC) */ - public Kti $kontoverbindungInternational; - - /** - * Format des Kontoauszugs - * 1 = MT940 (SWIFT) - * 2 = PDF - */ - public ?int $format = null; - - /** - * Von Datum (JJJJMMTT) - Optional - */ - public ?string $vonDatum = null; - - /** - * Bis Datum (JJJJMMTT) - Optional - */ - public ?string $bisDatum = null; - - /** - * Maximale Anzahl Einträge - Optional - */ + public \Fhp\Segment\Common\Kti $kontoverbindungInternational; + /** Kontoauszugsformat (optional): 1=MT940, 2=ISO8583, 3=PDF */ + public ?string $kontoauszugsformat = null; + /** Auszugsnummer (optional) */ + public ?string $auszugsnummer = null; + /** Jahr des Auszugs (optional, JJJJ) */ + public ?string $jahr = null; + /** Maximale Anzahl Eintraege (optional) */ public ?int $maximaleAnzahlEintraege = null; - - /** - * Aufsetzpunkt für Pagination - Max 35 Zeichen - */ + /** Max length: 35 */ public ?string $aufsetzpunkt = null; - /** - * Erstellt ein HKEKA v5 Segment - */ public static function create( - Kti $kti, - ?int $format = null, - ?string $vonDatum = null, - ?string $bisDatum = null, + \Fhp\Segment\Common\Kti $kti, + ?string $format = null, + ?string $auszugsnummer = null, + ?string $jahr = null, + ?int $maxEntries = null, ?string $aufsetzpunkt = null ): HKEKAv5 { $result = HKEKAv5::createEmpty(); $result->kontoverbindungInternational = $kti; - $result->format = $format; - $result->vonDatum = $vonDatum; - $result->bisDatum = $bisDatum; + $result->kontoauszugsformat = $format; + $result->auszugsnummer = $auszugsnummer; + $result->jahr = $jahr; + $result->maximaleAnzahlEintraege = $maxEntries; $result->aufsetzpunkt = $aufsetzpunkt; return $result; } - public function setPaginationToken(string $paginationToken): void + public function setPaginationToken(string $paginationToken) { $this->aufsetzpunkt = $paginationToken; } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/ParameterElektronischerKontoauszug.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/ParameterElektronischerKontoauszug.php old mode 100644 new mode 100755 index 8c4f609..aebc8f7 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/ParameterElektronischerKontoauszug.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/EKA/ParameterElektronischerKontoauszug.php @@ -1,75 +1,24 @@ unterstuetzteFormate)) { - return false; - } - return stripos($this->unterstuetzteFormate, 'PDF') !== false || - str_contains($this->unterstuetzteFormate, '2;'); - } - - /** - * Prüft ob MT940-Format unterstützt wird - */ - public function supportsMt940(): bool - { - if (empty($this->unterstuetzteFormate)) { - return false; - } - return stripos($this->unterstuetzteFormate, 'MT940') !== false || - str_contains($this->unterstuetzteFormate, '1;'); - } - - /** - * Prüft ob Zeitraum-Abruf möglich ist - */ - public function canFetchByDateRange(): bool - { - return $this->zeitraumAbrufMoeglich === 'J'; - } - - /** - * Prüft ob Quittierung erforderlich ist - */ - public function requiresReceipt(): bool - { - return $this->quittierungErforderlich === 'J'; - } + /** Index/Auszugsnummer erlaubt? */ + public bool $canindex; + /** Quittung erforderlich? */ + public bool $needreceipt; + /** Maximale Anzahl Eintraege erlaubt? */ + public bool $canmaxentries; + /** Anzahl unterstuetzter Formate (1=MT940, 2=ISO8583, 3=PDF) */ + public ?int $anzahlFormate = null; } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/ElementDescriptor.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/ElementDescriptor.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIBPA/HIBPAv3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIBPA/HIBPAv3.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIBPA/UnterstuetzteHbciVersionenV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIBPA/UnterstuetzteHbciVersionenV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIBPA/UnterstuetzteSprachenV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIBPA/UnterstuetzteSprachenV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIEPS/HIEPS.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIEPS/HIEPS.php new file mode 100755 index 0000000..ac6a925 --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIEPS/HIEPS.php @@ -0,0 +1,17 @@ +parameter; + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIEPS/HIEPSv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIEPS/HIEPSv2.php new file mode 100755 index 0000000..7f58103 --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIEPS/HIEPSv2.php @@ -0,0 +1,19 @@ +parameter; + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIEPS/ParameterKontoauszugPdf.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIEPS/ParameterKontoauszugPdf.php new file mode 100755 index 0000000..4cedebf --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIEPS/ParameterKontoauszugPdf.php @@ -0,0 +1,18 @@ +canindex; + } + + public function getNeedReceipt(): bool + { + return $this->needreceipt; + } + + public function getCanMaxEntries(): bool + { + return $this->canmaxentries; + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIEPS/ParameterKontoauszugPdfV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIEPS/ParameterKontoauszugPdfV2.php new file mode 100755 index 0000000..6bd5798 --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIEPS/ParameterKontoauszugPdfV2.php @@ -0,0 +1,19 @@ +base64; + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIKEP/HIKEP.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIKEP/HIKEP.php new file mode 100755 index 0000000..aacd75a --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIKEP/HIKEP.php @@ -0,0 +1,20 @@ +kontoauszug; + } + + public function getQuittung(): ?Bin + { + return $this->quittung; + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIKEP/HIKEPv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIKEP/HIKEPv2.php new file mode 100755 index 0000000..9e97fb1 --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIKEP/HIKEPv2.php @@ -0,0 +1,14 @@ +rueckmeldungscode === $code; })); } - - /** @return Rueckmeldung[] */ - public function getAllRueckmeldungen(): array - { - return $this->rueckmeldung; - } } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIRMS/HIRMSv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIRMS/HIRMSv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIRMS/Rueckmeldung.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIRMS/Rueckmeldung.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIRMS/RueckmeldungContainer.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIRMS/RueckmeldungContainer.php old mode 100644 new mode 100755 index 5f45baa..33bcdd0 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIRMS/RueckmeldungContainer.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIRMS/RueckmeldungContainer.php @@ -15,7 +15,4 @@ interface RueckmeldungContainer /** @return Rueckmeldung[] */ public function findRueckmeldungen(int $code): array; - - /** @return Rueckmeldung[] */ - public function getAllRueckmeldungen(): array; } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIRMS/Rueckmeldungscode.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIRMS/Rueckmeldungscode.php old mode 100644 new mode 100755 index d401cbb..7a53a5e --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIRMS/Rueckmeldungscode.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIRMS/Rueckmeldungscode.php @@ -2,8 +2,6 @@ namespace Fhp\Segment\HIRMS; -use Fhp\Protocol\DialogInitialization; - /** * Enum for the response codes that the server can send. * @@ -79,17 +77,7 @@ abstract class Rueckmeldungscode * Tells the client that the response is incomplete and the request needs to be re-sent with the pagination token * ("Aufsetzpunkt") that is contained in the Rueckmeldung parameters. */ - public const AUFSETZPUNKT = 3040; - - public const VOP_KEINE_NAMENSABWEICHUNG = 25; - - public const VOP_ERGEBNIS_NAMENSABGLEICH_PRUEFEN = 3090; - - public const VOP_AUSFUEHRUNGSAUFTRAG_NICHT_BENOETIGT = 3091; - - public const VOP_NAMENSABGLEICH_IST_NOCH_IN_BEARBEITUNG = 3093; - - public const VOP_NAMENSABGLEICH_IST_KOMPLETT = 3094; + public const PAGINATION = 3040; /** * Zugelassene Ein- und Zwei-Schritt-Verfahren für den Benutzer (+ Rückmeldungsparameter). @@ -111,14 +99,6 @@ abstract class Rueckmeldungscode */ public const ZUGANG_VORLAEUFIG_GESPERRT = 3938; - /** - * Der eingereichte HKTAN ist entwertet und der Auftrag (nach - * vollständiger Übermittlung des Prüfergebnisses) soll erneut mit einem neuen - * HKTAN in Verbindung mit einem HKVPA eingereicht werden, sofern der - * Kunde die Ausführung weiterhin wünscht. - */ - public const FREIGABE_KANN_NICHT_ERTEILT_WERDEN = 3945; - /** * Starke Kundenauthentifizierung noch ausstehend. * Indicates that the decoupled authentication is still outstanding. @@ -130,12 +110,6 @@ abstract class Rueckmeldungscode */ public const TEILWEISE_FEHLERHAFT = 9050; - /** - * Neue Kundensystem-ID anfordern. - * Als Antwort auf eine Dialoginitialisierungsnachricht ({@link DialogInitialization}). - */ - public const NEUE_KUNDENSYSTEM_ID_HOLEN = 9391; - /** * Kreditinstitutsseitige Beendigung des Dialoges */ diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HISYN/HISYNv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HISYN/HISYNv4.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPA/HIUPAv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPA/HIUPAv4.php old mode 100644 new mode 100755 index 5088d3e..5dc197f --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPA/HIUPAv4.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPA/HIUPAv4.php @@ -24,6 +24,7 @@ class HIUPAv4 extends BaseSegment * it does not support it, so sending such a request to the bank will always lead to failure. * 1: Explicitly declared types are definitely supported, anything else may be reported and can be sent; the bank * will check online and accept/reject accordingly. + * @var int */ public int $updVerwendung; /** Max length: 35 */ diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/ErlaubteGeschaeftsvorfaelle.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/ErlaubteGeschaeftsvorfaelle.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/ErlaubteGeschaeftsvorfaelleV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/ErlaubteGeschaeftsvorfaelleV1.php old mode 100644 new mode 100755 index 8b33098..f473ae0 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/ErlaubteGeschaeftsvorfaelleV1.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/ErlaubteGeschaeftsvorfaelleV1.php @@ -22,6 +22,7 @@ class ErlaubteGeschaeftsvorfaelleV1 extends BaseDeg implements ErlaubteGeschaeft /** If present, must be greater than 0 */ public ?int $limitTage = null; + /** {@inheritdoc} */ public function getGeschaeftsvorfall(): string { return $this->geschaeftsvorfall; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/ErlaubteGeschaeftsvorfaelleV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/ErlaubteGeschaeftsvorfaelleV2.php old mode 100644 new mode 100755 index 23b0dba..7766078 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/ErlaubteGeschaeftsvorfaelleV2.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/ErlaubteGeschaeftsvorfaelleV2.php @@ -22,6 +22,7 @@ class ErlaubteGeschaeftsvorfaelleV2 extends BaseDeg implements ErlaubteGeschaeft /** Only allowed for limitart==Z, must be greater than zero. */ public ?int $limitTage = null; + /** {@inheritdoc} */ public function getGeschaeftsvorfall(): string { return $this->geschaeftsvorfall; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/HIUPD.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/HIUPD.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/HIUPDv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/HIUPDv4.php old mode 100644 new mode 100755 index 4429fdd..234bc25 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/HIUPDv4.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/HIUPDv4.php @@ -29,12 +29,14 @@ class HIUPDv4 extends BaseSegment implements HIUPD /** @var ErlaubteGeschaeftsvorfaelleV1[]|null @Max(98) */ public ?array $erlaubteGeschaeftsvorfaelle = null; + /** {@inheritdoc} */ public function matchesAccount(SEPAAccount $account): bool { return !is_null($this->kontoverbindung->kontonummer) && $this->kontoverbindung->kontonummer == $account->getAccountNumber(); } + /** {@inheritdoc} */ public function getErlaubteGeschaeftsvorfaelle(): array { return $this->erlaubteGeschaeftsvorfaelle ?? []; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/HIUPDv6.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/HIUPDv6.php old mode 100644 new mode 100755 index 3ecd9d6..94e5c42 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/HIUPDv6.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/HIUPDv6.php @@ -51,15 +51,13 @@ class HIUPDv6 extends BaseSegment implements HIUPD */ public ?string $erweiterungKontobezogen = null; + /** {@inheritdoc} */ public function matchesAccount(SEPAAccount $account): bool { - if (!is_null($this->iban)) { - return $this->iban == $account->getIban(); - } - // Sparkasse (Koblenz) does not provide an IBAN in this segment, fall back to kontonummer: - return !is_null($this->kontoverbindung->kontonummer) && $this->kontoverbindung->kontonummer == $account->getAccountNumber(); + return !is_null($this->iban) && $this->iban == $account->getIban(); } + /** {@inheritdoc} */ public function getErlaubteGeschaeftsvorfaelle(): array { return $this->erlaubteGeschaeftsvorfaelle ?? []; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/KontolimitV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/KontolimitV1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/KontolimitV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HIUPD/KontolimitV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HKEKP/HKEKPv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HKEKP/HKEKPv1.php new file mode 100755 index 0000000..db5c22a --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HKEKP/HKEKPv1.php @@ -0,0 +1,46 @@ +kontoverbindungAuftraggeber = $ktv; + $result->auszugsnummer = $auszugsnummer; + $result->jahr = $jahr; + $result->maximaleAnzahlEintraege = $maxEntries; + $result->aufsetzpunkt = $aufsetzpunkt; + return $result; + } + + public function setPaginationToken(string $paginationToken) + { + $this->aufsetzpunkt = $paginationToken; + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HKEKP/HKEKPv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HKEKP/HKEKPv2.php new file mode 100755 index 0000000..1cd5f2c --- /dev/null +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HKEKP/HKEKPv2.php @@ -0,0 +1,46 @@ +kontoverbindungInternational = $kti; + $result->auszugsnummer = $auszugsnummer; + $result->jahr = $jahr; + $result->maximaleAnzahlEintraege = $maxEntries; + $result->aufsetzpunkt = $aufsetzpunkt; + return $result; + } + + public function setPaginationToken(string $paginationToken) + { + $this->aufsetzpunkt = $paginationToken; + } +} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HKEND/HKENDv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HKEND/HKENDv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HKIDN/HKIDNv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HKIDN/HKIDNv2.php old mode 100644 new mode 100755 index f4147de..155abd2 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/HKIDN/HKIDNv2.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/HKIDN/HKIDNv2.php @@ -30,6 +30,7 @@ class HKIDNv2 extends BaseSegment * 0: Kundensystem-ID wird nicht benötigt (HBCI DDV-Verfahren und chipkartenbasierte Verfahren ab * Sicherheitsprofil-Version 3) * 1: Kundensystem-ID wird benötigt (sonstige HBCI RAH-/RDH- und PIN/TAN-Verfahren) + * @var int */ public int $kundensystemStatus = 1; // This library only supports PIN/TAN, hence 1 is the right choice. diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HKSYN/HKSYNv3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HKSYN/HKSYNv3.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HKVVB/HKVVBv3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HKVVB/HKVVBv3.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNHBK/BezugsnachrichtV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNHBK/BezugsnachrichtV1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNHBK/HNHBKv3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNHBK/HNHBKv3.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNHBS/HNHBSv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNHBS/HNHBSv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNSHA/BenutzerdefinierteSignaturV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNSHA/BenutzerdefinierteSignaturV1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNSHA/HNSHAv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNSHA/HNSHAv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNSHK/HNSHKv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNSHK/HNSHKv4.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNSHK/HashalgorithmusV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNSHK/HashalgorithmusV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNSHK/SignaturalgorithmusV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNSHK/SignaturalgorithmusV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSD/HNVSDv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSD/HNVSDv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/HNVSKv3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/HNVSKv3.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/SchluesselnameV3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/SchluesselnameV3.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/SicherheitsdatumUndUhrzeitV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/SicherheitsdatumUndUhrzeitV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/SicherheitsidentifikationDetailsV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/SicherheitsidentifikationDetailsV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/SicherheitsprofilV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/SicherheitsprofilV1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/VerschluesselungsalgorithmusV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/VerschluesselungsalgorithmusV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/ZertifikatV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/HNVSK/ZertifikatV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HIIPZSv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HIIPZSv1.php old mode 100644 new mode 100755 index 2f4d7f2..21b915a --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HIIPZSv1.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HIIPZSv1.php @@ -11,6 +11,7 @@ use Fhp\Segment\BaseSegment; * @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2022-04-15_final_version.pdf * Section: C.10.2.9.1.1 c) */ + class HIIPZSv1 extends BaseGeschaeftsvorfallparameter { public ParameterSEPAInstantPaymentZahlungV1 $parameter; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HIIPZSv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HIIPZSv2.php old mode 100644 new mode 100755 index b31acf3..e78c92b --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HIIPZSv2.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HIIPZSv2.php @@ -2,6 +2,7 @@ namespace Fhp\Segment\IPZ; +use Fhp\Segment\IPZ\ParameterSEPAInstantPaymentZahlungV2; use Fhp\Segment\BaseGeschaeftsvorfallparameter; use Fhp\Segment\BaseSegment; @@ -11,6 +12,7 @@ use Fhp\Segment\BaseSegment; * @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2022-04-15_final_version.pdf * Section: C.10.2.9.1.2 c) */ + class HIIPZSv2 extends BaseGeschaeftsvorfallparameter { public ParameterSEPAInstantPaymentZahlungV2 $parameter; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HIIPZv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HIIPZv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HIIPZv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HIIPZv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HKIPZv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HKIPZv1.php old mode 100644 new mode 100755 index 9d7dcdd..b5ffdf9 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HKIPZv1.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HKIPZv1.php @@ -12,4 +12,5 @@ use Fhp\Segment\CCS\HKCCSv1; */ class HKIPZv1 extends HKCCSv1 { + } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HKIPZv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/HKIPZv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/ParameterSEPAInstantPaymentZahlungV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/ParameterSEPAInstantPaymentZahlungV1.php old mode 100644 new mode 100755 index 11cf6d6..9ae83ab --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/ParameterSEPAInstantPaymentZahlungV1.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/ParameterSEPAInstantPaymentZahlungV1.php @@ -21,4 +21,4 @@ class ParameterSEPAInstantPaymentZahlungV1 extends BaseDeg implements Unterstuet /** @var string[]|null @Max(9) Max length: 256 */ public ?array $unterstuetzteSEPADatenformate = null; -} +} \ No newline at end of file diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/ParameterSEPAInstantPaymentZahlungV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/IPZ/ParameterSEPAInstantPaymentZahlungV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HIKAA.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HIKAA.php deleted file mode 100644 index ff137b9..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HIKAA.php +++ /dev/null @@ -1,27 +0,0 @@ -parameter; - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HIKAAv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HIKAAv1.php deleted file mode 100644 index 3062af9..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HIKAAv1.php +++ /dev/null @@ -1,102 +0,0 @@ -kontoauszugsdaten->getData(); - } - - public function getStatementNumber(): ?int - { - return $this->kontoauszugsnummer; - } - - public function getStatementYear(): ?int - { - return $this->kontoauszugsjahr; - } - - public function getIban(): ?string - { - return $this->iban; - } - - public function getFilename(): ?string - { - return $this->dateiname; - } - - public function getFormat(): ?int - { - return $this->format; - } - - public function getCreationDate(): ?\DateTime - { - if ($this->erstellungsdatum === null) { - return null; - } - return \DateTime::createFromFormat('Ymd', $this->erstellungsdatum) ?: null; - } - - public function needsReceipt(): bool - { - return $this->quittungscode !== null; - } - - public function getReceiptCode(): ?string - { - return $this->quittungscode?->getData(); - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HIKAAv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HIKAAv2.php deleted file mode 100644 index c9e4910..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HIKAAv2.php +++ /dev/null @@ -1,102 +0,0 @@ -kontoauszugsdaten->getData(); - } - - public function getStatementNumber(): ?int - { - return $this->kontoauszugsnummer; - } - - public function getStatementYear(): ?int - { - return $this->kontoauszugsjahr; - } - - public function getIban(): ?string - { - return $this->iban; - } - - public function getFilename(): ?string - { - return $this->dateiname; - } - - public function getFormat(): ?int - { - return $this->format; - } - - public function getCreationDate(): ?\DateTime - { - if ($this->erstellungsdatum === null) { - return null; - } - return \DateTime::createFromFormat('Ymd', $this->erstellungsdatum) ?: null; - } - - public function needsReceipt(): bool - { - return $this->quittungscode !== null; - } - - public function getReceiptCode(): ?string - { - return $this->quittungscode?->getData(); - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HKKAAv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HKKAAv1.php deleted file mode 100644 index ad3417e..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HKKAAv1.php +++ /dev/null @@ -1,81 +0,0 @@ -kontoverbindungInternational = $kti; - $result->format = $format; - $result->vonDatum = $vonDatum; - $result->bisDatum = $bisDatum; - $result->aufsetzpunkt = $aufsetzpunkt; - return $result; - } - - public function setPaginationToken(string $paginationToken): void - { - $this->aufsetzpunkt = $paginationToken; - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HKKAAv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HKKAAv2.php deleted file mode 100644 index 1f12d60..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/HKKAAv2.php +++ /dev/null @@ -1,83 +0,0 @@ -kontoverbindungInternational = $kti; - $result->format = $format; - $result->vonDatum = $vonDatum; - $result->bisDatum = $bisDatum; - $result->aufsetzpunkt = $aufsetzpunkt; - return $result; - } - - public function setPaginationToken(string $paginationToken): void - { - $this->aufsetzpunkt = $paginationToken; - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/ParameterKontoauszugArchiv.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/ParameterKontoauszugArchiv.php deleted file mode 100644 index 7850bdf..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAA/ParameterKontoauszugArchiv.php +++ /dev/null @@ -1,90 +0,0 @@ -unterstuetzteFormate)) { - return false; - } - // Format "4;PDF;1" - Code 4 ist PDF - return str_contains($this->unterstuetzteFormate, '4;') || - stripos($this->unterstuetzteFormate, 'PDF') !== false; - } - - /** - * Gibt den Format-Code für PDF zurück (normalerweise 4) - */ - public function getPdfFormatCode(): int - { - return 4; - } - - /** - * Prüft ob Einzelabruf möglich ist - */ - public function canFetchSingle(): bool - { - return $this->einzelabrufMoeglich === 'J'; - } - - /** - * Prüft ob Zeitraum-Abruf möglich ist - */ - public function canFetchByDateRange(): bool - { - return $this->zeitraumAbrufMoeglich === 'J'; - } - - /** - * Prüft ob Quittierung erforderlich ist - */ - public function requiresReceipt(): bool - { - return $this->quittierungErforderlich === 'J'; - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZ.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZ.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZS.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZS.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZSv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZSv4.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZSv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZSv5.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZSv6.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZSv6.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZSv7.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZSv7.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZv4.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZv5.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZv6.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZv6.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZv7.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HIKAZv7.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HKKAZv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HKKAZv4.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HKKAZv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HKKAZv5.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HKKAZv6.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HKKAZv6.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HKKAZv7.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/HKKAZv7.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/ParameterKontoumsaetze.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/ParameterKontoumsaetze.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/ParameterKontoumsaetzeV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/ParameterKontoumsaetzeV1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/ParameterKontoumsaetzeV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/KAZ/ParameterKontoumsaetzeV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/Paginateable.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/Paginateable.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISAL.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISAL.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALSv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALSv4.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALSv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALSv5.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALSv6.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALSv6.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALSv7.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALSv7.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALv4.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALv5.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALv6.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALv6.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALv7.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HISALv7.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HKSALv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HKSALv4.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HKSALv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HKSALv5.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HKSALv6.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HKSALv6.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HKSALv7.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SAL/HKSALv7.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPA.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPA.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPAS.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPAS.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPASv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPASv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPASv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPASv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPASv3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPASv3.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPAv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPAv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPAv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPAv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPAv3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HISPAv3.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HKSPAv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HKSPAv1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HKSPAv2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HKSPAv2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HKSPAv3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/HKSPAv3.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/ParameterSepaKontoverbindungAnfordern.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/ParameterSepaKontoverbindungAnfordern.php old mode 100644 new mode 100755 index 27e5f17..d0b09eb --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/ParameterSepaKontoverbindungAnfordern.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/ParameterSepaKontoverbindungAnfordern.php @@ -10,4 +10,5 @@ use Fhp\Segment\UnterstuetzteSEPADatenformate; */ interface ParameterSepaKontoverbindungAnfordern extends UnterstuetzteSEPADatenformate { + } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/ParameterSepaKontoverbindungAnfordernV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/ParameterSepaKontoverbindungAnfordernV1.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/ParameterSepaKontoverbindungAnfordernV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/ParameterSepaKontoverbindungAnfordernV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/ParameterSepaKontoverbindungAnfordernV3.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SPA/ParameterSepaKontoverbindungAnfordernV3.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SegmentDescriptor.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SegmentDescriptor.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/SegmentInterface.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/SegmentInterface.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/Segmentkopf.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/Segmentkopf.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITAB.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITAB.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITABSv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITABSv4.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITABSv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITABSv5.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITABv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITABv4.php old mode 100644 new mode 100755 index 046c1af..9973795 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITABv4.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITABv4.php @@ -22,6 +22,7 @@ class HITABv4 extends BaseSegment implements HITAB /** @var TanMediumListeV4[]|null @Max(99) */ public ?array $tanMediumListe = null; + /** {@inheritdoc} */ public function getTanMediumListe(): array { return $this->tanMediumListe; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITABv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITABv5.php old mode 100644 new mode 100755 index 6a72c8c..c7f8916 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITABv5.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HITABv5.php @@ -22,6 +22,7 @@ class HITABv5 extends BaseSegment implements HITAB /** @var TanMediumListeV5[]|null @Max(99) */ public ?array $tanMediumListe = null; + /** {@inheritdoc} */ public function getTanMediumListe(): array { return $this->tanMediumListe; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HKTABv4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HKTABv4.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HKTABv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/HKTABv5.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/TanMediumListe.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/TanMediumListe.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/TanMediumListeV4.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/TanMediumListeV4.php old mode 100644 new mode 100755 index abe3dae..4f53401 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/TanMediumListeV4.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/TanMediumListeV4.php @@ -56,11 +56,13 @@ class TanMediumListeV4 extends BaseDeg implements TanMediumListe /** JJJJMMTT gemäß ISO 8601 */ public ?string $freigeschaltetAm = null; + /** {@inheritdoc} */ public function getName(): string { return $this->bezeichnungDesTanMediums; } + /** {@inheritdoc} */ public function getPhoneNumber(): ?string { return $this->mobiltelefonnummer !== null ? $this->mobiltelefonnummer : $this->mobiltelefonnummerVerschleiert; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/TanMediumListeV5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/TanMediumListeV5.php old mode 100644 new mode 100755 index 13bf8b0..be5aa7f --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/TanMediumListeV5.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAB/TanMediumListeV5.php @@ -59,11 +59,13 @@ class TanMediumListeV5 extends BaseDeg implements TanMediumListe /** JJJJMMTT gemäß ISO 8601 */ public ?string $freigeschaltetAm = null; + /** {@inheritdoc} */ public function getName(): string { return $this->bezeichnungDesTanMediums; } + /** {@inheritdoc} */ public function getPhoneNumber(): ?string { return $this->mobiltelefonnummer !== null ? $this->mobiltelefonnummer : $this->mobiltelefonnummerVerschleiert; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/AntwortHhdUc.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/AntwortHhdUc.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/GueltigkeitsdatumUndUhrzeitFuerChallenge.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/GueltigkeitsdatumUndUhrzeitFuerChallenge.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITAN.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITAN.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITANS.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITANS.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITANSv6.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITANSv6.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITANSv7.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITANSv7.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITANv6.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITANv6.php old mode 100644 new mode 100755 index c1032f9..2d641f2 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITANv6.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITANv6.php @@ -55,18 +55,21 @@ class HITANv6 extends BaseSegment implements HITAN */ public ?string $bezeichnungDesTanMediums = null; + /** {@inheritdoc} */ public function getProcessId(): string { // Note: This is non-null because tanProzess==4. return $this->auftragsreferenz; } + /** {@inheritdoc} */ public function getChallenge(): ?string { // Note: This is non-null because tanProzess==4. return $this->challenge === static::DUMMY_CHALLENGE ? null : $this->challenge; } + /** {@inheritdoc} */ public function getTanMediumName(): ?string { return $this->bezeichnungDesTanMediums; diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITANv7.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HITANv7.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HKTAN.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HKTAN.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HKTANFactory.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HKTANFactory.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HKTANv6.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HKTANv6.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HKTANv7.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/HKTANv7.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/ParameterChallengeKlasse.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/ParameterChallengeKlasse.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/ParameterZweiSchrittTanEinreichung.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/ParameterZweiSchrittTanEinreichung.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/ParameterZweiSchrittTanEinreichungV6.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/ParameterZweiSchrittTanEinreichungV6.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/ParameterZweiSchrittTanEinreichungV7.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/ParameterZweiSchrittTanEinreichungV7.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/VerfahrensparameterZweiSchrittVerfahrenV6.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/VerfahrensparameterZweiSchrittVerfahrenV6.php old mode 100644 new mode 100755 index 38ae6cb..6695917 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/VerfahrensparameterZweiSchrittVerfahrenV6.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/VerfahrensparameterZweiSchrittVerfahrenV6.php @@ -49,96 +49,115 @@ class VerfahrensparameterZweiSchrittVerfahrenV6 extends BaseDeg implements TanMo public bool $antwortHhdUcErforderlich; public ?int $anzahlUnterstuetzterAktiverTanMedien = null; + /** {@inheritdoc} */ public function getId(): int { return $this->sicherheitsfunktion; } + /** {@inheritdoc} */ public function getName(): string { return $this->nameDesZweiSchrittVerfahrens; } + /** {@inheritdoc} */ public function isProzessvariante2(): bool { return $this->tanProzess === HKTAN::TAN_PROZESS_2; } + /** {@inheritdoc} */ public function isDecoupled(): bool { return false; } + /** {@inheritdoc} */ public function getSmsAbbuchungskontoErforderlich(): bool { return $this->smsAbbuchungskontoErforderlich === 2; } + /** {@inheritdoc} */ public function getAuftraggeberkontoErforderlich(): bool { return $this->auftraggeberkontoErforderlich === 2; } + /** {@inheritdoc} */ public function getChallengeKlasseErforderlich(): bool { return $this->challengeKlasseErforderlich; } + /** {@inheritdoc} */ public function getAntwortHhdUcErforderlich(): bool { return $this->antwortHhdUcErforderlich; } + /** {@inheritdoc} */ public function getChallengeLabel(): string { return $this->textZurBelegungDesRueckgabewertes; } + /** {@inheritdoc} */ public function getMaxChallengeLength(): int { return $this->maximaleLaengeDesRueckgabewertes; } + /** {@inheritdoc} */ public function getMaxTanLength(): int { return $this->maximaleLaengeDesTanEingabewertes; } + /** {@inheritdoc} */ public function getTanFormat(): int { return $this->erlaubtesFormat; } + /** {@inheritdoc} */ public function needsTanMedium(): bool { return $this->bezeichnungDesTanMediumsErforderlich === 2 && $this->anzahlUnterstuetzterAktiverTanMedien > 0; } + /** {@inheritdoc} */ public function getMaxDecoupledChecks(): int { throw new \RuntimeException('Only allowed for decoupled TAN modes'); } + /** {@inheritdoc} */ public function getFirstDecoupledCheckDelaySeconds(): int { throw new \RuntimeException('Only allowed for decoupled TAN modes'); } + /** {@inheritdoc} */ public function getPeriodicDecoupledCheckDelaySeconds(): int { throw new \RuntimeException('Only allowed for decoupled TAN modes'); } + /** {@inheritdoc} */ public function allowsManualConfirmation(): bool { throw new \RuntimeException('Only allowed for decoupled TAN modes'); } + /** {@inheritdoc} */ public function allowsAutomatedPolling(): bool { throw new \RuntimeException('Only allowed for decoupled TAN modes'); } + /** {@inheritdoc} */ public function createHKTAN(): HKTAN { return HKTANv6::createEmpty(); diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/VerfahrensparameterZweiSchrittVerfahrenV7.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/VerfahrensparameterZweiSchrittVerfahrenV7.php old mode 100644 new mode 100755 index 3834f80..17c47c6 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/VerfahrensparameterZweiSchrittVerfahrenV7.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Segment/TAN/VerfahrensparameterZweiSchrittVerfahrenV7.php @@ -70,56 +70,67 @@ class VerfahrensparameterZweiSchrittVerfahrenV7 extends BaseDeg implements TanMo /** Maybe present if isDecoupled. */ public ?bool $automatisierteStatusabfragenErlaubt = null; + /** {@inheritdoc} */ public function getId(): int { return $this->sicherheitsfunktion; } + /** {@inheritdoc} */ public function getName(): string { return $this->nameDesZweiSchrittVerfahrens; } + /** {@inheritdoc} */ public function isProzessvariante2(): bool { return $this->tanProzess === HKTAN::TAN_PROZESS_2; } + /** {@inheritdoc} */ public function isDecoupled(): bool { return $this->dkTanVerfahren === 'Decoupled' || $this->dkTanVerfahren === 'DecoupledPush'; } + /** {@inheritdoc} */ public function getSmsAbbuchungskontoErforderlich(): bool { return $this->smsAbbuchungskontoErforderlich === 2; } + /** {@inheritdoc} */ public function getAuftraggeberkontoErforderlich(): bool { return $this->auftraggeberkontoErforderlich === 2; } + /** {@inheritdoc} */ public function getChallengeKlasseErforderlich(): bool { return $this->challengeKlasseErforderlich; } + /** {@inheritdoc} */ public function getAntwortHhdUcErforderlich(): bool { return $this->antwortHhdUcErforderlich; } + /** {@inheritdoc} */ public function getChallengeLabel(): string { return $this->textZurBelegungDesRueckgabewertes; } + /** {@inheritdoc} */ public function getMaxChallengeLength(): int { return $this->maximaleLaengeDesRueckgabewertes; } + /** {@inheritdoc} */ public function getMaxTanLength(): int { if ($this->isDecoupled()) { @@ -131,6 +142,7 @@ class VerfahrensparameterZweiSchrittVerfahrenV7 extends BaseDeg implements TanMo return $this->maximaleLaengeDesTanEingabewertes; } + /** {@inheritdoc} */ public function getTanFormat(): int { if ($this->isDecoupled()) { @@ -142,11 +154,13 @@ class VerfahrensparameterZweiSchrittVerfahrenV7 extends BaseDeg implements TanMo return $this->erlaubtesFormat; } + /** {@inheritdoc} */ public function needsTanMedium(): bool { return $this->bezeichnungDesTanMediumsErforderlich === 2 && $this->anzahlUnterstuetzterAktiverTanMedien > 0; } + /** {@inheritdoc} */ public function getMaxDecoupledChecks(): int { if (!$this->isDecoupled()) { @@ -158,6 +172,7 @@ class VerfahrensparameterZweiSchrittVerfahrenV7 extends BaseDeg implements TanMo return $this->maximaleAnzahlStatusabfragen; } + /** {@inheritdoc} */ public function getFirstDecoupledCheckDelaySeconds(): int { if (!$this->isDecoupled()) { @@ -169,6 +184,7 @@ class VerfahrensparameterZweiSchrittVerfahrenV7 extends BaseDeg implements TanMo return $this->wartezeitVorErsterStatusabfrage; } + /** {@inheritdoc} */ public function getPeriodicDecoupledCheckDelaySeconds(): int { if (!$this->isDecoupled()) { @@ -180,6 +196,7 @@ class VerfahrensparameterZweiSchrittVerfahrenV7 extends BaseDeg implements TanMo return $this->wartezeitVorNaechsterStatusabfrage; } + /** {@inheritdoc} */ public function allowsManualConfirmation(): bool { if (!$this->isDecoupled()) { @@ -191,6 +208,7 @@ class VerfahrensparameterZweiSchrittVerfahrenV7 extends BaseDeg implements TanMo return $this->manuelleBestaetigungMoeglich; } + /** {@inheritdoc} */ public function allowsAutomatedPolling(): bool { if (!$this->isDecoupled()) { @@ -202,6 +220,7 @@ class VerfahrensparameterZweiSchrittVerfahrenV7 extends BaseDeg implements TanMo return $this->automatisierteStatusabfragenErlaubt; } + /** {@inheritdoc} */ public function createHKTAN(): HKTAN { return HKTANv7::createEmpty(); diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/UnterstuetzteSEPADatenformate.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/UnterstuetzteSEPADatenformate.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/UnterstuetzteSEPADatenformateTrait.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/UnterstuetzteSEPADatenformateTrait.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/VPA/HKVPAv1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/VPA/HKVPAv1.php deleted file mode 100644 index 843d88a..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/VPA/HKVPAv1.php +++ /dev/null @@ -1,17 +0,0 @@ -unterstuetztePaymentStatusReports = new UnterstuetztePaymentStatusReportsV1(); - return $hkvpp; - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/VPP/ParameterNamensabgleichPruefauftragV1.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/VPP/ParameterNamensabgleichPruefauftragV1.php deleted file mode 100644 index df2331f..0000000 --- a/vendor/nemiah/php-fints/lib/Fhp/Segment/VPP/ParameterNamensabgleichPruefauftragV1.php +++ /dev/null @@ -1,30 +0,0 @@ -getLatestSupportedParameters('HIVPPS'); - $supportedFormats = explode(';', $hivpps->parameter->unterstuetztePaymentStatusReportDatenformate); - if ($hivpps->parameter->artDerLieferungPaymentStatusReport !== 'V') { - throw new UnsupportedException('The stepwise transfer of VOP reports is not yet supported'); - } - - $hkvpp = HKVPPv1::createEmpty(); - $hkvpp->unterstuetztePaymentStatusReports->paymentStatusReportDescriptor = $supportedFormats; - return $hkvpp; - } - - /** - * @param BPD $bpd The BPD. - * @param VopPollingInfo $pollingInfo The polling info we got from the immediately preceding request. - * @return HKVPPv1 A segment to poll the server for the completion of Verification of Payee. - */ - public static function createHKVPPForPollingRequest(BPD $bpd, VopPollingInfo $pollingInfo): HKVPPv1 - { - $hkvpp = static::createHKVPPForInitialRequest($bpd); - $hkvpp->aufsetzpunkt = $pollingInfo->getAufsetzpunkt(); - $hkvpp->pollingId = $pollingInfo->getPollingId(); - return $hkvpp; - } - - /** - * @param Message $response The response we just received from the server. - * @param int $hkvppSegmentNumber The number of the HKVPP segment in the request we had sent. - * @return ?VopPollingInfo If the response indicates that the Verification of Payee is still ongoing, such that the - * client should keep polling the server to (actively) wait until the result is available, this function returns - * a corresponding polling info object. If no polling is required, it returns null. - */ - public static function checkPollingRequired(Message $response, int $hkvppSegmentNumber): ?VopPollingInfo - { - // Note: We determine whether polling is required purely based on the presence of the primary polling token ( - // the Aufsetzpunkt is mandatory, the polling ID is optional). - // The specification also contains the code "3093 Namensabgleich ist noch in Bearbeitung", which could also be - // used to indicate that polling is required. But the specification does not mandate its use, and we have not - // observed banks using it consistently, so we don't rely on it here. - $aufsetzpunkt = $response->findRueckmeldung(Rueckmeldungscode::AUFSETZPUNKT, $hkvppSegmentNumber); - if ($aufsetzpunkt === null) { - return null; - } - /** @var HIVPPv1 $hivpp */ - $hivpp = $response->findSegment(HIVPPv1::class); - if ($hivpp->vopId !== null || $hivpp->paymentStatusReport !== null) { - // Implementation note: If this ever happens, it could be related to $artDerLieferungPaymentStatusReport. - throw new UnexpectedResponseException('Got response with Aufsetzpunkt AND vopId/paymentStatusReport.'); - } - return new VopPollingInfo( - $aufsetzpunkt->rueckmeldungsparameter[0], - $hivpp?->pollingId, - $hivpp?->wartezeitVorNaechsterAbfrage, - ); - } - - /** - * @param Message $response The response we just received from the server. - * @param int $hkvppSegmentNumber The number of the HKVPP segment in the request we had sent. - * @return ?VopConfirmationRequestImpl If the response contains a confirmation request for the user, it is returned, - * otherwise null (which may imply that the action was executed without requiring confirmation). - */ - public static function checkVopConfirmationRequired( - Message $response, - int $hkvppSegmentNumber, - ): ?VopConfirmationRequestImpl { - $codes = $response->findRueckmeldungscodesForReferenceSegment($hkvppSegmentNumber); - if (in_array(Rueckmeldungscode::VOP_AUSFUEHRUNGSAUFTRAG_NICHT_BENOETIGT, $codes)) { - return null; - } - /** @var HIVPPv1 $hivpp */ - $hivpp = $response->findSegment(HIVPPv1::class); - if ($hivpp === null) { - throw new UnexpectedResponseException('Missing HIVPP in response to a request with HKVPP'); - } - if ($hivpp->vopId === null) { - throw new UnexpectedResponseException('Missing HIVPP.vopId even though VOP should be completed.'); - } - - $verificationNotApplicableReason = null; - if ($hivpp->paymentStatusReport === null) { - if ($hivpp->ergebnisVopPruefungEinzeltransaktion === null) { - throw new UnsupportedException('Missing paymentStatusReport and ergebnisVopPruefungEinzeltransaktion'); - } - $verificationResult = VopVerificationResult::parse( - $hivpp->ergebnisVopPruefungEinzeltransaktion->vopPruefergebnis - ); - $verificationNotApplicableReason = $hivpp->ergebnisVopPruefungEinzeltransaktion->grundRVNA; - } else { - $report = simplexml_load_string($hivpp->paymentStatusReport->getData()); - $verificationResult = VopVerificationResult::parse( - $report->CstmrPmtStsRpt->OrgnlGrpInfAndSts->GrpSts ?: null - ); - - // For a single transaction, we can do better than "CompletedPartialMatch", - // which can indicate either CompletedCloseMatch or CompletedNoMatch - if (intval($report->CstmrPmtStsRpt->OrgnlGrpInfAndSts->OrgnlNbOfTxs ?: 0) === 1 - && $verificationResult === VopVerificationResult::CompletedPartialMatch - && $verificationResultCode = $report->CstmrPmtStsRpt->OrgnlPmtInfAndSts->TxInfAndSts?->TxSts - ) { - $verificationResult = VopVerificationResult::parse($verificationResultCode); - } - } - - return new VopConfirmationRequestImpl( - $hivpp->vopId, - $hivpp->vopIdGueltigBis?->asDateTime(), - $hivpp->aufklaerungstextAutorisierungTrotzAbweichung, - $verificationResult, - $verificationNotApplicableReason, - ); - } - - /** - * @param VopConfirmationRequestImpl $vopConfirmationRequest The VOP request we're confirming. - * @return HKVPAv1 A HKVPA segment that tells the bank the request is good to execute. - */ - public static function createHKVPAForConfirmation(VopConfirmationRequestImpl $vopConfirmationRequest): HKVPAv1 - { - $hkvpa = HKVPAv1::createEmpty(); - $hkvpa->vopId = $vopConfirmationRequest->getVopId(); - return $hkvpa; - } -} diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/HIWPD.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/HIWPD.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/HIWPDS.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/HIWPDS.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/HIWPDSv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/HIWPDSv5.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/HIWPDv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/HIWPDv5.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/HKWPDv5.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/HKWPDv5.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/ParameterDepotaufstellung.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/ParameterDepotaufstellung.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/ParameterDepotaufstellungV2.php b/vendor/nemiah/php-fints/lib/Fhp/Segment/WPD/ParameterDepotaufstellungV2.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Syntax/Bin.php b/vendor/nemiah/php-fints/lib/Fhp/Syntax/Bin.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Syntax/Delimiter.php b/vendor/nemiah/php-fints/lib/Fhp/Syntax/Delimiter.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Fhp/Syntax/InvalidResponseException.php b/vendor/nemiah/php-fints/lib/Fhp/Syntax/InvalidResponseException.php old mode 100644 new mode 100755 index f69f75d..c6fe5f8 --- a/vendor/nemiah/php-fints/lib/Fhp/Syntax/InvalidResponseException.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Syntax/InvalidResponseException.php @@ -7,7 +7,7 @@ namespace Fhp\Syntax; */ class InvalidResponseException extends \RuntimeException { - public function __construct(string $message, int $code = 0, ?\Exception $previous = null) + public function __construct(string $message, int $code = 0, \Exception $previous = null) { parent::__construct($message, $code, $previous); } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Syntax/Parser.php b/vendor/nemiah/php-fints/lib/Fhp/Syntax/Parser.php old mode 100644 new mode 100755 index 57c8ba2..8f29052 --- a/vendor/nemiah/php-fints/lib/Fhp/Syntax/Parser.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Syntax/Parser.php @@ -159,8 +159,8 @@ abstract class Parser $delimiterPos = strpos($rawValue, Delimiter::BINARY, 1); if ( - substr($rawValue, 0, 1) !== Delimiter::BINARY - || $delimiterPos === false + substr($rawValue, 0, 1) !== Delimiter::BINARY || + $delimiterPos === false ) { throw new \InvalidArgumentException("Expected binary block header, got $rawValue"); } @@ -192,10 +192,8 @@ abstract class Parser $rawElements = static::splitEscapedString(Delimiter::GROUP, $rawElements); list($result, $offset) = static::parseDegElements($rawElements, $type, $allowEmpty); if ($offset < count($rawElements)) { - // Bank sends more elements than expected - ignore extra elements instead of failing - // This happens when the bank uses a newer format version than the library supports - error_log("FinTS Parser: Ignoring " . (count($rawElements) - $offset) . " extra elements in DEG " . - (is_string($type) ? $type : get_class($type)) . ': ' . print_r(array_slice($rawElements, $offset), true)); + throw new \InvalidArgumentException( + "Expected only $offset elements, but got " . count($rawElements) . ': ' . print_r($rawElements, true)); } return $result; } @@ -207,7 +205,7 @@ abstract class Parser * write to (the same instance will be returned from this function). * @param bool $allowEmpty If true, this returns either a valid DEG, or null if *all* the fields were empty. * @param int $offset The position in $rawElements to be read next. - * @return array (BaseDeg|null, int) + * @return array (BaseDeg|null, integer) * 1. The parsed value, which has the given $type or is null in case all the fields were empty and $allowEmpty * is true. * 2. The offset at which parsing should continue. The difference between this returned offset and the $offset @@ -457,7 +455,14 @@ abstract class Parser $segmentType = static::SEGMENT_NAMESPACE . '\\' . $segmentkopf->segmentkennung . '\\' . $segmentkopf->segmentkennung . 'v' . $segmentkopf->segmentversion; if (class_exists($segmentType)) { - return static::parseSegment($rawSegment, $segmentType); + try { + return static::parseSegment($rawSegment, $segmentType); + } catch (\InvalidArgumentException $e) { + // Segment-Klasse passt nicht zur Bank-Antwort, Fallback auf anonymous + error_log("[phpFinTS Parser] Segment " . $segmentkopf->segmentkennung . "v" + . $segmentkopf->segmentversion . " Parsing fehlgeschlagen: " . $e->getMessage() + . " - verwende AnonymousSegment"); + } } // Alternatively, allow Geschäftsvorfall segments (HKXYZ, HIXYZ and HIXYZS) to live in an abbreviated namespace, @@ -465,10 +470,17 @@ abstract class Parser $segmentType = static::SEGMENT_NAMESPACE . '\\' . substr($segmentkopf->segmentkennung, 2, 3) . '\\' . $segmentkopf->segmentkennung . 'v' . $segmentkopf->segmentversion; if (class_exists($segmentType)) { - return static::parseSegment($rawSegment, $segmentType); + try { + return static::parseSegment($rawSegment, $segmentType); + } catch (\InvalidArgumentException $e) { + // Segment-Klasse passt nicht zur Bank-Antwort, Fallback auf anonymous + error_log("[phpFinTS Parser] Segment " . $segmentkopf->segmentkennung . "v" + . $segmentkopf->segmentversion . " Parsing fehlgeschlagen (kurzer Namespace): " + . $e->getMessage() . " - verwende AnonymousSegment"); + } } - // If the segment type is not implemented, fall back to an anonymous segment. + // If the segment type is not implemented (or parsing failed), fall back to an anonymous segment. return static::parseAnonymousSegment($rawSegment); } diff --git a/vendor/nemiah/php-fints/lib/Fhp/Syntax/Serializer.php b/vendor/nemiah/php-fints/lib/Fhp/Syntax/Serializer.php old mode 100644 new mode 100755 index c0d64ff..a5d1430 --- a/vendor/nemiah/php-fints/lib/Fhp/Syntax/Serializer.php +++ b/vendor/nemiah/php-fints/lib/Fhp/Syntax/Serializer.php @@ -71,15 +71,6 @@ abstract class Serializer return implode(Delimiter::ELEMENT, static::flattenAndTrimEnd($serializedElements)) . Delimiter::SEGMENT; } - /** - * @param BaseSegment[] $segments The segments to be serialized. - * @return string The concatenated HBCI wire format representation of the segments. - */ - public static function serializeSegments(array $segments): string - { - return implode(array_map([self::class, 'serializeSegment'], $segments)); - } - /** * @param BaseSegment|BaseDeg|null $obj An object to be serialized. If null, all fields are implicitly null. * @param BaseDescriptor $descriptor The descriptor for the object to be serialized. @@ -110,27 +101,11 @@ abstract class Serializer throw new \InvalidArgumentException( "Expected array value for $descriptor->class.$elementDescriptor->field, got: $value"); } - if ($elementDescriptor->repeated === PHP_INT_MAX) { - // For an uncapped repeated field (with @Unlimited), it must be the very last field and we do not - // need to insert padding elements, so we only output its actual contents. - if ($index !== $lastKey) { - throw new \AssertionError( - "Expected unlimited field at $index to be the last one, but the last one is $lastKey" - ); - } - $numOutputElements = count($value); - } else { - // For a capped repeated field (with @Max), we need to output the specified number of elements, such - // that subsequent fields will be at the right place. If this is the last field, the trailing empty - // elements will be trimmed away again by flattenAndTrimEnd() later. - $numOutputElements = $elementDescriptor->repeated; - } - for ($repetition = 0; $repetition < $numOutputElements; ++$repetition) { + for ($repetition = 0; $repetition < $elementDescriptor->repeated; ++$repetition) { $serializedElements[$index + $repetition] = static::serializeElement( $value === null || $repetition >= count($value) ? null : $value[$repetition], $elementDescriptor->type, $isSegment); } - $index += $numOutputElements - 1; // The outer loop will increment by 1 as well. } } return $serializedElements; @@ -145,7 +120,7 @@ abstract class Serializer */ private static function serializeElement($value, $type, bool $fullySerialize) { - if (is_string($type)) { // Scalar value / DE + if (is_string($type)) { return static::serializeDataElement($value, $type); } elseif ($type->getName() === Bin::class) { /* @var Bin|null $value */ diff --git a/vendor/nemiah/php-fints/lib/Fhp/UnsupportedException.php b/vendor/nemiah/php-fints/lib/Fhp/UnsupportedException.php old mode 100644 new mode 100755 index 2365ff2..9c1ca4d --- a/vendor/nemiah/php-fints/lib/Fhp/UnsupportedException.php +++ b/vendor/nemiah/php-fints/lib/Fhp/UnsupportedException.php @@ -7,7 +7,7 @@ namespace Fhp; */ class UnsupportedException extends \RuntimeException { - public function __construct(string $message, int $code = 0, ?\Exception $previous = null) + public function __construct(string $message, int $code = 0, \Exception $previous = null) { parent::__construct($message, $code, $previous); } diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Action/SendSEPATransferTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Action/SendSEPATransferTest.php deleted file mode 100644 index 03a8151..0000000 --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/Action/SendSEPATransferTest.php +++ /dev/null @@ -1,43 +0,0 @@ -initDialog(); - $this->expectMessage($this->getSendTransferRequest(), static::SEND_TRANSFER_RESPONSE); - $originalAction = $this->runInitialRequest(); - - // The key behavior we need is that the action produces the same request again after (un)serialization. It is - // not necessary for us to check the field values inside the action directly. - $originalRequest = $originalAction->getNextRequest($this->fints->getBpd(), null); - $this->assertIsArray($originalRequest); - Message::setSegmentNumbers($originalRequest, 42); - - // Sanity-check that the request we're getting is something sensible (not empty string or so). - $serializedRequest = Serializer::serializeSegments($originalRequest); - $this->assertStringContainsString('HKCCS', $serializedRequest); - $this->assertStringContainsString('DE42000000001234567890', $serializedRequest); - - // Do a serialization roundtrip. - $serializedAction = serialize($originalAction); - $unserializedAction = unserialize($serializedAction); - - // Verify that the request is still the same. - $newRequest = $unserializedAction->getNextRequest($this->fints->getBpd(), null); - $this->assertIsArray($newRequest); - Message::setSegmentNumbers($newRequest, 42); - $this->assertEquals($originalRequest, $newRequest); - } -} diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/BaseActionTanSerializationTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/BaseActionTanSerializationTest.php deleted file mode 100644 index a33b2fd..0000000 --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/BaseActionTanSerializationTest.php +++ /dev/null @@ -1,32 +0,0 @@ -initDialog(); - $this->expectMessage($this->getSendTransferRequest(), static::SEND_TRANSFER_RESPONSE); - $originalAction = $this->runInitialRequest(); - - // Sanity-check that the TAN request is present. - $this->assertNotNull($originalAction->getTanRequest()); - $this->assertNotNull($originalAction->getNeedTanForSegment()); - - // Do a serialization roundtrip. - $serializedAction = serialize($originalAction); - $unserializedAction = unserialize($serializedAction); - - // Verify that the TAN request hasn't changed. - $this->assertEquals($originalAction->getTanRequest(), $unserializedAction->getTanRequest()); - $this->assertEquals($originalAction->getNeedTanForSegment(), $unserializedAction->getNeedTanForSegment()); - } -} diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/BaseActionVopSerializationTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/BaseActionVopSerializationTest.php deleted file mode 100644 index 5546c14..0000000 --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/BaseActionVopSerializationTest.php +++ /dev/null @@ -1,58 +0,0 @@ -initDialog(); - $originalAction = $this->createAction(); - $this->expectMessage(static::SEND_TRANSFER_REQUEST, mb_convert_encoding(static::SEND_TRANSFER_RESPONSE_POLLING_NEEDED, 'ISO-8859-1', 'UTF-8')); - $this->fints->execute($originalAction); - - // Sanity-check that the polling is now expected. - $this->assertNotNull($originalAction->getPollingInfo()); - - // Do a serialization roundtrip. - $serializedAction = serialize($originalAction); - $unserializedAction = unserialize($serializedAction); - - // Verify that the polling info is still the same. - $this->assertEquals($originalAction->getPollingInfo(), $unserializedAction->getPollingInfo()); - } - - /** - * @throws \Throwable - */ - public function testSerializesVopConfirmationRequest() - { - // We piggy-back on the Atruvia integration test to provide an action that has some reasonable data inside and - // has already been executed so that polling is now required. - $this->initDialog(); - $originalAction = $this->createAction(); - $this->expectMessage(static::SEND_TRANSFER_REQUEST, mb_convert_encoding(static::SEND_TRANSFER_RESPONSE_POLLING_NEEDED, 'ISO-8859-1', 'UTF-8')); - $response = static::buildVopReportResponse(static::VOP_REPORT_PARTIAL_MATCH_RESPONSE, static::VOP_REPORT_PARTIAL_MATCH_XML_PAYLOAD); - $this->expectMessage(static::POLL_VOP_REQUEST, $response); - $this->fints->execute($originalAction); - $this->assertTrue($originalAction->needsPollingWait()); - $this->fints->pollAction($originalAction); - - // Sanity-check that the VOP confirmation is now expected. - $this->assertNotNull($originalAction->getVopConfirmationRequest()); - - // Do a serialization roundtrip. - $serializedAction = serialize($originalAction); - $unserializedAction = unserialize($serializedAction); - - // Verify that the polling info is still the same. - $this->assertEquals($originalAction->getVopConfirmationRequest(), $unserializedAction->getVopConfirmationRequest()); - } -} diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/CLILogger.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/CLILogger.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/FinTsPeer.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/FinTsPeer.php old mode 100644 new mode 100755 index 3ee01d5..3a6e276 --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/FinTsPeer.php +++ b/vendor/nemiah/php-fints/lib/Tests/Fhp/FinTsPeer.php @@ -13,27 +13,32 @@ use Fhp\Protocol\ServerException; */ class FinTsPeer extends FinTs { - public static ?Connection $mockConnection = null; + /** + * @var Connection + */ + public static $mockConnection; public function __construct(FinTsOptions $options, ?Credentials $credentials) { parent::__construct($options, $credentials); } + /** {@inheritdoc} */ protected function newConnection(): Connection { return self::$mockConnection; } /** + * {@inheritdoc} * @throws ServerException */ - public function endDialog(bool $isAnonymous = false): void // parent::endDialog() is protected + public function endDialog(bool $isAnonymous = false) // parent::endDialog() is protected { parent::endDialog($isAnonymous); } - public function getDialogId(): ?string + public function getDialogId() { return $this->dialogId; } diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/FinTsTestCase.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/FinTsTestCase.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Atruvia/AtruviaIntegrationTestBase.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Atruvia/AtruviaIntegrationTestBase.php deleted file mode 100644 index efdd455..0000000 --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Atruvia/AtruviaIntegrationTestBase.php +++ /dev/null @@ -1,90 +0,0 @@ -expectMessage(static::ANONYMOUS_INIT_REQUEST, mb_convert_encoding(static::ANONYMOUS_INIT_RESPONSE, 'ISO-8859-1', 'UTF-8')); - $this->expectMessage(static::ANONYMOUS_END_REQUEST, mb_convert_encoding(static::ANONYMOUS_END_RESPONSE, 'ISO-8859-1', 'UTF-8')); - - $this->fints->getBpd(); - } - - /** - * Executes dialog synchronization and initialization, so that BPD and UPD are filled. - * @throws \Throwable - */ - protected function initDialog() - { - // We already know the TAN mode, so it will only fetch the BPD (anonymously) to verify it. - $this->expectMessage(static::ANONYMOUS_INIT_REQUEST, mb_convert_encoding(static::ANONYMOUS_INIT_RESPONSE, 'ISO-8859-1', 'UTF-8')); - $this->expectMessage(static::ANONYMOUS_END_REQUEST, mb_convert_encoding(static::ANONYMOUS_END_RESPONSE, 'ISO-8859-1', 'UTF-8')); - - // Then when we initialize a dialog, it's going to request a Kundensystem-ID and UPD. - $this->expectMessage(static::SYNC_REQUEST, mb_convert_encoding(static::SYNC_RESPONSE, 'ISO-8859-1', 'UTF-8')); - $this->expectMessage(static::SYNC_END_REQUEST, mb_convert_encoding(static::SYNC_END_RESPONSE, 'ISO-8859-1', 'UTF-8')); - - // And finally it can initialize the main dialog. - $this->expectMessage(static::INIT_REQUEST, mb_convert_encoding(static::INIT_RESPONSE, 'ISO-8859-1', 'UTF-8')); - - $this->fints->selectTanMode(intval(static::TEST_TAN_MODE)); - $login = $this->fints->login(); - $login->ensureDone(); // No TAN required upon login.*/ - $this->assertAllMessagesSeen(); - } - - protected function getTestAccount(): SEPAAccount - { - $sepaAccount = new SEPAAccount(); - $sepaAccount->setIban('DE00ABCDEFGH1234567890'); - $sepaAccount->setBic('ABCDEFGHIJK'); - $sepaAccount->setAccountNumber('1234567890'); - $sepaAccount->setBlz(self::TEST_BANK_CODE); - return $sepaAccount; - } -} diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Atruvia/SendTransferVoPTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Atruvia/SendTransferVoPTest.php deleted file mode 100644 index 19bb3a7..0000000 --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Atruvia/SendTransferVoPTest.php +++ /dev/null @@ -1,247 +0,0 @@ -' . "\n" - . 'M12345678902025-10-10T12:52:56+02:00110.00PRIVATE__________________P12345678TRF110.00SEPA
1999-01-01
PRIVATE__________________DE00ABCDEFGH1234567890ABCDEFGHIJKSLEVNOTPROVIDED10.00EmpfängerDE00ABCDEFGH1234567890Testüberweisung
' - ); - - public const SEND_TRANSFER_REQUEST = ( - 'HKCCS:3:1+DE00ABCDEFGH1234567890:ABCDEFGHIJK:1234567890::280:11223344+urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.001.001.09+@1161@' . - self::XML_PAYLOAD . - "'HKTAN:4:7+4+HKCCS'HKVPP:5:1+urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.002.001.10'" - ); - public const SEND_TRANSFER_RESPONSE_POLLING_NEEDED = "HIRMG:3:2+3060::Bitte beachten Sie die enthaltenen Warnungen/Hinweise.+3905::Es wurde keine Challenge erzeugt.'HIRMS:4:2:5+3040::Es liegen weitere Informationen vor.:staticscrollref'HIRMS:5:2:4+3945::Freigabe ohne VOP-Bestätigung nicht möglich.'HIVPP:6:1:5+++@36@c0f5c2a4-ebb7-4e72-be44-c68742177a2b+++++2'"; - public const SEND_TRANSFER_RESPONSE_IMMEDIATE_SUCCESS = "HIRMG:3:2+3060::Bitte beachten Sie die enthaltenen Warnungen/Hinweise.+3905::Es wurde keine Challenge erzeugt.'HIRMS:4:2:5+3091::VOP-Ausführungsauftrag nicht benötigt.+0025::Keine Namensabweichung.'HIRMS:5:2:4+3076::Keine starke Authentifizierung erforderlich.'HIVPP:6:1:5+@36@5e3b5c99-df27-4d42-835b-18b35d0c66ff+++urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.002.001.10'HITAN:6:7:4+4++noref+nochallenge'HIRMS:7:2:3+0020::*SEPA-Einzelüberweisung erfolgreich+0900::Freigabe erfolgreich'"; - - public const POLL_VOP_REQUEST = "HKVPP:3:1+urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.002.001.10+@36@c0f5c2a4-ebb7-4e72-be44-c68742177a2b++staticscrollref'"; - - public const VOP_REPORT_MATCH_RESPONSE = "HIRMG:3:2+0010::Nachricht entgegengenommen.'HIRMS:4:2:3+0020::Auftrag ausgeführt.+0025::Keine Namensabweichung.'HIVPP:5:1:3+@36@5e3b5c99-df27-4d42-835b-18b35d0c66ff+++urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.002.001.10'"; - public const VOP_REPORT_MATCH_NO_CONFIRMATION_RESPONSE = "HIRMG:3:2+0010::Nachricht entgegengenommen.'HIRMS:4:2:3+3091::VOP-Ausführungsauftrag nicht benötigt.+0025::Keine Namensabweichung.'HIVPP:5:1:3+@36@5e3b5c99-df27-4d42-835b-18b35d0c66ff+++urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.002.001.10'HITAN:6:7:5+4++1234567890123456789012345678+Bitte bestätigen Sie den Vorgang in Ihrer SecureGo plus App'"; - public const VOP_REPORT_MATCH_XML_PAYLOAD = "ATRUVIA-20251013-125258-XXXXXXXXXXXXXXXX2025-10-13T11:36:04.201+02:00ABCDEFGHIJKM1234567890pain.001.001.091100.00RCVCRCVC Der von Ihnen eingegebene Name des Zahlungsempfängers stimmt mit dem für diese IBANRCVC hinterlegten Namen bei der Zahlungsempfängerbank überein.RVMC Der von Ihnen eingegebene Name des Zahlungsempfängers stimmt nahezu mit dem für diese IBANRVMC hinterlegten Namen bei der Zahlungsempfängerbank überein. Die Autorisierung der ZahlungRVMC kann dazu führen, dass das Geld auf ein Konto überwiesen wird, dessen Inhaber nichtRVMC der von Ihnen angegebene Empfänger ist. In diesem Fall haften die Zahlungsdienstleister nicht fürRVMC die Folgen der fehlenden Übereinstimmung, insbesondere besteht kein Anspruch auf Rückerstattung.RVNM Der von Ihnen eingegebene Name des Zahlungsempfängers stimmt nicht mit dem für diese IBAN hinter-RVNM legten Namen bei der Zahlungsempfängerbank überein. Bitte prüfen Sie den Empfängernamen. Die Autori-RVNM sierung der Zahlung kann dazu führen, dass das Geld auf ein Konto überwiesen wird, dessen InhaberRVNM nicht der von Ihnen angegebene Empfänger ist. In diesem Fall haften die Zahlungsdienstleister nichtRVNM für die Folgen der fehlenden Übereinstimmung, insbesondere besteht kein Anspruch auf Rückerstattung.RVNA Der von Ihnen eingegebene Name des Zahlungsempfängers konnte nicht mit dem für diese IBAN hinter-RVNA legten Namen bei der Zahlungsempfängerbank abgeglichen werden (z.B. technischer Fehler). Die Autori-RVNA sierung der Zahlung kann dazu führen, dass das Geld auf ein Konto überwiesen wird, dessen InhaberRVNA nicht der von Ihnen angegebene Empfänger ist. In diesem Fall haften die Zahlungsdienstleister nichtRVNA für die Folgen der fehlenden Übereinstimmung, insbesondere besteht kein Anspruch auf Rückerstattung.1RCVC0RVMC0RVNM0RVNA176034816211RCVC0RVMC0RVNM0RVNANOTPROVIDEDRCVCTestempfängerDE00ABCDEFGH1234567890"; - - public const VOP_REPORT_PARTIAL_MATCH_RESPONSE = "HIRMG:3:2+3060::Bitte beachten Sie die enthaltenen Warnungen/Hinweise.'HIRMS:4:2:3+3090::Ergebnis des Namensabgleichs prüfen.'HIVPP:5:1:3+@36@5e3b5c99-df27-4d42-835b-18b35d0c66ff+++urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.002.001.10+++Bei mindestens einem Zahlungsempfänger stimmt der Name mit dem für diese IBAN bei der Zahlungsempfängerbank hinterlegten Namen nicht oder nur nahezu überein.
Alternativ konnte der Name des Zahlungsempfängers nicht mit dem bei der Zahlungsempfängerbank hinterlegten Namen abgeglichen werden.

Eine nicht mögliche Empfängerüberprüfung kann auftreten, wenn ein technisches Problem vorliegt, die Empfängerbank diesen Service nicht anbietet oder eine Prüfung für das Empfängerkonto nicht möglich ist.

Wichtiger Hinweis?: Die Überweisung wird ohne Korrektur ausgeführt.

Dies kann dazu führen, dass das Geld auf ein Konto überwiesen wird, dessen Inhaber nicht der von Ihnen angegebene Empfänger ist.
In diesem Fall haftet die Bank nicht für die Folgen der fehlenden Übereinstimmung, insbesondere besteht kein Anspruch auf Rückerstattung.

Eine Haftung der an der Ausführung der Überweisung beteiligten Zahlungsdienstleister ist ebenfalls ausgeschlossen.'"; - public const VOP_REPORT_PARTIAL_MATCH_XML_PAYLOAD = "ATRUVIA-20251010-125258-X2025-10-10T12:52:58.283+02:00ABCDEFGHIJKM1234567890pain.001.001.09110.00RVCMRCVC Der von Ihnen eingegebene Name des Zahlungsempfängers stimmt mit dem für diese IBANRCVC hinterlegten Namen bei der Zahlungsempfängerbank überein.RVMC Der von Ihnen eingegebene Name des Zahlungsempfängers stimmt nahezu mit dem für diese IBANRVMC hinterlegten Namen bei der Zahlungsempfängerbank überein. Die Autorisierung der ZahlungRVMC kann dazu führen, dass das Geld auf ein Konto überwiesen wird, dessen Inhaber nichtRVMC der von Ihnen angegebene Empfänger ist. In diesem Fall haften die Zahlungsdienstleister nicht fürRVMC die Folgen der fehlenden Übereinstimmung, insbesondere besteht kein Anspruch auf Rückerstattung.RVNM Der von Ihnen eingegebene Name des Zahlungsempfängers stimmt nicht mit dem für diese IBAN hinter-RVNM legten Namen bei der Zahlungsempfängerbank überein. Bitte prüfen Sie den Empfängernamen. Die Autori-RVNM sierung der Zahlung kann dazu führen, dass das Geld auf ein Konto überwiesen wird, dessen InhaberRVNM nicht der von Ihnen angegebene Empfänger ist. In diesem Fall haften die Zahlungsdienstleister nichtRVNM für die Folgen der fehlenden Übereinstimmung, insbesondere besteht kein Anspruch auf Rückerstattung.RVNA Der von Ihnen eingegebene Name des Zahlungsempfängers konnte nicht mit dem für diese IBAN hinter-RVNA legten Namen bei der Zahlungsempfängerbank abgeglichen werden (z.B. technischer Fehler). Die Autori-RVNA sierung der Zahlung kann dazu führen, dass das Geld auf ein Konto überwiesen wird, dessen InhaberRVNA nicht der von Ihnen angegebene Empfänger ist. In diesem Fall haften die Zahlungsdienstleister nichtRVNA für die Folgen der fehlenden Übereinstimmung, insbesondere besteht kein Anspruch auf Rückerstattung.0RCVC0RVMC1RVNM0RVNA176009357610RCVC0RVMC1RVNM0RVNANOTPROVIDEDRVNMTestempfängerDE00ABCDEFGH1234567890"; - - public const CONFIRM_VOP_REQUEST = ( - 'HKCCS:3:1+DE00ABCDEFGH1234567890:ABCDEFGHIJK:1234567890::280:11223344+urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.001.001.09+@1161@' - . self::XML_PAYLOAD - . "'HKVPA:4:1+@36@5e3b5c99-df27-4d42-835b-18b35d0c66ff'HKTAN:5:7+4+HKCCS'" - ); - public const CONFIRM_VOP_RESPONSE = "HIRMG:3:2+3060::Bitte beachten Sie die enthaltenen Warnungen/Hinweise.'HIRMS:4:2:4+0020::Ausführungsbestätigung nach Namensabgleich erhalten.'HIRMS:5:2:5+3955::Sicherheitsfreigabe erfolgt über anderen Kanal.'HITAN:6:7:5+4++1234567890123456789012345678+Bitte bestätigen Sie den Vorgang in Ihrer SecureGo plus App'"; - - public const CHECK_DECOUPLED_SUBMISSION_REQUEST = "HKTAN:3:7+S++++1234567890123456789012345678+N'"; - public const CHECK_DECOUPLED_SUBMISSION_RESPONSE = "HIRMG:3:2+0010::Nachricht entgegengenommen.'HIRMS:4:2:3+0020::*SEPA-Einzelüberweisung erfolgreich+0900::Freigabe erfolgreich'HITAN:5:7:3+S++1234567890123456789012345678'"; - - /** - * @throws \Throwable - */ - public function testVopWithResultMatchButConfirmationRequired(): void - { - $this->initDialog(); - $action = $this->createAction(); - - // We send the transfer and the bank asks to wait while VOP is happening. - $this->expectMessage(static::SEND_TRANSFER_REQUEST, mb_convert_encoding(static::SEND_TRANSFER_RESPONSE_POLLING_NEEDED, 'ISO-8859-1', 'UTF-8')); - $this->fints->execute($action); - $this->assertTrue($action->needsPollingWait()); - $this->assertFalse($action->needsVopConfirmation()); - $this->assertFalse($action->needsTan()); - $this->assertFalse($action->isDone()); - $this->assertEquals(2, $action->getPollingInfo()->getNextAttemptInSeconds()); - - // We poll the bank for the first and only time, now the VOP process is done, the result is available, and it's - // a match (CompletedFullMatch). But the bank still asks for the VOP confirmation. - $response = static::buildVopReportResponse(static::VOP_REPORT_MATCH_RESPONSE, static::VOP_REPORT_MATCH_XML_PAYLOAD); - $this->expectMessage(static::POLL_VOP_REQUEST, $response); - $this->fints->pollAction($action); - $this->assertFalse($action->needsPollingWait()); - $this->assertTrue($action->needsVopConfirmation()); - $this->assertFalse($action->needsTan()); - $this->assertFalse($action->isDone()); - $this->assertEquals( - VopVerificationResult::CompletedFullMatch, - $action->getVopConfirmationRequest()->getVerificationResult() - ); - - // We confirm to the bank that it's okay to proceed, the bank asks for decoupled 2FA authentication. - $this->expectMessage(static::CONFIRM_VOP_REQUEST, mb_convert_encoding(static::CONFIRM_VOP_RESPONSE, 'ISO-8859-1', 'UTF-8')); - $this->fints->confirmVop($action); - $this->assertFalse($action->needsPollingWait()); - $this->assertFalse($action->needsVopConfirmation()); - $this->assertTrue($action->needsTan()); - $this->assertFalse($action->isDone()); - $this->assertEquals( - 'Bitte bestätigen Sie den Vorgang in Ihrer SecureGo plus App', - $action->getTanRequest()->getChallenge() - ); - - // After having completed the 2FA on the other device (not shown in this unit test), we ask the bank again, and - // it confirms that the transfer was executed. - $this->expectMessage(static::CHECK_DECOUPLED_SUBMISSION_REQUEST, mb_convert_encoding(static::CHECK_DECOUPLED_SUBMISSION_RESPONSE, 'ISO-8859-1', 'UTF-8')); - $this->fints->checkDecoupledSubmission($action); - $this->assertFalse($action->needsPollingWait()); - $this->assertFalse($action->needsVopConfirmation()); - $this->assertFalse($action->needsTan()); - $this->assertTrue($action->isDone()); - - $action->ensureDone(); - } - - /** - * @throws \Throwable - */ - public function testVopWithResultPartialMatch(): void - { - $this->initDialog(); - $action = $this->createAction(); - - // We send the transfer and the bank asks to wait while VOP is happening. - $this->expectMessage(static::SEND_TRANSFER_REQUEST, mb_convert_encoding(static::SEND_TRANSFER_RESPONSE_POLLING_NEEDED, 'ISO-8859-1', 'UTF-8')); - $this->fints->execute($action); - $this->assertTrue($action->needsPollingWait()); - $this->assertFalse($action->needsVopConfirmation()); - $this->assertFalse($action->needsTan()); - $this->assertFalse($action->isDone()); - $this->assertEquals(2, $action->getPollingInfo()->getNextAttemptInSeconds()); - - // We poll the bank for the first and only time, now the VOP process is done and the VOP result is available, - // but the payee didn't match, and so we're being asked to confirm. - $response = static::buildVopReportResponse(static::VOP_REPORT_PARTIAL_MATCH_RESPONSE, static::VOP_REPORT_PARTIAL_MATCH_XML_PAYLOAD); - $this->expectMessage(static::POLL_VOP_REQUEST, $response); - $this->fints->pollAction($action); - $this->assertFalse($action->needsPollingWait()); - $this->assertTrue($action->needsVopConfirmation()); - $this->assertFalse($action->needsTan()); - $this->assertFalse($action->isDone()); - $this->assertEquals( - VopVerificationResult::CompletedNoMatch, - $action->getVopConfirmationRequest()->getVerificationResult() - ); - - // We confirm to the bank that it's okay to proceed, the bank asks for decoupled 2FA authentication. - $this->expectMessage(static::CONFIRM_VOP_REQUEST, mb_convert_encoding(static::CONFIRM_VOP_RESPONSE, 'ISO-8859-1', 'UTF-8')); - $this->fints->confirmVop($action); - $this->assertFalse($action->needsPollingWait()); - $this->assertFalse($action->needsVopConfirmation()); - $this->assertTrue($action->needsTan()); - $this->assertFalse($action->isDone()); - $this->assertEquals( - 'Bitte bestätigen Sie den Vorgang in Ihrer SecureGo plus App', - $action->getTanRequest()->getChallenge() - ); - - // After having completed the 2FA on the other device (not shown in this unit test), we ask the bank again, and - // it confirms that the transfer was executed. - $this->expectMessage(static::CHECK_DECOUPLED_SUBMISSION_REQUEST, mb_convert_encoding(static::CHECK_DECOUPLED_SUBMISSION_RESPONSE, 'ISO-8859-1', 'UTF-8')); - $this->fints->checkDecoupledSubmission($action); - $this->assertFalse($action->needsPollingWait()); - $this->assertFalse($action->needsVopConfirmation()); - $this->assertFalse($action->needsTan()); - $this->assertTrue($action->isDone()); - - $action->ensureDone(); - } - - /** - * This is a hypothetical test case in the sense that it wasn't recorded based on real traffic with the bank, but - * constructed based on what the specification has to say. - * @see FinTS_3.0_Messages_Geschaeftsvorfaelle_VOP_1.01_2025_06_27_FV.pdf (E.8.1.1.1 and exclude red part). - * @throws \Throwable - */ - public function testVopWithResultMatchWithoutConfirmation(): void - { - $this->initDialog(); - $action = $this->createAction(); - - // We send the transfer and the bank asks to wait while VOP is happening. - $this->expectMessage(static::SEND_TRANSFER_REQUEST, mb_convert_encoding(static::SEND_TRANSFER_RESPONSE_POLLING_NEEDED, 'ISO-8859-1', 'UTF-8')); - $this->fints->execute($action); - $this->assertTrue($action->needsPollingWait()); - $this->assertFalse($action->needsVopConfirmation()); - $this->assertFalse($action->needsTan()); - $this->assertFalse($action->isDone()); - $this->assertEquals(2, $action->getPollingInfo()->getNextAttemptInSeconds()); - - // We poll the bank for the first and only time, now the VOP process is done, the result is available, and it's - // a match (CompletedFullMatch). The bank does not want a VOP confirmation (as indicated by code 3091), so we - // move straight on to 2FA authentication. - $response = static::buildVopReportResponse( - static::VOP_REPORT_MATCH_NO_CONFIRMATION_RESPONSE, - static::VOP_REPORT_MATCH_XML_PAYLOAD - ); - $this->expectMessage(static::POLL_VOP_REQUEST, $response); - $this->fints->pollAction($action); - $this->assertFalse($action->needsPollingWait()); - $this->assertFalse($action->needsVopConfirmation()); - $this->assertTrue($action->needsTan()); - $this->assertFalse($action->isDone()); - // Note: We currently lack an API for applications to retrieve the CompletedFullMatch result in this case, - // because the VOP check itself is no longer actionable. - $this->assertEquals( - 'Bitte bestätigen Sie den Vorgang in Ihrer SecureGo plus App', - $action->getTanRequest()->getChallenge() - ); - - // After having completed the 2FA on the other device (not shown in this unit test), we ask the bank again, and - // it confirms that the transfer was executed. - $this->expectMessage(static::CHECK_DECOUPLED_SUBMISSION_REQUEST, mb_convert_encoding(static::CHECK_DECOUPLED_SUBMISSION_RESPONSE, 'ISO-8859-1', 'UTF-8')); - $this->fints->checkDecoupledSubmission($action); - $this->assertFalse($action->needsPollingWait()); - $this->assertFalse($action->needsVopConfirmation()); - $this->assertFalse($action->needsTan()); - $this->assertTrue($action->isDone()); - - $action->ensureDone(); - } - - /** - * This is a hypothetical test case in the sense that it wasn't recorded based on real traffic with the bank, but - * constructed based on what the specification has to say. - * @see FinTS_3.0_Messages_Geschaeftsvorfaelle_VOP_1.01_2025_06_27_FV.pdf (E.8.1 bullet point 2.). - * @throws \Throwable - */ - public function testVopWithResultImmediateSuccess(): void - { - $this->initDialog(); - $action = $this->createAction(); - - // We send the transfer and the bank asks to wait while VOP is happening. - $this->expectMessage(static::SEND_TRANSFER_REQUEST, mb_convert_encoding(static::SEND_TRANSFER_RESPONSE_IMMEDIATE_SUCCESS, 'ISO-8859-1', 'UTF-8')); - $this->fints->execute($action); - $this->assertFalse($action->needsPollingWait()); - $this->assertFalse($action->needsVopConfirmation()); - $this->assertFalse($action->needsTan()); - $this->assertTrue($action->isDone()); - - $action->ensureDone(); - } - - protected function createAction(): SendSEPATransfer - { - return SendSEPATransfer::create($this->getTestAccount(), self::XML_PAYLOAD); - } - - protected static function buildVopReportResponse( - string $outerFintsMessageInUtf8, - string $innerXmlInUtf8, - ): string { - $segments = Parser::parseSegments(mb_convert_encoding($outerFintsMessageInUtf8, 'ISO-8859-1', 'UTF-8')); - foreach ($segments as $segment) { - if ($segment instanceof HIVPPv1) { - $segment->paymentStatusReport = new Bin($innerXmlInUtf8); - } - } - return Serializer::serializeSegments($segments); - } -} diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Consors/ConsorsIntegrationTestBase.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Consors/ConsorsIntegrationTestBase.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Consors/GetBPDTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Consors/GetBPDTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Consors/GetSEPAAccountsTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Consors/GetSEPAAccountsTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Consors/GetStatementOfAccountTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Consors/GetStatementOfAccountTest.php old mode 100644 new mode 100755 index a492764..466f554 --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Consors/GetStatementOfAccountTest.php +++ b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Consors/GetStatementOfAccountTest.php @@ -10,17 +10,15 @@ class GetStatementOfAccountTest extends ConsorsIntegrationTestBase public const GET_STATEMENT_REQUEST = "HKKAZ:3:7+DExxABCDEFGH1234567890:CSDBDE71XXX:1234567890::280:50220500+N+20190601+20190922'HKTAN:4:6+4+HKKAZ'"; // Note: Consorsbank weirdly returns November statements even when only up to September was requested. - public const GET_STATEMENT_RESPONSE = ( - "HIRMG:2:2:+3060::Teilweise liegen Warnungen/Hinweise vor.'HIRMS:3:2:3+0020::Der Auftrag wurde ausgefuhrt.+3076::Keine starke Authentifizierung erforderlich.+3997::Der Auftrag wurde nur teilweise ausgefuhrt.'" - . "HIKAZ:4:7:3+@1034@\r\n" - . ":20:0\r\n:21:NONREF\r\n:25:50220500/123456789\r\n:28C:0/7\r\n:60M:C191118EUR950,59\r\n" - . ":61:1911181118D2,8N008NONREF\r\n:86:008?00Dauerauftrag?20EREF+NOTPROVIDED ?21 ?\r\n22KREF+NONREF?23SVWZ+XY?30BICBICBICBI?31DExx444444444444444444?32\r\nMax Mustermannig\r\n:62M:C191118EUR947,79\r\n-\r\n" - . ":20:0\r\n:21:NONREF\r\n:25:50220500/123456789\r\n:28C:0/8\r\n:60M:C191120EUR947,79\r\n" - . ":61:1911201120D11,3N005NONREF\r\n:86:005?00Lastschrift (Einzugsermächtigung)?20EREF+ZAA0987654321 \r\n ?21 ?22KREF+NONREF?23SVWZ+LogPay OnlineTicket i.?\r\n24A.v. Irgendeine Firma und S?25oehne AG. Ihre Kundenn r. 2?26019\r\n999999999?30BICBICBI?31DExx555555555555555555?32LOGPAY FINANCIAL \r\nSERVICES G?33MBH\r\n" - . ":61:1911201120D15,5N005NONREF\r\n:86:005?00Lastschrift (Einzugsermächtigung)?20EREF+ZAA0123456789 \r\n ?21 ?22KREF+NONREF?23SVWZ+LogPay OnlineTicket i.?\r\n24A.v. Irgendeine Firma und S?25oehne AG. Ihre Kundenn r. 2?26019\r\n999999999?30BICBICBI?31DExx555555555555555555?32LOGPAY FINANCIAL \r\nSERVICES G?33MBH\r\n" - . ":62F:C191120EUR920,99\r\n-'" - . "HITAN:5:6:4+4++noref+nochallenge'" - ); + public const GET_STATEMENT_RESPONSE = "HIRMG:2:2:+3060::Teilweise liegen Warnungen/Hinweise vor.'HIRMS:3:2:3+0020::Der Auftrag wurde ausgefuhrt.+3076::Keine starke Authentifizierung erforderlich.+3997::Der Auftrag wurde nur teilweise ausgefuhrt.'" + . "HIKAZ:4:7:3+@1034@\r\n" + . ":20:0\r\n:21:NONREF\r\n:25:50220500/123456789\r\n:28C:0/7\r\n:60M:C191118EUR950,59\r\n" + . ":61:1911181118D2,8N008NONREF\r\n:86:008?00Dauerauftrag?20EREF+NOTPROVIDED ?21 ?\r\n22KREF+NONREF?23SVWZ+XY?30BICBICBICBI?31DExx444444444444444444?32\r\nMax Mustermannig\r\n:62M:C191118EUR947,79\r\n-\r\n" + . ":20:0\r\n:21:NONREF\r\n:25:50220500/123456789\r\n:28C:0/8\r\n:60M:C191120EUR947,79\r\n" + . ":61:1911201120D11,3N005NONREF\r\n:86:005?00Lastschrift (Einzugsermächtigung)?20EREF+ZAA0987654321 \r\n ?21 ?22KREF+NONREF?23SVWZ+LogPay OnlineTicket i.?\r\n24A.v. Irgendeine Firma und S?25oehne AG. Ihre Kundenn r. 2?26019\r\n999999999?30BICBICBI?31DExx555555555555555555?32LOGPAY FINANCIAL \r\nSERVICES G?33MBH\r\n" + . ":61:1911201120D15,5N005NONREF\r\n:86:005?00Lastschrift (Einzugsermächtigung)?20EREF+ZAA0123456789 \r\n ?21 ?22KREF+NONREF?23SVWZ+LogPay OnlineTicket i.?\r\n24A.v. Irgendeine Firma und S?25oehne AG. Ihre Kundenn r. 2?26019\r\n999999999?30BICBICBI?31DExx555555555555555555?32LOGPAY FINANCIAL \r\nSERVICES G?33MBH\r\n" + . ":62F:C191120EUR920,99\r\n-'" + . "HITAN:5:6:4+4++noref+nochallenge'"; // Note: There is no HIKAZ at all in this response, but it's still valid. public const GET_STATEMENT_EMPTY_RESPONSE = "HIRMG:2:2:+3060::Teilweise liegen Warnungen/Hinweise vor.'HIRMS:3:2:3+3010::Keine Umsatze gefunden+3076::Keine starke Authentifizierung erforderlich.'HITAN:4:6:4+4++noref+nochallenge'"; diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Consors/InitEndDialogTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Consors/InitEndDialogTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/DKBIntegrationTestBase.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/DKBIntegrationTestBase.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/GetBalanceTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/GetBalanceTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/GetSEPAAccountsTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/GetSEPAAccountsTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/GetStatementOfAccountTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/GetStatementOfAccountTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/InitEndDialogTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/InitEndDialogTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/SendSEPATransferTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/SendSEPATransferTest.php old mode 100644 new mode 100755 index cdaa011..b409aee --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/SendSEPATransferTest.php +++ b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/DKB/SendSEPATransferTest.php @@ -81,7 +81,7 @@ class SendSEPATransferTest extends DKBIntegrationTestBase public const SEND_TAN_REQUEST = "HNHBK:1:3+000000000425+300+FAKEDIALOGIDabcdefghijklmnopqr+3'HNVSK:998:3+PIN:2+998+1+1::FAKEKUNDENSYSTEMIDabcdefghij+1:20190102:030405+2:2:13:@8@00000000:5:1+280:12030000:test?@user:V:0:0+0'HNVSD:999:1+@206@HNSHK:2:4+PIN:2+921+9999999+1+1+1::FAKEKUNDENSYSTEMIDabcdefghij+1+1:20190102:030405+1:999:1+6:10:19+280:12030000:test?@user:S:0:0'HKTAN:3:6+2++++2472-12-07-21.27.57.456789+N'HNSHA:4:2+9999999++12345:666555''HNHBS:5:1+3'"; public const SEND_TAN_RESPONSE = "HIRMG:3:2+0010::Nachricht entgegengenommen.'HIRMS:4:2:3+0010::Der Auftrag wurde entgegengenommen.'HITAN:5:6:3+2++2472-12-07-21.27.57.456789'"; - protected function getSendTransferRequest(): string + private function getSendTransferRequest(): string { // Note: strlen() is computed instead of hard-coded because it depends on the indentation in this file, which // may be changed by linters and other tools, and because it contains line breaks, which are different depending @@ -93,7 +93,7 @@ class SendSEPATransferTest extends DKBIntegrationTestBase /** * @throws \Throwable */ - protected function runInitialRequest(): SendSEPATransfer + private function runInitialRequest(): SendSEPATransfer { $sendTransfer = SendSEPATransfer::create($this->getTestAccount(), static::PAIN_MESSAGE); $this->fints->execute($sendTransfer); diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/GLS/GLSIntegrationTestBase.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/GLS/GLSIntegrationTestBase.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/GLS/GetStatementOfAccountXMLTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/GLS/GetStatementOfAccountXMLTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/GLS/InitEndDialogTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/GLS/InitEndDialogTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/IngDiba/GetSEPAAccountsTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/IngDiba/GetSEPAAccountsTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/IngDiba/GetStatementOfAccountTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/IngDiba/GetStatementOfAccountTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/IngDiba/IngDibaIntegrationTestBase.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/IngDiba/IngDibaIntegrationTestBase.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/IngDiba/InitDialogWithBlockedPinTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/IngDiba/InitDialogWithBlockedPinTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/IngDiba/InitEndDialogTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/IngDiba/InitEndDialogTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/InitializationErrorTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/InitializationErrorTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/KSK/Biberach/GetBPDTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/KSK/Biberach/GetBPDTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/KSK/Biberach/KskBiberachIntegrationTestBase.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/KSK/Biberach/KskBiberachIntegrationTestBase.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/KSK/InitDialogWithBlockedPinTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/KSK/InitDialogWithBlockedPinTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/KSK/KSKIntegrationTestBase.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/KSK/KSKIntegrationTestBase.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Postbank/GetSEPAAccountsTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Postbank/GetSEPAAccountsTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Postbank/InitDialogWithBlockedPinTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Postbank/InitDialogWithBlockedPinTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Postbank/InitEndDialogTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Postbank/InitEndDialogTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Postbank/PostbankIntegrationTestBase.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Integration/Postbank/PostbankIntegrationTestBase.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Model/FlickerTan/TanRequestChallengeFlickerTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Model/FlickerTan/TanRequestChallengeFlickerTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Options/SanitizingLoggerTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Options/SanitizingLoggerTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Protocol/DialogInitializationTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Protocol/DialogInitializationTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Protocol/DialogInitializationTestModel.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Protocol/DialogInitializationTestModel.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Protocol/ServerExceptionTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Protocol/ServerExceptionTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/AnonymousSegmentTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/AnonymousSegmentTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/Common/TspTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/Common/TspTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/FindRueckmeldungTraitTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/FindRueckmeldungTraitTest.php deleted file mode 100644 index 3b9ce9a..0000000 --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/FindRueckmeldungTraitTest.php +++ /dev/null @@ -1,62 +0,0 @@ -testMessage = Message::createPlainMessage( - MessageBuilder::create() - ->add(Parser::parseSegments(self::TEST_RESPONSE)) - ); - } - - public function testFindRueckmeldungFound() - { - $this->assertEquals('Angemeldet.', $this->testMessage->findRueckmeldung(20)->rueckmeldungstext); - $this->assertEquals([900], $this->testMessage->findRueckmeldung(3920)->rueckmeldungsparameter); - } - - public function testFindRueckmeldungNotFound() - { - $this->assertNull($this->testMessage->findRueckmeldung(42)); - } - - public function testFindRueckmeldungen() - { - $this->assertCount(3, $this->testMessage->findRueckmeldungen(20)); - $this->assertCount(1, $this->testMessage->findRueckmeldungen(3920)); - $this->assertCount(0, $this->testMessage->findRueckmeldungen(42)); - } - - public function testGetAllRueckmeldungen() - { - /** @var HIRMGv2 $hirmg */ - $hirmg = $this->testMessage->findSegmentByNumber(2); - $this->assertCount(1, $hirmg->getAllRueckmeldungen()); - - /** @var HIRMSv2 $hirms */ - $hirms = $this->testMessage->findSegmentByNumber(3); - $this->assertCount(3, $hirms->getAllRueckmeldungen()); - } - - public function testFindRueckmeldungscodesForReferenceSegment() - { - $this->assertEquals([20, 3076, 901], $this->testMessage->findRueckmeldungscodesForReferenceSegment(3)); - $this->assertEquals([20, 3920], $this->testMessage->findRueckmeldungscodesForReferenceSegment(4)); - $this->assertEquals([20], $this->testMessage->findRueckmeldungscodesForReferenceSegment(6)); - } -} diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HICAZTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HICAZTest.php old mode 100644 new mode 100755 index 54e61d9..77ecf67 --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HICAZTest.php +++ b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HICAZTest.php @@ -13,69 +13,59 @@ class HICAZTest extends \PHPUnit\Framework\TestCase // Inside segemnts several XMLs can be present, seperated by ":" private const HICAZ_TEST_START = 'HICAZ:5:1:3+DE06940594210000027227:TESTDETT421:::280:+urn?:iso?:std?:iso?:20022?:tech?:xsd?:camt.052.001.02+'; - private const SAMPLE_XML_DOC1 = ( - '' . - '' . - 'camt52_20131118101510__ONLINEBA' . - '2013-11-18T10:15:10+01:001true' . - 'camt052_ONLINEBA' . - 'BOOK' . - 'BOOK' . - '' - ); - private const SAMPLE_XML_DOC2 = ( - '' . - '' . - 'camt52_20131118101510__ONLINEBA' . - '2013-11-18T10:15:10+01:001true' . - 'camt052_ONLINEBA' . - 'BOOK' . - 'BOOK' . - 'BOOK' . - 'BOOK' . - '' - ); - private const SAMPLE_XML_DOC3 = ( - '' . - '' . - 'camt52_20131118101510__ONLINEBA' . - '2013-11-18T10:15:10+01:001true' . - 'camt052_ONLINEBA' . - 'PDNG' . - '' - ); + private const SAMPLE_XML_DOC1 = '' . + '' . + 'camt52_20131118101510__ONLINEBA' . + '2013-11-18T10:15:10+01:001true' . + 'camt052_ONLINEBA' . + 'BOOK' . + 'BOOK' . + ''; + private const SAMPLE_XML_DOC2 = '' . + '' . + 'camt52_20131118101510__ONLINEBA' . + '2013-11-18T10:15:10+01:001true' . + 'camt052_ONLINEBA' . + 'BOOK' . + 'BOOK' . + 'BOOK' . + 'BOOK' . + ''; + private const SAMPLE_XML_DOC3 = '' . + '' . + 'camt52_20131118101510__ONLINEBA' . + '2013-11-18T10:15:10+01:001true' . + 'camt052_ONLINEBA' . + 'PDNG' . + ''; public function testHICAZparse() { // First example: two XMLs seperated by ":" - both are gebuchteUmsaetze - $hicaz1 = HICAZv1::parse( - static::HICAZ_TEST_START . - '@' . strlen(static::SAMPLE_XML_DOC1) . '@' . - static::SAMPLE_XML_DOC1 . - ':' . - '@' . strlen(static::SAMPLE_XML_DOC2) . '@' . - static::SAMPLE_XML_DOC2 . - "'" - ); + $hicaz1 = HICAZv1::parse(static::HICAZ_TEST_START . + '@' . strlen(static::SAMPLE_XML_DOC1) . '@' . + static::SAMPLE_XML_DOC1 . + ':' . + '@' . strlen(static::SAMPLE_XML_DOC2) . '@' . + static::SAMPLE_XML_DOC2 . + "'"); $this->assertEquals([static::SAMPLE_XML_DOC1, static::SAMPLE_XML_DOC2], $hicaz1->getGebuchteUmsaetze()); // Second example: two areas seperated by +, first area has a group of two XMLs seperated by : - $hicaz2 = HICAZv1::parse( - static::HICAZ_TEST_START . - '@' . strlen(static::SAMPLE_XML_DOC1) . '@' . - static::SAMPLE_XML_DOC1 . - ':@' . strlen(static::SAMPLE_XML_DOC2) . '@' . - static::SAMPLE_XML_DOC2 . - '+@' . strlen(static::SAMPLE_XML_DOC3) . '@' . - static::SAMPLE_XML_DOC3 . - "'" - ); + $hicaz2 = HICAZv1::parse(static::HICAZ_TEST_START . + '@' . strlen(static::SAMPLE_XML_DOC1) . '@' . + static::SAMPLE_XML_DOC1 . + ':@' . strlen(static::SAMPLE_XML_DOC2) . '@' . + static::SAMPLE_XML_DOC2 . + '+@' . strlen(static::SAMPLE_XML_DOC3) . '@' . + static::SAMPLE_XML_DOC3 . + "'"); $this->assertEquals([static::SAMPLE_XML_DOC1, static::SAMPLE_XML_DOC2], $hicaz2->getGebuchteUmsaetze()); $this->assertEquals(static::SAMPLE_XML_DOC3, diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HISALTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HISALTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HITABTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HITABTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HITANSTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HITANSTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HIUPATest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HIUPATest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HIUPDTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HIUPDTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HIVPPSTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HIVPPSTest.php deleted file mode 100644 index 54cbf19..0000000 --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HIVPPSTest.php +++ /dev/null @@ -1,44 +0,0 @@ -hivpps = HIVPPSv1::createEmpty(); - $this->hivpps->setSegmentNumber(42); - $this->hivpps->maximaleAnzahlAuftraege = 43; - $this->hivpps->anzahlSignaturenMindestens = 44; - $this->hivpps->sicherheitsklasse = 45; - $this->hivpps->parameter = new ParameterNamensabgleichPruefauftragV1(); - $this->hivpps->parameter->maximaleAnzahlCreditTransferTransactionInformationOptIn = 1; - $this->hivpps->parameter->aufklaerungstextStrukturiert = true; - $this->hivpps->parameter->artDerLieferungPaymentStatusReport = 'Art'; - $this->hivpps->parameter->sammelzahlungenMitEinemAuftragErlaubt = false; - $this->hivpps->parameter->eingabeAnzahlEintraegeErlaubt = false; - $this->hivpps->parameter->unterstuetztePaymentStatusReportDatenformate = 'Test'; - } - - public function testPopulatedArray() - { - $this->hivpps->parameter->vopPflichtigerZahlungsverkehrsauftrag = ['HKFOO', 'HKBAR']; - - $serialized = $this->hivpps->serialize(); - $this->assertEquals("HIVPPS:42:1+43+44+45+1:J:Art:N:N:Test:HKFOO:HKBAR'", $serialized); - - /** @var HIVPPSv1 $parsed */ - $parsed = Parser::parseSegment($serialized, HIVPPSv1::class); - $this->assertEquals(['HKFOO', 'HKBAR'], $parsed->parameter->vopPflichtigerZahlungsverkehrsauftrag); - } -} diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HKCCSTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HKCCSTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HKSPATest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HKSPATest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HKVPPTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HKVPPTest.php deleted file mode 100644 index 99ab281..0000000 --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HKVPPTest.php +++ /dev/null @@ -1,28 +0,0 @@ -setSegmentNumber(42); - $hkvpp->unterstuetztePaymentStatusReports->paymentStatusReportDescriptor = ['A', 'B', 'C']; - - $serialized = $hkvpp->serialize(); - $this->assertEquals("HKVPP:42:1+A:B:C'", $serialized); - - /** @var HKVPPv1 $hkvpp */ - $hkvpp = Parser::parseSegment($serialized, HKVPPv1::class); - $this->assertEquals(42, $hkvpp->getSegmentNumber()); - $this->assertEquals(['A', 'B', 'C'], $hkvpp->unterstuetztePaymentStatusReports->paymentStatusReportDescriptor); - } -} diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HNVSDTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HNVSDTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HNVSKTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/HNVSKTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/SegmentComparator.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/SegmentComparator.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/UpdSerializationTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/UpdSerializationTest.php deleted file mode 100644 index 8df47a6..0000000 --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/Segment/UpdSerializationTest.php +++ /dev/null @@ -1,33 +0,0 @@ -assertEquals(static::HIUPD, Serializer::serializeSegment($hiupd)); - } - - public function testNativePhpSerialization(): void - { - /** @var HIUPDv6 $hiupd */ - $hiupd = Parser::parseSegment(static::HIUPD, HIUPDv6::class); - $before = $hiupd->getErlaubteGeschaeftsvorfaelle(); - - /** @var HIUPDv6 $hiupd */ - $hiupd = unserialize(serialize($hiupd)); - $after = $hiupd->getErlaubteGeschaeftsvorfaelle(); - - $this->assertEquals($before, $after); - } -} diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Syntax/BinTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Syntax/BinTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Syntax/ParserTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Syntax/ParserTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Syntax/SerializerTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Syntax/SerializerTest.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/Fhp/Unit/SendSEPADirectDebitTest.php b/vendor/nemiah/php-fints/lib/Tests/Fhp/Unit/SendSEPADirectDebitTest.php old mode 100644 new mode 100755 index f92c4a8..96d7d82 --- a/vendor/nemiah/php-fints/lib/Tests/Fhp/Unit/SendSEPADirectDebitTest.php +++ b/vendor/nemiah/php-fints/lib/Tests/Fhp/Unit/SendSEPADirectDebitTest.php @@ -2,6 +2,7 @@ namespace Tests\Fhp\Unit; + use Fhp\Action\SendSEPADirectDebit; use Fhp\Model\SEPAAccount; use Tests\Fhp\FinTsTestCase; diff --git a/vendor/nemiah/php-fints/lib/Tests/phpunit_bootstrap.php b/vendor/nemiah/php-fints/lib/Tests/phpunit_bootstrap.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/lib/Tests/resources/pain.008.002.02.xml b/vendor/nemiah/php-fints/lib/Tests/resources/pain.008.002.02.xml old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/phpunit.xml.dist b/vendor/nemiah/php-fints/phpunit.xml.dist old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/prettify_message.php b/vendor/nemiah/php-fints/prettify_message.php old mode 100644 new mode 100755 diff --git a/vendor/nemiah/php-fints/prettify_segment.php b/vendor/nemiah/php-fints/prettify_segment.php old mode 100644 new mode 100755

'.img_picto('', 'upload', 'class="pictofixedwidth"').$langs->trans("UploadPDFStatement").''.$langs->trans("UploadPDFStatement").'