Passed
Push — master ( 3b9ce6...298e9b )
by Hannes
02:09
created

XmlMandateParser   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 107
Duplicated Lines 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
eloc 57
dl 0
loc 107
rs 10
c 7
b 0
f 0
wmc 8

2 Methods

Rating   Name   Duplication   Size   Complexity  
B parseXml() 0 87 7
A __construct() 0 4 1
1
<?php
2
/**
3
 * This file is part of byrokrat\giroapp.
4
 *
5
 * byrokrat\giroapp 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\giroapp 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\giroapp. If not, see <http://www.gnu.org/licenses/>.
17
 *
18
 * Copyright 2016-20 Hannes Forsgård
19
 */
20
21
declare(strict_types = 1);
22
23
namespace byrokrat\giroapp\Xml;
24
25
use byrokrat\giroapp\DependencyInjection;
26
use byrokrat\giroapp\Domain\PostalAddress;
27
use byrokrat\giroapp\Exception\InvalidDataException;
28
use byrokrat\giroapp\Exception\ValidatorException;
29
use byrokrat\giroapp\Validator\AccountValidator;
30
use byrokrat\giroapp\Validator\IdValidator;
31
use byrokrat\giroapp\Validator\PayerNumberValidator;
32
use byrokrat\giroapp\Validator\PostalCodeValidator;
33
use byrokrat\giroapp\Validator\StringValidator;
34
use byrokrat\banking\AccountNumber;
35
use byrokrat\id\IdInterface;
36
37
/**
38
 * Create XmlMandate objects from xml source
39
 */
40
class XmlMandateParser
41
{
42
    use DependencyInjection\AccountFactoryProperty,
43
        DependencyInjection\IdFactoryProperty;
44
45
    /** @var IdInterface */
46
    private $payeeOrgNr;
47
48
    /** @var AccountNumber */
49
    private $payeeBankgiro;
50
51
    public function __construct(IdInterface $payeeOrgNr, AccountNumber $payeeBankgiro)
52
    {
53
        $this->payeeOrgNr = $payeeOrgNr;
54
        $this->payeeBankgiro = $payeeBankgiro;
55
    }
56
57
    /**
58
     * @return array<XmlMandate>
59
     */
60
    public function parseXml(XmlObject $xmlRoot): array
61
    {
62
        /** @var array<XmlMandate> */
63
        $mandates = [];
64
65
        $stringValidator = new StringValidator;
66
67
        foreach ($xmlRoot->getElements('/DocumentElement/MedgivandeViaHemsida') as $xmlSource) {
68
            // Validate payee organisational number
69
            $orgNr = $xmlSource->readElement('/MedgivandeViaHemsida/Organisationsnr', new IdValidator);
70
            if ($this->payeeOrgNr->format('S-sk') != $orgNr) {
71
                // Hard failure, implicit rollback
72
                throw new InvalidDataException(sprintf(
73
                    'Invalid payee org nr %s, expecting %s',
74
                    $orgNr,
75
                    $this->payeeOrgNr->format('S-sk')
76
                ));
77
            }
78
79
            // Validate payee bankgiro account number
80
            $bankgiro = $xmlSource->readElement('/MedgivandeViaHemsida/Bankgironr', new AccountValidator);
81
            if (preg_replace('/\D/', '', $this->payeeBankgiro->getNumber()) != preg_replace('/\D/', '', $bankgiro)) {
82
                // Hard failure, implicit rollback
83
                throw new InvalidDataException(sprintf(
84
                    'Invalid payee bankgiro %s, expecting %s',
85
                    $bankgiro,
86
                    $this->payeeBankgiro->getNumber()
87
                ));
88
            }
89
90
            // require this empty element to exist
91
            $xmlSource->readElement('/MedgivandeViaHemsida/Autogiroanmälan_x002C__x0020_medgivande', $stringValidator);
92
93
            $mandate = new XmlMandate;
94
95
            $mandate->donorId = $this->idFactory->createId(
96
                $xmlSource->readElement('/MedgivandeViaHemsida/Kontoinnehavarens_x0020_personnr', new IdValidator)
97
            );
98
99
            if ($xmlSource->hasElement('/MedgivandeViaHemsida/Betalarnummer')) {
100
                try {
101
                    $mandate->payerNumber = $xmlSource->readElement(
102
                        '/MedgivandeViaHemsida/Betalarnummer',
103
                        new PayerNumberValidator
104
                    );
105
                } catch (ValidatorException $e) {
106
                    // intentionally empty
107
                }
108
            }
109
110
            $mandate->account = $this->accountFactory->createAccount(
111
                $xmlSource->readElement('/MedgivandeViaHemsida/Kontonr', new AccountValidator)
112
            );
113
114
            $mandate->name = $xmlSource->readElement('/MedgivandeViaHemsida/Betalares_x0020_namn', $stringValidator);
115
116
            $mandate->address = [
117
                'line1' =>
118
                    $xmlSource->readElement('/MedgivandeViaHemsida/Betalares_x0020_adress_1', $stringValidator),
119
                'line2' =>
120
                    $xmlSource->readElement('/MedgivandeViaHemsida/Betalares_x0020_adress_2', $stringValidator),
121
                'line3' =>
122
                    $xmlSource->readElement('/MedgivandeViaHemsida/Betalares_x0020_adress_3', $stringValidator),
123
                'postalCode' =>
124
                    $xmlSource->readElement('/MedgivandeViaHemsida/Betalares_x0020_postnr', new PostalCodeValidator),
125
                'postalCity' =>
126
                    $xmlSource->readElement('/MedgivandeViaHemsida/Betalares_x0020_postort', $stringValidator)
127
            ];
128
129
            foreach ($xmlSource->getElements('/MedgivandeViaHemsida/Övrig_x0020_info/customdata') as $custom) {
130
                $mandate->attributes[$custom->readElement('/customdata/name', $stringValidator)]
131
                    = $custom->readElement('/customdata/value', $stringValidator);
132
            }
133
134
            $mandate->attributes['online_form_id']
135
                = $xmlSource->readElement('/MedgivandeViaHemsida/Formulärnamn', $stringValidator);
136
137
            $mandate->attributes['online_verification_time']
138
                = $xmlSource->readElement('/MedgivandeViaHemsida/Verifieringstid', $stringValidator);
139
140
            $mandate->attributes['online_verification_code']
141
                = $xmlSource->readElement('/MedgivandeViaHemsida/Verifieringsreferens', $stringValidator);
142
143
            $mandates[] = $mandate;
144
        }
145
146
        return $mandates;
147
    }
148
}
149