TreeBuilder::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 6
rs 10
cc 1
nc 1
nop 3
1
<?php
2
3
/**
4
 * This file is part of byrokrat\autogiro.
5
 *
6
 * byrokrat\autogiro is free software: you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License as published
8
 * by the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * byrokrat\autogiro is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with byrokrat\autogiro. If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * Copyright 2016-21 Hannes Forsgård
20
 */
21
22
declare(strict_types=1);
23
24
namespace byrokrat\autogiro\Writer;
25
26
use byrokrat\autogiro\Intervals;
27
use byrokrat\autogiro\Tree\AutogiroFile;
28
use byrokrat\autogiro\Tree\ImmediateDate;
29
use byrokrat\autogiro\Tree\Node;
30
use byrokrat\autogiro\Tree\Number;
31
use byrokrat\autogiro\Tree\Obj;
32
use byrokrat\autogiro\Tree\Record;
33
use byrokrat\autogiro\Tree\Section;
34
use byrokrat\autogiro\Tree\Text;
35
use byrokrat\banking\AccountNumber;
36
use byrokrat\id\IdInterface;
37
use Money\Money;
38
39
/**
40
 * Build trees representing autogiro request files
41
 */
42
class TreeBuilder
43
{
44
    /**
45
     * Map section classes to record store array names
46
     */
47
    private const SECTION_TO_RECORD_STORE_MAP = [
48
        Node::MANDATE_REQUEST_SECTION => 'mandates',
49
        Node::PAYMENT_REQUEST_SECTION => 'payments',
50
        Node::AMENDMENT_REQUEST_SECTION => 'amendments'
51
    ];
52
53
    /**
54
     * @var Record Opening record used for each section
55
     */
56
    private $opening;
57
58
    /**
59
     * @var Record[] List of created mandate requests
60
     */
61
    private $mandates;
62
63
    /**
64
     * @var Record[] List of created payment requests
65
     */
66
    private $payments;
67
68
    /**
69
     * @var Record[] List of created amendment requests
70
     */
71
    private $amendments;
72
73
    /**
74
     * @var string Payee BGC customer number
75
     */
76
    private $bgcNr;
77
78
    /**
79
     * @var Obj Wrapper around payee bankgiro account number
80
     */
81
    private $payeeBgNode;
82
83
    /**
84
     * @var \DateTimeInterface Date of file creation
85
     */
86
    private $date;
87
88
    /**
89
     * @param string             $bgcNr    The BGC customer number of payee
90
     * @param AccountNumber      $bankgiro Payee bankgiro account number
91
     * @param \DateTimeInterface $date     Creation date
92
     */
93
    public function __construct(string $bgcNr, AccountNumber $bankgiro, \DateTimeInterface $date)
94
    {
95
        $this->bgcNr = $bgcNr;
96
        $this->payeeBgNode = new Obj(0, $bankgiro, Node::PAYEE_BANKGIRO);
97
        $this->date = $date;
98
        $this->reset();
99
    }
100
101
    /**
102
     * Reset builder to initial state
103
     */
104
    public function reset(): void
105
    {
106
        $this->opening = new Record(
107
            Node::OPENING,
108
            new Obj(0, $this->date, Node::DATE),
109
            new Text(0, 'AUTOGIRO'),
110
            new Text(0, str_pad('', 44)),
111
            new Number(0, $this->bgcNr, Node::PAYEE_BGC_NUMBER),
112
            $this->payeeBgNode,
113
            new Text(0, '  ')
114
        );
115
        $this->mandates = [];
116
        $this->payments = [];
117
        $this->amendments = [];
118
    }
119
120
    /**
121
     * Add a new mandate request to tree
122
     */
123
    public function addCreateMandateRequest(string $payerNr, AccountNumber $account, IdInterface $id): void
124
    {
125
        $this->mandates[] = new Record(
126
            Node::CREATE_MANDATE_REQUEST,
127
            $this->payeeBgNode,
128
            new Number(0, $payerNr, Node::PAYER_NUMBER),
129
            new Obj(0, $account, Node::ACCOUNT),
130
            new Obj(0, $id, Node::STATE_ID),
131
            new Text(0, str_pad('', 24))
132
        );
133
    }
134
135
    /**
136
     * Add a delete mandate request to tree
137
     */
138
    public function addDeleteMandateRequest(string $payerNr): void
139
    {
140
        $this->mandates[] = new Record(
141
            Node::DELETE_MANDATE_REQUEST,
142
            $this->payeeBgNode,
143
            new Number(0, $payerNr, Node::PAYER_NUMBER),
144
            new Text(0, str_pad('', 52))
145
        );
146
    }
147
148
    /**
149
     * Add an accept digital mandate request to tree
150
     */
151
    public function addAcceptDigitalMandateRequest(string $payerNr): void
152
    {
153
        $this->mandates[] = new Record(
154
            Node::ACCEPT_DIGITAL_MANDATE_REQUEST,
155
            $this->payeeBgNode,
156
            new Number(0, $payerNr, Node::PAYER_NUMBER),
157
            new Text(0, str_pad('', 52))
158
        );
159
    }
160
161
    /**
162
     * Add a reject digital mandate request to tree
163
     */
164
    public function addRejectDigitalMandateRequest(string $payerNr): void
165
    {
166
        $this->mandates[] = new Record(
167
            Node::REJECT_DIGITAL_MANDATE_REQUEST,
168
            $this->payeeBgNode,
169
            new Number(0, $payerNr, Node::PAYER_NUMBER),
170
            new Text(0, str_pad('', 48)),
171
            new Text(0, 'AV'),
172
            new Text(0, '  ')
173
        );
174
    }
175
176
    /**
177
     * Add an update mandate request to tree
178
     */
179
    public function addUpdateMandateRequest(string $payerNr, string $newPayerNr): void
180
    {
181
        $this->mandates[] = new Record(
182
            Node::UPDATE_MANDATE_REQUEST,
183
            $this->payeeBgNode,
184
            new Number(0, $payerNr, Node::PAYER_NUMBER),
185
            $this->payeeBgNode,
186
            new Number(0, $newPayerNr, Node::PAYER_NUMBER),
187
            new Text(0, str_pad('', 26))
188
        );
189
    }
190
191
    /**
192
     * Add an incoming payment request to tree
193
     */
194
    public function addIncomingPaymentRequest(
195
        string $payerNr,
196
        Money $amount,
197
        \DateTimeInterface $date,
198
        string $ref,
199
        string $interval,
200
        int $repetitions
201
    ): void {
202
        $this->addPaymentRequest(
203
            Node::INCOMING_PAYMENT_REQUEST,
204
            $payerNr,
205
            $amount,
206
            $date,
207
            $ref,
208
            $interval,
209
            $repetitions
210
        );
211
    }
212
213
    /**
214
     * Add an outgoing payment request to tree
215
     */
216
    public function addOutgoingPaymentRequest(
217
        string $payerNr,
218
        Money $amount,
219
        \DateTimeInterface $date,
220
        string $ref,
221
        string $interval,
222
        int $repetitions
223
    ): void {
224
        $this->addPaymentRequest(
225
            Node::OUTGOING_PAYMENT_REQUEST,
226
            $payerNr,
227
            $amount,
228
            $date,
229
            $ref,
230
            $interval,
231
            $repetitions
232
        );
233
    }
234
235
    /**
236
     * Add an incoming payment at next possible bank date request to tree
237
     */
238
    public function addImmediateIncomingPaymentRequest(string $payerNr, Money $amount, string $ref): void
239
    {
240
        $this->addImmediatePaymentRequest(Node::INCOMING_PAYMENT_REQUEST, $payerNr, $amount, $ref);
241
    }
242
243
    /**
244
     * Add an outgoing payment at next possible bank date request to tree
245
     */
246
    public function addImmediateOutgoingPaymentRequest(string $payerNr, Money $amount, string $ref): void
247
    {
248
        $this->addImmediatePaymentRequest(Node::OUTGOING_PAYMENT_REQUEST, $payerNr, $amount, $ref);
249
    }
250
251
    /**
252
     * Add a delete payment request to tree
253
     */
254
    public function addDeletePaymentRequest(string $payerNr): void
255
    {
256
        $this->amendments[] = new Record(
257
            Node::AMENDMENT_REQUEST,
258
            $this->payeeBgNode,
259
            new Number(0, $payerNr, Node::PAYER_NUMBER),
260
            new Text(0, str_repeat(' ', 52))
261
        );
262
    }
263
264
    /**
265
     * Get the created request tree
266
     */
267
    public function buildTree(): Node
268
    {
269
        $sections = [];
270
271
        foreach (self::SECTION_TO_RECORD_STORE_MAP as $sectionName => $recordStore) {
272
            if (!empty($this->$recordStore)) {
273
                $sections[] = new Section($sectionName, $this->opening, ...$this->$recordStore);
274
            }
275
        }
276
277
        return new AutogiroFile(Node::AUTOGIRO_REQUEST_FILE, ...$sections);
278
    }
279
280
    private function addPaymentRequest(
281
        string $nodename,
282
        string $payerNr,
283
        Money $amount,
284
        \DateTimeInterface $date,
285
        string $ref,
286
        string $interval,
287
        int $repetitions
288
    ): void {
289
        $this->payments[] = new Record(
290
            $nodename,
291
            new Obj(0, $date, Node::DATE),
292
            new Number(0, $interval, Node::INTERVAL),
293
            new Number(0, (string)$repetitions, Node::REPETITIONS),
294
            new Text(0, ' '),
295
            new Number(0, $payerNr, Node::PAYER_NUMBER),
296
            new Obj(0, $amount, Node::AMOUNT),
297
            $this->payeeBgNode,
298
            new Text(0, str_pad($ref, 16, ' ', STR_PAD_LEFT)),
299
            new Text(0, str_pad('', 11))
300
        );
301
    }
302
303
    private function addImmediatePaymentRequest(string $nodename, string $payerNr, Money $amount, string $ref): void
304
    {
305
        $this->payments[] = new Record(
306
            $nodename,
307
            new ImmediateDate(),
308
            new Number(0, Intervals::INTERVAL_ONCE, Node::INTERVAL),
309
            new Number(0, '0', Node::REPETITIONS),
310
            new Text(0, ' '),
311
            new Number(0, $payerNr, Node::PAYER_NUMBER),
312
            new Obj(0, $amount, Node::AMOUNT),
313
            $this->payeeBgNode,
314
            new Text(0, str_pad($ref, 16, ' ', STR_PAD_LEFT)),
315
            new Text(0, str_pad('', 11))
316
        );
317
    }
318
}
319