Completed
Push — master ( 7e81c7...bd5f3a )
by Hannes
01:39
created

TreeBuilder::reset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 12
nc 1
nop 0
1
<?php
2
/**
3
 * This file is part of byrokrat\autogiro.
4
 *
5
 * byrokrat\autogiro is free software: you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License as published
7
 * by the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * byrokrat\autogiro is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with byrokrat\autogiro. If not, see <http://www.gnu.org/licenses/>.
17
 *
18
 * Copyright 2016-18 Hannes Forsgård
19
 */
20
21
declare(strict_types = 1);
22
23
namespace byrokrat\autogiro\Writer;
24
25
use byrokrat\autogiro\Layouts;
26
use byrokrat\autogiro\Tree\RecordNode;
27
use byrokrat\autogiro\Tree\Request\RequestOpening;
28
use byrokrat\autogiro\Tree\Request\AcceptDigitalMandateRequest;
29
use byrokrat\autogiro\Tree\Request\CreateMandateRequest;
30
use byrokrat\autogiro\Tree\Request\DeleteMandateRequest;
31
use byrokrat\autogiro\Tree\Request\RejectDigitalMandateRequest;
32
use byrokrat\autogiro\Tree\Request\UpdateMandateRequest;
33
use byrokrat\autogiro\Tree\Request\IncomingPaymentRequest;
34
use byrokrat\autogiro\Tree\Request\OutgoingPaymentRequest;
35
use byrokrat\autogiro\Tree\FileNode;
36
use byrokrat\autogiro\Tree\LayoutNode;
37
use byrokrat\autogiro\Tree\DateNode;
38
use byrokrat\autogiro\Tree\ImmediateDateNode;
39
use byrokrat\autogiro\Tree\TextNode;
40
use byrokrat\autogiro\Tree\BgcNumberNode;
41
use byrokrat\autogiro\Tree\BankgiroNode;
42
use byrokrat\autogiro\Tree\PayerNumberNode;
43
use byrokrat\autogiro\Tree\AccountNode;
44
use byrokrat\autogiro\Tree\IdNode;
45
use byrokrat\autogiro\Tree\IntervalNode;
46
use byrokrat\autogiro\Tree\RepetitionsNode;
47
use byrokrat\autogiro\Tree\AmountNode;
48
use byrokrat\banking\AccountNumber;
49
use byrokrat\banking\Bankgiro;
50
use byrokrat\id\IdInterface;
51
use byrokrat\amount\Currency\SEK;
52
53
/**
54
 * Build trees representing autogiro request files
55
 */
56
class TreeBuilder
57
{
58
    /**
59
     * Map layout names to record store array names
60
     */
61
    private const LAYOUT_TO_RECORD_STORE_MAP = [
62
        Layouts::LAYOUT_MANDATE_REQUEST => 'mandates',
63
        Layouts::LAYOUT_PAYMENT_REQUEST => 'payments',
64
        Layouts::LAYOUT_AMENDMENT_REQUEST => 'amendments'
65
    ];
66
67
    /**
68
     * @var RequestOpening Opening record used for each layout
69
     */
70
    private $opening;
71
72
    /**
73
     * @var RecordNode[] List of created mandate requests
74
     */
75
    private $mandates;
76
77
    /**
78
     * @var RecordNode[] List of created payment requests
79
     */
80
    private $payments;
81
82
    /**
83
     * @var RecordNode[] List of created amendment requests
84
     */
85
    private $amendments;
86
87
    /**
88
     * @var string Payee BGC customer number
89
     */
90
    private $bgcNr;
91
92
    /**
93
     * @var BankgiroNode Wrapper around payee bankgiro account number
94
     */
95
    private $payeeBgNode;
96
97
    /**
98
     * @var \DateTimeInterface Date of file creation
99
     */
100
    private $date;
101
102
    /**
103
     * @var IntervalFormatter
104
     */
105
    private $intervalFormatter;
106
107
    /**
108
     * @var RepititionsFormatter
109
     */
110
    private $repititionsFormatter;
111
112
    /**
113
     * @param string               $bgcNr                The BGC customer number of payee
114
     * @param Bankgiro             $bankgiro             Payee bankgiro account number
115
     * @param \DateTimeInterface   $date                 Creation date
116
     * @param IntervalFormatter    $intervalFormatter    Interval formatter
117
     * @param RepititionsFormatter $repititionsFormatter Repititions formatter
118
     */
119
    public function __construct(
120
        string $bgcNr,
121
        Bankgiro $bankgiro,
122
        \DateTimeInterface $date,
123
        IntervalFormatter $intervalFormatter,
124
        RepititionsFormatter $repititionsFormatter
125
    ) {
126
        $this->bgcNr = $bgcNr;
127
        $this->payeeBgNode = BankgiroNode::fromBankgiro($bankgiro);
0 ignored issues
show
Documentation Bug introduced by
It seems like \byrokrat\autogiro\Tree\...fromBankgiro($bankgiro) of type object<self> is incompatible with the declared type object<byrokrat\autogiro\Tree\BankgiroNode> of property $payeeBgNode.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
128
        $this->date = $date;
129
        $this->intervalFormatter = $intervalFormatter;
130
        $this->repititionsFormatter = $repititionsFormatter;
131
        $this->reset();
132
    }
133
134
    /**
135
     * Reset builder to initial state
136
     */
137
    public function reset(): void
138
    {
139
        $this->opening = new RequestOpening(
140
            0,
141
            DateNode::fromDate($this->date),
142
            new TextNode(0, 'AUTOGIRO'),
143
            new TextNode(0, str_pad('', 44)),
144
            new BgcNumberNode(0, $this->bgcNr),
145
            $this->payeeBgNode,
146
            [new TextNode(0, '  ')]
147
        );
148
        $this->mandates = [];
149
        $this->payments = [];
150
        $this->amendments = [];
151
    }
152
153
    /**
154
     * Add a new mandate request to tree
155
     */
156
    public function addCreateMandateRequest(string $payerNr, AccountNumber $account, IdInterface $id): void
157
    {
158
        $this->mandates[] = new CreateMandateRequest(
159
            0,
160
            $this->payeeBgNode,
161
            new PayerNumberNode(0, $payerNr),
162
            AccountNode::fromAccount($account),
163
            IdNode::fromId($id),
164
            [new TextNode(0, str_pad('', 24))]
165
        );
166
    }
167
168
    /**
169
     * Add a delete mandate request to tree
170
     */
171
    public function addDeleteMandateRequest(string $payerNr): void
172
    {
173
        $this->mandates[] = new DeleteMandateRequest(
174
            0,
175
            $this->payeeBgNode,
176
            new PayerNumberNode(0, $payerNr),
177
            [new TextNode(0, str_pad('', 52))]
178
        );
179
    }
180
181
    /**
182
     * Add an accept digital mandate request to tree
183
     */
184
    public function addAcceptDigitalMandateRequest(string $payerNr): void
185
    {
186
        $this->mandates[] = new AcceptDigitalMandateRequest(
187
            0,
188
            $this->payeeBgNode,
189
            new PayerNumberNode(0, $payerNr),
190
            [new TextNode(0, str_pad('', 52))]
191
        );
192
    }
193
194
    /**
195
     * Add a reject digital mandate request to tree
196
     */
197
    public function addRejectDigitalMandateRequest(string $payerNr): void
198
    {
199
        $this->mandates[] = new RejectDigitalMandateRequest(
200
            0,
201
            $this->payeeBgNode,
202
            new PayerNumberNode(0, $payerNr),
203
            new TextNode(0, str_pad('', 48)),
204
            new TextNode(0, 'AV'),
205
            [new TextNode(0, '  ')]
206
        );
207
    }
208
209
    /**
210
     * Add an update mandate request to tree
211
     */
212
    public function addUpdateMandateRequest(string $payerNr, string $newPayerNr): void
213
    {
214
        $this->mandates[] = new UpdateMandateRequest(
215
            0,
216
            $this->payeeBgNode,
217
            new PayerNumberNode(0, $payerNr),
218
            $this->payeeBgNode,
219
            new PayerNumberNode(0, $newPayerNr),
220
            [new TextNode(0, str_pad('', 26))]
221
        );
222
    }
223
224
    /**
225
     * Add an incoming payment request to tree
226
     */
227
    public function addIncomingPaymentRequest(
228
        string $payerNr,
229
        SEK $amount,
230
        \DateTimeInterface $date,
231
        string $ref,
232
        string $interval,
233
        int $repetitions
234
    ): void {
235
        $this->addPaymentRequest(
236
            IncomingPaymentRequest::CLASS,
237
            $payerNr,
238
            $amount,
239
            $date,
240
            $ref,
241
            $interval,
242
            $repetitions
243
        );
244
    }
245
246
    /**
247
     * Add an outgoing payment request to tree
248
     */
249
    public function addOutgoingPaymentRequest(
250
        string $payerNr,
251
        SEK $amount,
252
        \DateTimeInterface $date,
253
        string $ref,
254
        string $interval,
255
        int $repetitions
256
    ): void {
257
        $this->addPaymentRequest(
258
            OutgoingPaymentRequest::CLASS,
259
            $payerNr,
260
            $amount,
261
            $date,
262
            $ref,
263
            $interval,
264
            $repetitions
265
        );
266
    }
267
268
    /**
269
     * Add an incoming payment at next possible bank date request to tree
270
     */
271
    public function addImmediateIncomingPaymentRequest(string $payerNr, SEK $amount, string $ref): void
272
    {
273
        $this->addImmediatePaymentRequest(IncomingPaymentRequest::CLASS, $payerNr, $amount, $ref);
274
    }
275
276
    /**
277
     * Add an outgoing payment at next possible bank date request to tree
278
     */
279
    public function addImmediateOutgoingPaymentRequest(string $payerNr, SEK $amount, string $ref): void
280
    {
281
        $this->addImmediatePaymentRequest(OutgoingPaymentRequest::CLASS, $payerNr, $amount, $ref);
282
    }
283
284
    /**
285
     * Get the created request tree
286
     */
287
    public function buildTree(): FileNode
288
    {
289
        $layouts = [];
290
291
        foreach (self::LAYOUT_TO_RECORD_STORE_MAP as $layoutName => $recordStore) {
292
            if (!empty($this->$recordStore)) {
293
                $layouts[] = new LayoutNode($layoutName, $this->opening, ...$this->$recordStore);
294
            }
295
        }
296
297
        return new FileNode(...$layouts);
298
    }
299
300
    private function addPaymentRequest(
301
        string $classname,
302
        string $payerNr,
303
        SEK $amount,
304
        \DateTimeInterface $date,
305
        string $ref,
306
        string $interval,
307
        int $repetitions
308
    ): void {
309
        $this->payments[] = new $classname(
310
            0,
311
            DateNode::fromDate($date),
312
            new IntervalNode(0, $this->intervalFormatter->format($interval)),
313
            new RepetitionsNode(0, $this->repititionsFormatter->format($repetitions)),
314
            new TextNode(0, ' '),
315
            new PayerNumberNode(0, $payerNr),
316
            AmountNode::fromAmount($amount),
317
            $this->payeeBgNode,
318
            new TextNode(0, str_pad($ref, 16, ' ', STR_PAD_LEFT), '/^.{16}$/'),
319
            [new TextNode(0, str_pad('', 11))]
320
        );
321
    }
322
323
    private function addImmediatePaymentRequest(string $classname, string $payerNr, SEK $amount, string $ref): void
324
    {
325
        $this->payments[] = new $classname(
326
            0,
327
            new ImmediateDateNode,
328
            new IntervalNode(0, '0'),
329
            new RepetitionsNode(0, '   '),
330
            new TextNode(0, ' '),
331
            new PayerNumberNode(0, $payerNr),
332
            AmountNode::fromAmount($amount),
333
            $this->payeeBgNode,
334
            new TextNode(0, str_pad($ref, 16, ' ', STR_PAD_LEFT), '/^.{16}$/'),
335
            [new TextNode(0, str_pad('', 11))]
336
        );
337
    }
338
}
339