$to) { throw new \InvalidArgumentException('From-date must be before to-date'); } $result = new GetStatementOfAccount(); $result->account = $account; $result->from = $from; $result->to = $to; $result->allAccounts = $allAccounts; $result->includeUnbooked = $includeUnbooked; 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->from, $this->to, $this->allAccounts, $this->bankName, ]; } /** * @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->from, $this->to, $this->allAccounts, $this->bankName ) = $serialized; is_array($parentSerialized) ? parent::__unserialize($parentSerialized) : parent::unserialize($parentSerialized); } /** * @return string The raw MT940 data received from the server. * @noinspection PhpUnused */ public function getRawMT940(): string { $this->ensureDone(); return $this->rawMT940; } /** * @return array The parsed MT940 data. */ public function getParsedMT940(): array { $this->ensureDone(); return $this->parsedMT940; } public function getStatement(): StatementOfAccount { $this->ensureDone(); return $this->statement; } /** {@inheritdoc} */ protected function createRequest(BPD $bpd, ?UPD $upd) { $this->bankName = $bpd->getBankName(); /** @var HIKAZS $hikazs */ $hikazs = $bpd->requireLatestSupportedParameters('HIKAZS'); if ($this->allAccounts && !$hikazs->getParameter()->getAlleKontenErlaubt()) { throw new \InvalidArgumentException('The bank do not permit the use of allAccounts=true'); } switch ($hikazs->getVersion()) { case 4: return HKKAZv4::create(Kto::fromAccount($this->account), $this->from, $this->to); case 5: return HKKAZv5::create(KtvV3::fromAccount($this->account), $this->allAccounts, $this->from, $this->to); case 6: return HKKAZv6::create(KtvV3::fromAccount($this->account), $this->allAccounts, $this->from, $this->to); case 7: return HKKAZv7::create(Kti::fromAccount($this->account), $this->allAccounts, $this->from, $this->to); default: throw new UnsupportedException('Unsupported HKKAZ version: ' . $hikazs->getVersion()); } } /** {@inheritdoc} */ public function processResponse(Message $response) { parent::processResponse($response); // Banks send just 3010 and no HIKAZ in case there are no transactions. $isUnavailable = $response->findRueckmeldung(Rueckmeldungscode::NICHT_VERFUEGBAR) !== null; $responseHikaz = $response->findSegments(HIKAZ::class); $numResponseSegments = count($responseHikaz); if (!$isUnavailable && $numResponseSegments < count($this->getRequestSegmentNumbers())) { throw new UnexpectedResponseException("Only got $numResponseSegments HIKAZ response segments!"); } /** @var HIKAZ $hikaz */ foreach ($responseHikaz as $hikaz) { $this->rawMT940 .= $hikaz->getGebuchteUmsaetze()->getData(); if ($this->includeUnbooked and $hikaz->getNichtGebuchteUmsaetze() !== null) { $this->rawMT940 .= $hikaz->getNichtGebuchteUmsaetze()->getData(); } } // Note: Pagination boundaries may cut in the middle of the MT940 data, so it is not possible to parse a partial // reponse before having received all pages. if (!$this->hasMorePages()) { $this->parseMt940(); } } private function parseMt940() { if (str_contains(strtolower($this->bankName), 'sparda')) { $parser = new SpardaMT940(); } elseif (str_contains(strtolower($this->bankName), 'postbank')) { $parser = new PostbankMT940(); } else { $parser = new MT940(); } try { // Note: Some banks encode their MT 940 data as SWIFT/ISO-8859 like it should be according to the // specification (e.g. DKB), others just send UTF-8 (e.g. Consorsbank), so we try to detect it here. $rawMT940 = mb_detect_encoding($this->rawMT940, 'UTF-8', true) === false ? mb_convert_encoding($this->rawMT940, 'UTF-8', 'ISO-8859-1') : $this->rawMT940; $this->parsedMT940 = $parser->parse($rawMT940); $this->statement = StatementOfAccount::fromMT940Array($this->parsedMT940); } catch (MT940Exception $e) { throw new \InvalidArgumentException('Invalid MT940 data', 0, $e); } } }