Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.28% covered (success)
98.28%
57 / 58
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
TatraBankaMailParser
98.28% covered (success)
98.28%
57 / 58
0.00% covered (danger)
0.00%
0 / 1
16
0.00% covered (danger)
0.00%
0 / 1
 parse
98.28% covered (success)
98.28%
57 / 58
0.00% covered (danger)
0.00%
0 / 1
16
1<?php
2declare(strict_types=1);
3
4namespace Tomaj\BankMailsParser\Parser\TatraBanka;
5
6use DateTimeImmutable;
7use Tomaj\BankMailsParser\MailContent;
8use Tomaj\BankMailsParser\Parser\ParserInterface;
9
10class TatraBankaMailParser implements ParserInterface
11{
12    /**
13     * @param $content
14     * @return ?MailContent
15     */
16    public function parse(string $content): ?MailContent
17    {
18        $mailContent = new MailContent();
19
20        $pattern1 = '/(.*) bol zostatok Vasho uctu ([a-zA-Z0-9]+) (zvyseny|znizeny) o ([0-9 ]+,[0-9]+) ([a-zA-Z]+)/m';
21        $res = preg_match($pattern1, $content, $result);
22        if (!$res) {
23            return null;
24        }
25
26        $transactionDateFormats = [
27            'j. n. Y G:i', // "19. 5. 2026 0:34"
28            'j.n.Y G:i',   // "19.5.2026 9:40"
29        ];
30        $transactionDate = false; // backward compatible default
31        foreach ($transactionDateFormats as $format) {
32            $parsedDate = DateTimeImmutable::createFromFormat($format, $result[1]);
33            if ($parsedDate) {
34                $transactionDate = $parsedDate->getTimestamp();
35                break;
36            }
37        }
38        if (!$transactionDate) {
39            $transactionDate = strtotime($result[1]);
40        }
41        $mailContent->setTransactionDate($transactionDate);
42
43        $mailContent->setAccountNumber($result[2]);
44
45        $amount = floatval(str_replace(',', '.', str_replace(' ', '', $result[4])));
46        $currency = $result[5];
47        if ($result[3] === 'znizeny') {
48            $amount = -$amount;
49        }
50        $mailContent->setAmount($amount);
51        $mailContent->setCurrency($currency);
52
53        $pattern = '/Informacia pre prijemcu: (.*)/m';
54        $res = preg_match($pattern, $content, $result);
55        if ($res) {
56            $mailContent->setReceiverMessage($result[1]);
57        }
58
59        // loads VS provided in format:
60        // - Referencia platitela: /VS1234056789/SS/KS
61        $pattern = '/Referencia platitela: \/VS(.*)\/SS(.*)\/KS(.*)/m';
62        $res = preg_match($pattern, $content, $result);
63        if ($res) {
64            $mailContent->setVs($result[1]);
65            $mailContent->setSs($result[2]);
66            $mailContent->setKs($result[3]);
67        }
68
69        // search whole email for number with `vs` prefix
70        if ($mailContent->getVs() === null) {
71            $pattern = '/vs([0-9]{1,10})/i';
72            $res = preg_match($pattern, $content, $result);
73            if ($res) {
74                $mailContent->setVs($result[1]);
75            }
76        }
77
78        // if still no number found, check receiver message
79        // - some payers incorrectly set this field with VS number but without "VS" prefix
80        // - some banks send here variable symbol in Creditor Reference Information - SEPA XML format
81        // loads VS provided in formats:
82        // - Informacia pre prijemcu: 1234056789
83        // - Informacia pre prijemcu: (CdtrRefInf)(Tp)(CdOrPrtry)(Cd)SCOR(/Cd)(/CdOrPrtry)(/Tp)(Ref)1234056789(/Ref)(/CdtrRefInf)
84        if ($mailContent->getVs() === null) {
85            $pattern = '/Informacia pre prijemcu:.*\b([0-9]{1,10})\b.*/i';
86            $res = preg_match($pattern, $content, $result);
87            if ($res) {
88                $mailContent->setVs($result[1]);
89            }
90        }
91
92        // if still no number found, check unique mandate reference
93        // some payers incorrectly set this field without correct prefixes /VS/SS/KS
94        // loads VS provided in format:
95        // - Referencia platitela: 1234056789
96        if ($mailContent->getVs() === null) {
97            $pattern = '/Referencia platitela:.*\b([0-9]{1,10})\b.*/i';
98            $res = preg_match($pattern, $content, $result);
99            if ($res) {
100                $mailContent->setVs($result[1]);
101            }
102        }
103
104        $pattern4 = '/Popis transakcie: (.*)/m';
105        $res = preg_match($pattern4, $content, $result);
106        if ($res) {
107            $mailContent->setDescription($result[1]);
108
109            $descriptionParts = explode(' ', $result[1], 2);
110            $hasPrefix = count($descriptionParts) === 2;
111            $mailContent->setSourceAccountNumber($descriptionParts[$hasPrefix ? 1 : 0]);
112        }
113
114        return $mailContent;
115    }
116}