Knab::parseStatementEndTimestamp()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Kingsquare\Parser\Banking\Mt940\Engine;
4
5
use Kingsquare\Parser\Banking\Mt940\Engine;
6
use Kingsquare\Banking\Transaction\Type;
7
8
/**
9
 * Knab parser for Kingsquare mt940 package.
10
 *
11
 * @package Kingsquare\Parser\Banking\Mt940\Engine
12
 * @author Kingsquare ([email protected])
13
 * @author Sam Mousa ([email protected])
14
 * @license http://opensource.org/licenses/MIT MIT
15
 */
16
class Knab extends Engine
17
{
18
    const IBAN = '[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}(?:[a-zA-Z0-9]?){0,16}';
19
20
    /**
21
     * @inheritdoc
22
     */
23
    protected function parseStatementBank()
24
    {
25
        return 'KNAB';
26
    }
27
28
    /**
29
     * @inheritdoc
30
     */
31
    protected function parseStatementStartPrice()
32
    {
33
        return $this->parseStatementPrice('60[FM]');
34
    }
35
36
    /**
37
     * @inheritdoc
38
     */
39
    protected function parseStatementEndPrice()
40
    {
41
        return $this->parseStatementPrice('62[FM]');
42
    }
43
44
    /**
45
     * @inheritdoc
46
     */
47
    protected function parseStatementStartTimestamp()
48
    {
49
        return $this->parseTimestampFromStatement('60[FM]');
50
    }
51
52
    /**
53
     * @inheritdoc
54
     */
55
    protected function parseStatementEndTimestamp()
56
    {
57
        return $this->parseTimestampFromStatement('62[FM]');
58
    }
59
60
    /**
61
     * @inheritdoc
62
     */
63
    protected function parseTransactionAccount()
64
    {
65
        $results = [];
66
67
        // SEPA MT940 Structured
68
        if (preg_match('/^:86:.*?\/IBAN\/(' . self::IBAN . ')/ims', $this->getCurrentTransactionData(), $results)
69
            && !empty($results[1])
70
        ) {
71
            return $this->sanitizeAccount($results[1]);
72
        }
73
74
75
        $pattern = '/^:86:.*?REK:\s*(?<account>' . self::IBAN . '|\d+)/ims';
76
        if (preg_match($pattern, $this->getCurrentTransactionData(), $results)
77
            && !empty($results['account'])
78
        ) {
79
            return $results['account'];
80
        }
81
82
        if (
83
            preg_match('/^:86:.*?\/BBAN\/(\d{8})/ims', $this->getCurrentTransactionData(), $results)
84
            && !empty($results[1])
85
        ) {
86
            return $this->sanitizeAccount($results[1]);
87
        }
88
89
        return '';
90
    }
91
92
    /**
93
     * @inheritdoc
94
     */
95
    protected function parseTransactionAccountName()
96
    {
97
        $results = [];
98
99
        // SEPA MT940 Structured
100
        if (preg_match('#/NAME/(.*?)/(EREF|REMI|ADDR)/#ms', $this->getCurrentTransactionData(), $results)
101
            && !empty($results[1])
102
        ) {
103
            $accountName = trim($results[1]);
104
            if (!empty($accountName)) {
105
                return $this->sanitizeAccountName($accountName);
106
            }
107
        }
108
109
        if (preg_match('/NAAM: (.+)/', $this->getCurrentTransactionData(), $results)
110
            && !empty($results[1])
111
        ) {
112
            return trim($results[1]);
113
        }
114
        if (preg_match('#/NAME/(.*?)\n?/(REMI|CSID)/#ms', $this->getCurrentTransactionData(), $results)
115
            && !empty($results[1])
116
        ) {
117
            return trim($results[1]);
118
        }
119
120
        return '';
121
    }
122
123
    /**
124
     * @inheritdoc
125
     */
126
    protected function parseTransactionDescription()
127
    {
128
        $description = parent::parseTransactionDescription();
129
130
        // SEPA MT940 Structured
131
        if (strpos($description, '/REMI/') !== false
132
            && preg_match('#/REMI/(.*)[/:]?#', $description, $results) && !empty($results[1])
133
        ) {
134
            return $results[1];
135
        }
136
137
        $accountIsInDescription = strpos($description, 'REK:');
138
        if ($accountIsInDescription !== false) {
139
            return trim(substr($description, 0, $accountIsInDescription));
140
        }
141
142
        $name = $this->parseTransactionAccountName();
143
        if ($name === '') {
144
            return $description;
145
        }
146
        $accountNameIsInDescription = strpos($description, $name);
147
        if ($accountNameIsInDescription !== false) {
148
            return trim(substr($description, 0, $accountNameIsInDescription - 6));
149
        }
150
        return $description;
151
    }
152
153
    /**
154
     * @inheritdoc
155
     */
156
    public static function isApplicable($string)
157
    {
158
        $firstline = strtok($string, "\r\n\t");
159
        return strpos($firstline, 'F01KNABNL2HAXXX0000000000') !== false;
160
    }
161
162
    /**
163
     * @TODO WIP get this into the transaction somehow.. (possibly as a decorator over the transactions?)
164
     * @return int
165
     */
166
    protected function parseTransactionType()
167
    {
168
        static $map = [
169
            541 => Type::SEPA_TRANSFER,
170
            544 => Type::SEPA_TRANSFER,
171
            547 => Type::SEPA_TRANSFER,
172
            64 => Type::SEPA_DIRECTDEBIT,
173
            93 => Type::BANK_COSTS,
174
            13 => Type::PAYMENT_TERMINAL,
175
            30 => Type::PAYMENT_TERMINAL,
176
            'MSC' => Type::BANK_INTEREST,
177
            'TRF' => Type::UNKNOWN,
178
        ];
179
180
        $code = $this->parseTransactionCode();
181
        if (array_key_exists($code, $map)) {
182
            return $map[$code];
183
        }
184
        throw new \RuntimeException("Don't know code $code for this bank");
185
    }
186
187
}
188