Passed
Push — master ( 9536d0...0dc3be )
by Jan
12:11
created

PaymentOrderSEPAExporter::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
/*
3
 * Copyright (C) 2020  Jan Böhmer
4
 *
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU Affero 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
 * This program 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 Affero General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Affero General Public License
16
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
 */
18
19
namespace App\Services\SEPAExport;
20
21
use App\Entity\PaymentOrder;
22
use App\Entity\SEPAExport;
23
use App\Helpers\SEPAXML\SEPAXMLExportResult;
24
use Digitick\Sepa\DomBuilder\BaseDomBuilder;
25
use Digitick\Sepa\DomBuilder\DomBuilderFactory;
26
use Digitick\Sepa\PaymentInformation;
27
use Digitick\Sepa\TransferFile\CustomerCreditTransferFile;
28
use Digitick\Sepa\TransferInformation\CustomerCreditTransferInformation;
29
use Webmozart\Assert\Assert;
30
31
final class PaymentOrderSEPAExporter
32
{
33
    private $group_header_helper;
34
35
    public function __construct(GroupHeaderHelper $group_header_helper)
36
    {
37
        $this->group_header_helper = $group_header_helper;
38
    }
39
40
    /**
41
     * Exports the given payment orders using the given options.
42
     * @param  array  $payment_orders
43
     * @param  array  $options
44
     * @return SEPAXMLExportResult
45
     */
46
    public function export(array $payment_orders, array $options): SEPAXMLExportResult
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

46
    public function export(array $payment_orders, /** @scrutinizer ignore-unused */ array $options): SEPAXMLExportResult

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $payment_orders is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

46
    public function export(/** @scrutinizer ignore-unused */ array $payment_orders, array $options): SEPAXMLExportResult

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
47
    {
48
49
    }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return App\Helpers\SEPAXML\SEPAXMLExportResult. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
50
51
    public function exportUsingGivenIBAN(array $payment_orders, string $debtor_iban, string $debtor_bic, string $debtor_account_name): SEPAExport
52
    {
53
        //We need IBAN without spaces
54
        $debtor_iban = str_replace(" ", "", $debtor_iban);
55
56
        $groupHeader = $this->group_header_helper->getGroupHeader($debtor_bic);
57
        $sepaFile = new CustomerCreditTransferFile($groupHeader);
58
59
        $payment = new PaymentInformation(
60
            md5(random_bytes(50)), //Use a random payment identifier ID
61
            $debtor_iban,
62
            $debtor_bic,
63
            $debtor_account_name
64
        );
65
66
        //Disable batch booking, as the commerzbank does not show details for "Sammelüberweisungen"
67
        $payment->setBatchBooking(false);
68
69
        //Add each payment order as transaction
70
        foreach ($payment_orders as $payment_order) {
71
            //Ensure that type is correct
72
            if (!$payment_order instanceof PaymentOrder) {
73
                throw new \InvalidArgumentException('$payment_orders must be an array of PaymentOrder elements!');
74
            }
75
76
            //Ensure that the ID is available
77
            if (!$payment_order->getId() === null) {
78
                throw new \InvalidArgumentException('A payment order that should be exported misses an ID. All payment orders must have been persisted!');
79
            }
80
81
            $transfer = new CustomerCreditTransferInformation(
82
                $payment_order->getAmount(),
83
                $payment_order->getBankInfo()->getIbanWithoutSpaces(),
84
                $payment_order->getBankInfo()->getAccountOwner()
85
            );
86
87
            //BIC is optional, only set it if it was set.
88
            if (!empty($payment_order->getBankInfo()->getBic())) {
89
                $transfer->setBic($payment_order->getBankInfo()->getBic());
90
            }
91
92
            //We use the ID String of the payment order as end to end reference
93
            $transfer->setEndToEndIdentification($payment_order->getIDString());
94
            //Set the reference ID of the payment order as
95
            $transfer->setRemittanceInformation($payment_order->getBankInfo()->getReference());
96
97
            $payment->addTransfer($transfer);
98
        }
99
100
        //Add payment infos to SEPA file
101
        $sepaFile->addPaymentInformation($payment);
102
103
        // We have to use the format 'pain.001.001.03'
104
        $domBuilder = DomBuilderFactory::createDomBuilder($sepaFile, 'pain.001.001.03');
105
106
        if (!$domBuilder instanceof BaseDomBuilder) {
0 ignored issues
show
introduced by
$domBuilder is always a sub-type of Digitick\Sepa\DomBuilder\BaseDomBuilder.
Loading history...
107
            throw new \RuntimeException('$domBuilder must be an BaseDomBuilder instance!');
108
        }
109
110
        //Create a temporary file with the XML content
111
        $xml_string = $domBuilder->asXml();
112
113
        //We use the format YYYYMMDDHHmmss_MsgID.xml
114
        $original_filename = sprintf("%s_%s.xml",
115
            (new \DateTime())->format('YmdHis'),
116
            $groupHeader->getMessageIdentification(),
117
        );
118
119
        return SEPAExport::createFromXMLString($xml_string, $original_filename);
120
    }
121
122
123
}