Passed
Push — master ( 2c0c97...e77480 )
by Robin
01:12
created

Knab::parseTransactionType()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 14
nc 2
nop 0
dl 0
loc 19
rs 9.7998
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('60M');
34
    }
35
36
    /**
37
     * @inheritdoc
38
     */
39
    protected function parseStatementEndPrice()
40
    {
41
        return $this->parseStatementPrice('62M');
42
    }
43
44
    /**
45
     * @inheritdoc
46
     */
47
    protected function parseStatementStartTimestamp()
48
    {
49
        return $this->parseTimestampFromStatement('60M');
50
    }
51
52
    /**
53
     * @inheritdoc
54
     */
55
    protected function parseStatementEndTimestamp()
56
    {
57
        return $this->parseTimestampFromStatement('62M');
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
        return '';
83
    }
84
85
    /**
86
     * @inheritdoc
87
     */
88
    protected function parseTransactionAccountName()
89
    {
90
        $results = [];
91
92
        // SEPA MT940 Structured
93
        if (preg_match('#/NAME/(.*?)/(EREF|REMI|ADDR)/#ms', $this->getCurrentTransactionData(), $results)
94
            && !empty($results[1])
95
        ) {
96
            $accountName = trim($results[1]);
97
            if (!empty($accountName)) {
98
                return $this->sanitizeAccountName($accountName);
99
            }
100
        }
101
102
        if (preg_match('/NAAM: (.+)/', $this->getCurrentTransactionData(), $results)
103
            && !empty($results[1])
104
        ) {
105
            return trim($results[1]);
106
        }
107
        if (preg_match('#/NAME/(.*?)\n?/(REMI|CSID)/#ms', $this->getCurrentTransactionData(), $results)
108
            && !empty($results[1])
109
        ) {
110
            return trim($results[1]);
111
        }
112
113
        return '';
114
    }
115
116
    /**
117
     * @inheritdoc
118
     */
119
    protected function parseTransactionDescription()
120
    {
121
        $description = parent::parseTransactionDescription();
122
123
        // SEPA MT940 Structured
124
        if (strpos($description, '/REMI/') !== false
125
            && preg_match('#/REMI/(.*)[/:]?#', $description, $results) && !empty($results[1])
126
        ) {
127
            return $results[1];
128
        }
129
130
        $accountIsInDescription = strpos($description, 'REK:');
131
        if ($accountIsInDescription !== false) {
132
            return trim(substr($description, 0, $accountIsInDescription));
133
        }
134
135
        $name = $this->parseTransactionAccountName();
136
        if ($name === '') {
137
            return $description;
138
        }
139
        $accountNameIsInDescription = strpos($description, $name);
140
        if ($accountNameIsInDescription !== false) {
141
            return trim(substr($description, 0, $accountNameIsInDescription - 6));
142
        }
143
        return $description;
144
    }
145
146
    /**
147
     * @inheritdoc
148
     */
149
    public static function isApplicable($string)
150
    {
151
        $firstline = strtok($string, "\r\n\t");
152
        return strpos($firstline, 'F01KNABNL2HAXXX0000000000') !== false;
153
    }
154
155
    /**
156
     * @TODO WIP get this into the transaction somehow.. (possibly as a decorator over the transactions?)
157
     * @return int
158
     */
159
    protected function parseTransactionType()
160
    {
161
        static $map = [
162
            541 => Type::SEPA_TRANSFER,
163
            544 => Type::SEPA_TRANSFER,
164
            547 => Type::SEPA_TRANSFER,
165
            64 => Type::SEPA_DIRECTDEBIT,
166
            93 => Type::BANK_COSTS,
167
            13 => Type::PAYMENT_TERMINAL,
168
            30 => Type::PAYMENT_TERMINAL,
169
            'MSC' => Type::BANK_INTEREST,
170
            'TRF' => Type::UNKNOWN,
171
        ];
172
173
        $code = $this->parseTransactionCode();
174
        if (array_key_exists($code, $map)) {
175
            return $map[$code];
176
        }
177
        throw new \RuntimeException("Don't know code $code for this bank");
178
    }
179
180
}
181