Completed
Push — master ( 239205...f0cec0 )
by Marc
03:53 queued 01:44
created

PaymentSlipData   D

Complexity

Total Complexity 90

Size/Duplication

Total Lines 893
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Test Coverage

Coverage 98.7%

Importance

Changes 5
Bugs 0 Features 0
Metric Value
wmc 90
c 5
b 0
f 0
lcom 2
cbo 2
dl 0
loc 893
ccs 228
cts 231
cp 0.987
rs 4.4444

45 Methods

Rating   Name   Duplication   Size   Complexity  
A getAmountCents() 0 10 2
A getWithBank() 0 4 1
A getWithAccountNumber() 0 4 1
A getWithRecipient() 0 4 1
A getWithAmount() 0 4 1
A getWithPayer() 0 4 1
A setBankData() 0 7 1
A setBankName() 0 9 2
A getBankName() 0 7 2
A setBankCity() 0 9 2
A getBankCity() 0 7 2
A setAccountNumber() 0 9 2
A getAccountNumber() 0 7 2
A setRecipientData() 0 9 1
A setRecipientLine1() 0 9 2
A getRecipientLine1() 0 7 2
A setRecipientLine2() 0 9 2
A getRecipientLine2() 0 7 2
A setRecipientLine3() 0 9 2
A getRecipientLine3() 0 7 2
A setRecipientLine4() 0 9 2
A getRecipientLine4() 0 7 2
A setAmount() 0 9 2
A getAmount() 0 7 2
A setPayerData() 0 9 1
A setPayerLine1() 0 9 2
A getPayerLine1() 0 7 2
A setPayerLine2() 0 9 2
A getPayerLine2() 0 7 2
A setPayerLine3() 0 9 2
A getPayerLine3() 0 7 2
A setPayerLine4() 0 9 2
A getPayerLine4() 0 7 2
B getAccountDigits() 0 18 5
A getAmountFrancs() 0 9 2
A getNotForPayment() 0 4 1
A setWithBank() 0 12 2
A setWithAccountNumber() 0 11 2
A setWithRecipient() 0 14 2
A setWithAmount() 0 11 2
A setWithPayer() 0 14 2
C setNotForPayment() 0 24 7
A modulo10() 0 9 2
A breakStringIntoBlocks() 0 17 3
A isBool() 0 12 2

How to fix   Complexity   

Complex Class

Complex classes like PaymentSlipData often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PaymentSlipData, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Swiss Payment Slip
4
 *
5
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
6
 * @copyright 2012-2016 Some nice Swiss guys
7
 * @author Marc Würth [email protected]
8
 * @author Manuel Reinhard <[email protected]>
9
 * @author Peter Siska <[email protected]>
10
 * @link https://github.com/ravage84/SwissPaymentSlip/
11
 */
12
13
namespace SwissPaymentSlip\SwissPaymentSlip;
14
15
use InvalidArgumentException;
16
use SwissPaymentSlip\SwissPaymentSlip\Exception\PaymentSlipException;
17
use SwissPaymentSlip\SwissPaymentSlip\Exception\DisabledDataException;
18
19
/**
20
 * Swiss Payment Slip Data
21
 *
22
 * A base class for all Swiss payment slip data classes,
23
 * which encapsulate all the common data
24
 * of the various Swiss payment slips types.
25
 *
26
 * It actually doesn't do much. It's mostly a data container class to keep
27
 * including classes from having to care about how a particular slip actually works.
28
 *
29
 * But it provides a flexibility of which data it holds, because not always
30
 * all slip fields are needed in an application.
31
 *
32
 * Glossary:
33
 * ESR = Einzahlungsschein mit Referenznummer
34
 *     ISR, (In-)Payment slip with reference number
35
 *     Summary term for orange payment slips in Switzerland
36
 * BESR = Banken-Einzahlungsschein mit Referenznummer
37
 *     Banking payment slip with reference number
38
 *     Orange payment slip for paying into a bank account (in contrast to a post cheque account with a VESR)
39
 * VESR = Verfahren für Einzahlungsschein mit Referenznummer
40
 *     Procedure for payment slip with reference number
41
 *     Orange payment slip for paying into a post cheque account (in contrast to a banking account with a BESR)
42
 * (B|V)ESR+ = Einzahlungsschein mit Referenznummer ohne Betragsangabe
43
 *     Payment slip with reference number without amount specification
44
 *     An payment slip can be issued without a predefined payment amount
45
 * ES = Einzahlungsschein
46
 *     IS, (In-)Payment slip
47
 *     Also summary term for all payment slips.
48
 *     Red payment slip for paying into a post cheque or bank account without reference number, with message box
49
 *
50
 * @link http://www.six-interbank-clearing.com/en/home/standardization/dta.html Payments in DTA format
51
 *
52
 * @todo Implement currency (CHF, EUR), means different prefixes in code line
53
 * @todo Implement payment on own account, means different prefixes in code line --> edge case!
54
 * @todo Implement cash on delivery (Nachnahme), means different prefixes in code line --> do it on demand
55
 * @todo Implement amount check for unrounded (.05) cents, document why (see manual)
56
 * @todo Create a getBankData method with formatting parameter, e.g. stripping blank lines
57
 * @todo Create a getRecipientData with formatting parameter, e.g. stripping blank lines
58
 */
59
abstract class PaymentSlipData
60
{
61
62
    /**
63
     * The array table for calculating the check digit by modulo 10
64
     *
65
     * @var array
66
     */
67
    private $moduloTable = [0, 9, 4, 6, 8, 2, 7, 1, 3, 5];
68
69
    /**
70
     * Determines if the payment slip has a recipient bank. Can be disabled for pre-printed payment slips
71
     *
72
     * @var bool
73
     */
74
    protected $withBank = true;
75
76
    /**
77
     * Determines if the payment slip has a account number. Can be disabled for pre-printed payment slips
78
     *
79
     * @var bool
80
     */
81
    protected $withAccountNumber = true;
82
83
    /**
84
     * Determines if the payment slip has a recipient. Can be disabled for pre-printed payment slips
85
     *
86
     * @var bool
87
     */
88
    protected $withRecipient = true;
89
90
    /**
91
     * Determines if it's an ESR or an ESR+
92
     *
93
     * @var bool
94
     */
95
    protected $withAmount = true;
96
97
    /**
98
     * Determines if the payment slip has a payer. Can be disabled for pre-printed payment slips
99
     *
100
     * @var bool
101
     */
102
    protected $withPayer = true;
103
104
    /**
105
     * The name of the bank
106
     *
107
     * @var string
108
     */
109
    protected $bankName = '';
110
111
    /**
112
     * The postal code and city of the bank
113
     *
114
     * @var string
115
     */
116
    protected $bankCity = '';
117
118
    /**
119
     * The bank or post cheque account where the money will be transferred to
120
     *
121
     * @var string
122
     */
123
    protected $accountNumber = '';
124
125
    /**
126
     * The first line of the recipient, e.g. "My Company Ltd."
127
     *
128
     * @var string
129
     */
130
    protected $recipientLine1 = '';
131
132
    /**
133
     * The second line of the recipient, e.g. "Examplestreet 61"
134
     *
135
     * @var string
136
     */
137
    protected $recipientLine2 = '';
138
139
    /**
140
     * The third line of the recipient, e.g. "8000 Zürich"
141
     *
142
     * @var string
143
     */
144
    protected $recipientLine3 = '';
145
146
    /**
147
     * The fourth line of the recipient, if needed
148
     *
149
     * @var string
150
     */
151
    protected $recipientLine4 = '';
152
153
    /**
154
     * The amount to be payed into. Can be disabled with withAmount = false for ESR+ slips
155
     *
156
     * @var float
157
     */
158
    protected $amount = 0.0;
159
160
    /**
161
     * The first line of the payer, e.g. "Hans Mustermann"
162
     *
163
     * @var string
164
     */
165
    protected $payerLine1 = '';
166
167
    /**
168
     * The second line of the payer, e.g. "Main Street 11"
169
     *
170
     * @var string
171
     */
172
    protected $payerLine2 = '';
173
174
    /**
175
     * The third line of the payer, e.g. "4052 Basel"
176
     *
177
     * @var string
178
     */
179
    protected $payerLine3 = '';
180
181
    /**
182
     * The fourth line of the payer, if needed
183
     *
184
     * @var string
185
     */
186
    protected $payerLine4 = '';
187
188
    /**
189
     * Determines if the payment slip must not be used for payment (XXXed out)
190
     *
191
     * @var bool
192
     */
193
    protected $notForPayment = false;
194
195
    /**
196
     * Set if payment slip has a bank specified
197
     *
198
     * Resets the bank data when disabling.
199
     *
200
     * @param bool $withBank True for yes, false for no
201
     * @return $this The current instance for a fluent interface.
202
     */
203 2
    public function setWithBank($withBank = true)
204
    {
205 2
        $this->isBool($withBank, 'withBank');
206 1
        $this->withBank = $withBank;
207
208 1
        if ($withBank === false) {
209 1
            $this->bankName = '';
210 1
            $this->bankCity = '';
211
        }
212
213 1
        return $this;
214
    }
215
216
    /**
217
     * Get if payment slip has recipient specified
218
     *
219
     * @return bool True if payment slip has the recipient specified, else false.
220
     */
221 1
    public function getWithBank()
222
    {
223 1
        return $this->withBank;
224
    }
225
226
    /**
227
     * Set if payment slip has an account number specified
228
     *
229
     * Resets the account number when disabling.
230
     *
231
     * @param bool $withAccountNumber True if yes, false if no.
232
     * @return $this The current instance for a fluent interface.
233
     */
234 2
    public function setWithAccountNumber($withAccountNumber = true)
235
    {
236 2
        $this->isBool($withAccountNumber, 'withAccountNumber');
237 1
        $this->withAccountNumber = $withAccountNumber;
238
239 1
        if ($withAccountNumber === false) {
240 1
            $this->accountNumber = '';
241
        }
242
243 1
        return $this;
244
    }
245
246
    /**
247
     * Get if payment slip has an account number specified
248
     *
249
     * @return bool True if payment slip has an account number specified, else false.
250
     */
251 1
    public function getWithAccountNumber()
252
    {
253 1
        return $this->withAccountNumber;
254
    }
255
256
    /**
257
     * Set if payment slip has a recipient specified
258
     *
259
     * Resets the recipient data when disabling.
260
     *
261
     * @param bool $withRecipient True if yes, false if no.
262
     * @return $this The current instance for a fluent interface.
263
     */
264 2
    public function setWithRecipient($withRecipient = true)
265
    {
266 2
        $this->isBool($withRecipient, 'withRecipient');
267 1
        $this->withRecipient = $withRecipient;
268
269 1
        if ($withRecipient === false) {
270 1
            $this->recipientLine1 = '';
271 1
            $this->recipientLine2 = '';
272 1
            $this->recipientLine3 = '';
273 1
            $this->recipientLine4 = '';
274
        }
275
276 1
        return $this;
277
    }
278
279
    /**
280
     * Get if payment slip has a recipient specified
281
     *
282
     * @return bool True if payment slip has a recipient specified, else false.
283
     */
284 1
    public function getWithRecipient()
285
    {
286 1
        return $this->withRecipient;
287
    }
288
289
    /**
290
     * Set if payment slip has an amount specified
291
     *
292
     * Resets the amount when disabling.
293
     *
294
     * @param bool $withAmount True for yes, false for no.
295
     * @return $this The current instance for a fluent interface.
296
     */
297 2
    public function setWithAmount($withAmount = true)
298
    {
299 2
        $this->isBool($withAmount, 'withAmount');
300 1
        $this->withAmount = $withAmount;
301
302 1
        if ($withAmount === false) {
303 1
            $this->amount = 0.0;
304
        }
305
306 1
        return $this;
307
    }
308
309
    /**
310
     * Get if payment slip has an amount specified
311
     *
312
     * @return bool True if payment slip has an amount specified, else false.
313
     */
314 1
    public function getWithAmount()
315
    {
316 1
        return $this->withAmount;
317
    }
318
319
    /**
320
     * Set if payment slip has a payer specified
321
     *
322
     * Resets the payer data when disabling.
323
     *
324
     * @param bool $withPayer True if yes, false if no.
325
     * @return $this The current instance for a fluent interface.
326
     */
327 2
    public function setWithPayer($withPayer = true)
328
    {
329 2
        $this->isBool($withPayer, 'withPayer');
330 1
        $this->withPayer = $withPayer;
331
332 1
        if ($withPayer === false) {
333 1
            $this->payerLine1 = '';
334 1
            $this->payerLine2 = '';
335 1
            $this->payerLine3 = '';
336 1
            $this->payerLine4 = '';
337
        }
338
339 1
        return $this;
340
    }
341
342
    /**
343
     * Get if payment slip has a payer specified
344
     *
345
     * @return bool True if payment slip has a payer specified, else false.
346
     */
347 1
    public function getWithPayer()
348
    {
349 1
        return $this->withPayer;
350
    }
351
352
    /**
353
     * Sets the name, city and account number of the bank
354
     *
355
     * @param string $bankName Name of the bank.
356
     * @param string $bankCity City of the bank.
357
     * @return $this The current instance for a fluent interface.
358
     */
359 1
    public function setBankData($bankName, $bankCity)
360
    {
361 1
        $this->setBankName($bankName);
362 1
        $this->setBankCity($bankCity);
363
364 1
        return $this;
365
    }
366
367
    /**
368
     * Set the name of the bank
369
     *
370
     * @param string $bankName The name of the bank.
371
     * @return $this The current instance for a fluent interface.
372
     * @throws DisabledDataException If the data is disabled.
373
     *
374
     * @todo Implement max length check
375
     */
376 2
    public function setBankName($bankName)
377
    {
378 2
        if (!$this->getWithBank()) {
379 1
            throw new DisabledDataException('bank name');
380
        }
381 1
        $this->bankName = $bankName;
382
383 1
        return $this;
384
    }
385
386
    /**
387
     * Get the name of the bank
388
     *
389
     * @return string The name of the bank, if withBank is set to true.
390
     * @throws DisabledDataException If the data is disabled.
391
     */
392 2
    public function getBankName()
393
    {
394 2
        if (!$this->getWithBank()) {
395 1
            throw new DisabledDataException('bank name');
396
        }
397 1
        return $this->bankName;
398
    }
399
400
    /**
401
     * Set the postal code and city of the bank
402
     *
403
     * @param string $bankCity The postal code and city of the bank
404
     * @return $this The current instance for a fluent interface.
405
     * @throws DisabledDataException If the data is disabled.
406
     *
407
     * @todo Implement max length check
408
     */
409 2
    public function setBankCity($bankCity)
410
    {
411 2
        if (!$this->getWithBank()) {
412 1
            throw new DisabledDataException('bank city');
413
        }
414 1
        $this->bankCity = $bankCity;
415
416 1
        return $this;
417
    }
418
419
    /**
420
     * Get the postal code and city of the bank
421
     *
422
     * @return string The postal code and city, if withBank is set to true.
423
     * @throws DisabledDataException If the data is disabled.
424
     */
425 2
    public function getBankCity()
426
    {
427 2
        if (!$this->getWithBank()) {
428 1
            throw new DisabledDataException('bank city');
429
        }
430 1
        return $this->bankCity;
431
    }
432
433
    /**
434
     * Set the bank or post cheque account where the money will be transferred to
435
     *
436
     * @param string $accountNumber The bank or post cheque account.
437
     * @return $this The current instance for a fluent interface.
438
     * @throws DisabledDataException If the data is disabled.
439
     *
440
     * @todo Implement parameter validation (two hyphens, min & max length)
441
     */
442 2
    public function setAccountNumber($accountNumber)
443
    {
444 2
        if (!$this->getWithAccountNumber()) {
445 1
            throw new DisabledDataException('account number');
446
        }
447 1
        $this->accountNumber = $accountNumber;
448
449 1
        return $this;
450
    }
451
452
    /**
453
     * Get the bank or post cheque account where the money will be transferred to
454
     *
455
     * @return string The bank or post cheque account, if withAccountNumber is set to true.
456
     * @throws DisabledDataException If the data is disabled.
457
     */
458 2
    public function getAccountNumber()
459
    {
460 2
        if (!$this->getWithAccountNumber()) {
461 1
            throw new DisabledDataException('account number');
462
        }
463 1
        return $this->accountNumber;
464
    }
465
466
    /**
467
     * Sets the four lines of the recipient
468
     *
469
     * @param string $recipientLine1 The first line of the recipient, e.g. "My Company Ltd.".
470
     * @param string $recipientLine2 The second line of the recipient, e.g. "Examplestreet 61".
471
     * @param string $recipientLine3 The third line of the recipient, e.g. "8000 Zürich".
472
     * @param string $recipientLine4 The fourth line of the recipient, if needed.
473
     * @return $this The current instance for a fluent interface.
474
     */
475 1
    public function setRecipientData($recipientLine1, $recipientLine2, $recipientLine3 = '', $recipientLine4 = '')
476
    {
477 1
        $this->setRecipientLine1($recipientLine1);
478 1
        $this->setRecipientLine2($recipientLine2);
479 1
        $this->setRecipientLine3($recipientLine3);
480 1
        $this->setRecipientLine4($recipientLine4);
481
482 1
        return $this;
483
    }
484
485
    /**
486
     * Set the first line of the recipient
487
     *
488
     * @param string $recipientLine1 The first line of the recipient, e.g. "My Company Ltd.".
489
     * @return $this The current instance for a fluent interface.
490
     * @throws DisabledDataException If the data is disabled.
491
     */
492 2
    public function setRecipientLine1($recipientLine1)
493
    {
494 2
        if (!$this->getWithRecipient()) {
495 1
            throw new DisabledDataException('recipient line 1');
496
        }
497 1
        $this->recipientLine1 = $recipientLine1;
498
499 1
        return $this;
500
    }
501
502
    /**
503
     * Get the first line of the recipient
504
     *
505
     * @return string The first line of the recipient, if withRecipient is set to true.
506
     * @throws DisabledDataException If the data is disabled.
507
     */
508 2
    public function getRecipientLine1()
509
    {
510 2
        if (!$this->getWithRecipient()) {
511 1
            throw new DisabledDataException('recipient line 1');
512
        }
513 1
        return $this->recipientLine1;
514
    }
515
516
    /**
517
     * Set the second line of the recipient
518
     *
519
     * @param string $recipientLine2 The second line of the recipient, e.g. "Examplestreet 61".
520
     * @return $this The current instance for a fluent interface.
521
     * @throws DisabledDataException If the data is disabled.
522
     */
523 2
    public function setRecipientLine2($recipientLine2)
524
    {
525 2
        if (!$this->getWithRecipient()) {
526 1
            throw new DisabledDataException('recipient line 2');
527
        }
528 1
        $this->recipientLine2 = $recipientLine2;
529
530 1
        return $this;
531
    }
532
533
    /**
534
     * Get the second line of the recipient
535
     *
536
     * @return string The second line of the recipient, if withRecipient is set to true.
537
     * @throws DisabledDataException If the data is disabled.
538
     */
539 2
    public function getRecipientLine2()
540
    {
541 2
        if (!$this->getWithRecipient()) {
542 1
            throw new DisabledDataException('recipient line 2');
543
        }
544 1
        return $this->recipientLine2;
545
    }
546
547
    /**
548
     * Set the third line of the recipient
549
     *
550
     * @param string $recipientLine3 The third line of the recipient, e.g. "8000 Zürich".
551
     * @return $this The current instance for a fluent interface.
552
     * @throws DisabledDataException If the data is disabled.
553
     */
554 2
    public function setRecipientLine3($recipientLine3)
555
    {
556 2
        if (!$this->getWithRecipient()) {
557 1
            throw new DisabledDataException('recipient line 3');
558
        }
559 1
        $this->recipientLine3 = $recipientLine3;
560
561 1
        return $this;
562
    }
563
564
    /**
565
     * Get the third line of the recipient
566
     *
567
     * @return string The third line of the recipient, if withRecipient is set to true.
568
     * @throws DisabledDataException If the data is disabled.
569
     */
570 2
    public function getRecipientLine3()
571
    {
572 2
        if (!$this->getWithRecipient()) {
573 1
            throw new DisabledDataException('recipient line 3');
574
        }
575 1
        return $this->recipientLine3;
576
    }
577
578
    /**
579
     * Set the fourth line of the recipient
580
     *
581
     * @param string $recipientLine4 The fourth line of the recipient, if needed.
582
     * @return $this The current instance for a fluent interface.
583
     * @throws DisabledDataException If the data is disabled.
584
     */
585 2
    public function setRecipientLine4($recipientLine4)
586
    {
587 2
        if (!$this->getWithRecipient()) {
588 1
            throw new DisabledDataException('recipient line 4');
589
        }
590 1
        $this->recipientLine4 = $recipientLine4;
591
592 1
        return $this;
593
    }
594
595
    /**
596
     * Get the fourth line of the recipient
597
     *
598
     * @return string The fourth line of the recipient, if withRecipient is set to true.
599
     * @throws DisabledDataException If the data is disabled.
600
     */
601 2
    public function getRecipientLine4()
602
    {
603 2
        if (!$this->getWithRecipient()) {
604 1
            throw new DisabledDataException('recipient line 4');
605
        }
606 1
        return $this->recipientLine4;
607
    }
608
609
    /**
610
     * Set the amount of the payment slip. Only possible if it's not a ESR+.
611
     *
612
     * @param float $amount The amount to be payed into
613
     * @return $this The current instance for a fluent interface.
614
     * @throws DisabledDataException If the data is disabled.
615
     */
616 2
    public function setAmount($amount = 0.0)
617
    {
618 2
        if (!$this->getWithAmount()) {
619 1
            throw new DisabledDataException('amount');
620
        }
621 1
        $this->amount = $amount;
622
623 1
        return $this;
624
    }
625
626
    /**
627
     * Get the amount to be payed into
628
     *
629
     * @return float The amount to be payed into.
630
     * @throws DisabledDataException If the data is disabled.
631
     */
632 2
    public function getAmount()
633
    {
634 2
        if (!$this->getWithAmount()) {
635 1
            throw new DisabledDataException('amount');
636
        }
637 1
        return $this->amount;
638
    }
639
640
    /**
641
     * Sets the four lines of the payer
642
     *
643
     * At least two lines are necessary.
644
     *
645
     * @param string $payerLine1 The first line of the payer, e.g. "Hans Mustermann".
646
     * @param string $payerLine2 The second line of the payer, e.g. "Main Street 11".
647
     * @param string $payerLine3 The third line of the payer, e.g. "4052 Basel".
648
     * @param string $payerLine4 The fourth line of the payer, if needed.
649
     * @return $this The current instance for a fluent interface.
650
     */
651 1
    public function setPayerData($payerLine1, $payerLine2, $payerLine3 = '', $payerLine4 = '')
652
    {
653 1
        $this->setPayerLine1($payerLine1);
654 1
        $this->setPayerLine2($payerLine2);
655 1
        $this->setPayerLine3($payerLine3);
656 1
        $this->setPayerLine4($payerLine4);
657
658 1
        return $this;
659
    }
660
661
    /**
662
     * Set the first line of the payer
663
     *
664
     * @param string $payerLine1 The first line of the payer, e.g. "Hans Mustermann".
665
     * @return $this The current instance for a fluent interface.
666
     * @throws DisabledDataException If the data is disabled.
667
     */
668 2
    public function setPayerLine1($payerLine1)
669
    {
670 2
        if (!$this->getWithPayer()) {
671 1
            throw new DisabledDataException('payer line 1');
672
        }
673 1
        $this->payerLine1 = $payerLine1;
674
675 1
        return $this;
676
    }
677
678
    /**
679
     * Get the first line of the payer
680
     *
681
     * @return string The first line of the payer, if withPayer is set to true.
682
     * @throws DisabledDataException If the data is disabled.
683
     */
684 2
    public function getPayerLine1()
685
    {
686 2
        if (!$this->getWithPayer()) {
687 1
            throw new DisabledDataException('payer line 1');
688
        }
689 1
        return $this->payerLine1;
690
    }
691
692
    /**
693
     * Set the second line of the payer
694
     *
695
     * @param string $payerLine2 The second line of the payer, e.g. "Main Street 11".
696
     * @return $this The current instance for a fluent interface.
697
     * @throws DisabledDataException If the data is disabled.
698
     */
699 2
    public function setPayerLine2($payerLine2)
700
    {
701 2
        if (!$this->getWithPayer()) {
702 1
            throw new DisabledDataException('payer line 2');
703
        }
704 1
        $this->payerLine2 = $payerLine2;
705
706 1
        return $this;
707
    }
708
709
    /**
710
     * Get the second line of the payer
711
     *
712
     * @return string The second line of the payer, if withPayer is set to true.
713
     * @throws DisabledDataException If the data is disabled.
714
     */
715 2
    public function getPayerLine2()
716
    {
717 2
        if (!$this->getWithPayer()) {
718 1
            throw new DisabledDataException('payer line 2');
719
        }
720 1
        return $this->payerLine2;
721
    }
722
723
    /**
724
     * Set the third line of the payer
725
     *
726
     * @param string $payerLine3 The third line of the payer, e.g. "4052 Basel".
727
     * @return $this The current instance for a fluent interface.
728
     * @throws DisabledDataException If the data is disabled.
729
     */
730 2
    public function setPayerLine3($payerLine3)
731
    {
732 2
        if (!$this->getWithPayer()) {
733 1
            throw new DisabledDataException('payer line 3');
734
        }
735 1
        $this->payerLine3 = $payerLine3;
736
737 1
        return $this;
738
    }
739
740
    /**
741
     * Get the third line of the payer
742
     *
743
     * @return string The third line of the payer, if withPayer is set to true.
744
     * @throws DisabledDataException If the data is disabled.
745
     */
746 2
    public function getPayerLine3()
747
    {
748 2
        if (!$this->getWithPayer()) {
749 1
            throw new DisabledDataException('payer line 3');
750
        }
751 1
        return $this->payerLine3;
752
    }
753
754
    /**
755
     * Set the fourth line of the payer
756
     *
757
     * @param string $payerLine4 The fourth line of the payer, if needed.
758
     * @return $this The current instance for a fluent interface.
759
     * @throws DisabledDataException If the data is disabled.
760
     */
761 2
    public function setPayerLine4($payerLine4)
762
    {
763 2
        if (!$this->getWithPayer()) {
764 1
            throw new DisabledDataException('payer line 4');
765
        }
766 1
        $this->payerLine4 = $payerLine4;
767
768 1
        return $this;
769
    }
770
771
    /**
772
     * Get the fourth line of the payer
773
     *
774
     * @return string The fourth line of the payer, if withPayer is set to true.
775
     * @throws DisabledDataException If the data is disabled.
776
     */
777 2
    public function getPayerLine4()
778
    {
779 2
        if (!$this->getWithPayer()) {
780 1
            throw new DisabledDataException('payer line 4');
781
        }
782 1
        return $this->payerLine4;
783
    }
784
785
    /**
786
     * Clear the account of the two hyphens
787
     *
788
     * @return string The account of the two hyphens, 'XXXXXXXXX' if not for payment or else false.
789
     * @throws DisabledDataException If the data is disabled.
790
     * @throws PaymentSlipException If account number does not contain two hyphens.
791
     * @todo Cover the edge cases with tests
792
     */
793 2
    protected function getAccountDigits()
794
    {
795 2
        if (!$this->getWithAccountNumber()) {
796
            throw new DisabledDataException('account number');
797
        }
798 2
        if ($this->getNotForPayment()) {
799 1
            return 'XXXXXXXXX';
800
        }
801 1
        $accountNumber = $this->getAccountNumber();
802 1
        if ($accountNumber === '') {
803
            return $accountNumber;
804
        }
805 1
        $accountDigits = str_replace('-', '', $accountNumber, $replacedHyphens);
806 1
        if ($replacedHyphens != 2) {
807
            throw new PaymentSlipException('Invalid Account number. Does not contain two hyphens.');
808
        }
809 1
        return $accountDigits;
810
    }
811
812
    /**
813
     * Get the francs amount without cents
814
     *
815
     * @return bool|int Francs amount without cents.
816
     */
817 2
    public function getAmountFrancs()
818
    {
819 2
        if ($this->getNotForPayment()) {
820 1
            return 'XXXXXXXX';
821
        }
822 2
        $amount = $this->getAmount();
823 2
        $francs = intval($amount);
824 2
        return $francs;
825
    }
826
827
    /**
828
     * Get the zero filled, right padded, two digits long cents amount
829
     *
830
     * @return bool|string Amount of Cents, zero filled, right padded, two digits long.
831
     */
832 2
    public function getAmountCents()
833
    {
834 2
        if ($this->getNotForPayment()) {
835 1
            return 'XX';
836
        }
837 2
        $amount = $this->getAmount();
838 2
        $francs = intval($amount);
839 2
        $cents = round(($amount - $francs) * 100);
840 2
        return str_pad($cents, 2, '0', STR_PAD_LEFT);
841
    }
842
843
    /**
844
     * Set payment slip for not to be used for payment
845
     *
846
     * XXXes out all fields to prevent people using the payment slip.
847
     *
848
     * @param boolean $notForPayment True if not for payment, else false.
849
     * @return $this The current instance for a fluent interface.
850
     */
851 2
    public function setNotForPayment($notForPayment = true)
852
    {
853 2
        $this->notForPayment = $notForPayment;
854
855 2
        if ($notForPayment === true) {
856 2
            if ($this->getWithBank() === true) {
857 1
                $this->setBankData('XXXXXX', 'XXXXXX');
858
            }
859 2
            if ($this->getWithAccountNumber() === true) {
860 1
                $this->setAccountNumber('XXXXXX');
861
            }
862 2
            if ($this->getWithRecipient() === true) {
863 1
                $this->setRecipientData('XXXXXX', 'XXXXXX', 'XXXXXX', 'XXXXXX');
864
            }
865 2
            if ($this->getWithPayer() === true) {
866 1
                $this->setPayerData('XXXXXX', 'XXXXXX', 'XXXXXX', 'XXXXXX');
867
            }
868 2
            if ($this->getWithAmount() === true) {
869 1
                $this->setAmount('XXXXXXXX.XX');
870
            }
871
        }
872
873 2
        return $this;
874
    }
875
876
    /**
877
     * Get whether this payment slip must not be used for payment
878
     *
879
     * @return bool True if yes, else false.
880
     */
881 2
    public function getNotForPayment()
882
    {
883 2
        return $this->notForPayment;
884
    }
885
886
    /**
887
     * Creates Modulo10 recursive check digit
888
     *
889
     * @copyright As found on http://www.developers-guide.net/forums/5431,modulo10-rekursiv (thanks, dude!)
890
     * @param string $number Number to create recursive check digit off.
891
     * @return int Recursive check digit.
892
     */
893 2
    protected function modulo10($number)
894
    {
895 2
        $next = 0;
896 2
        for ($i=0; $i < strlen($number); $i++) {
897 2
            $next = $this->moduloTable[($next + intval(substr($number, $i, 1))) % 10];
898
        }
899
900 2
        return (10 - $next) % 10;
901
    }
902
903
    /**
904
     * Get a given string broken down in blocks of a certain size
905
     *
906
     * Example: 000000000000000 becomes more readable 00000 00000 00000
907
     *
908
     * @param string $string The to be formatted string.
909
     * @param int $blockSize The Block size of choice.
910
     * @param bool $alignFromRight Right aligned, blocks are build from right.
911
     * @return string Given string divided in blocks of given block size separated by one space.
912
     */
913 1
    protected function breakStringIntoBlocks($string, $blockSize = 5, $alignFromRight = true)
914
    {
915
        // Lets reverse the string (because we want the block to be aligned from the right)
916 1
        if ($alignFromRight === true) {
917 1
            $string = strrev($string);
918
        }
919
920
        // Chop it into blocks
921 1
        $string = trim(chunk_split($string, $blockSize, ' '));
922
923
        // Re-reverse
924 1
        if ($alignFromRight === true) {
925 1
            $string = strrev($string);
926
        }
927
928 1
        return $string;
929
    }
930
931
    /**
932
     * Verify that a given parameter is boolean
933
     *
934
     * @param mixed $parameter The given parameter to validate.
935
     * @param string $varName The name of the variable.
936
     * @return true If the parameter is a boolean.
937
     * @throws InvalidArgumentException If the parameter is not a boolean.
938
     */
939 18
    protected function isBool($parameter, $varName)
940
    {
941 18
        if (!is_bool($parameter)) {
942 9
            throw new InvalidArgumentException(
943 9
                sprintf(
944 9
                    '$%s is not a boolean.',
945 9
                    $varName
946
                )
947
            );
948
        }
949 9
        return true;
950
    }
951
}
952