NovaSearchPartnerMethod::createPartner()   F
last analyzed

Complexity

Conditions 13
Paths 960

Size

Total Lines 80
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 47
CRAP Score 13.0015

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 13
eloc 47
c 1
b 0
f 0
nc 960
nop 2
dl 0
loc 80
ccs 47
cts 48
cp 0.9792
crap 13.0015
rs 2.5055

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace OrcaServices\NovaApi\Method;
4
5
use Cake\Chronos\Chronos;
6
use DOMDocument;
7
use DOMElement;
8
use Exception;
9
use OrcaServices\NovaApi\Parameter\NovaSearchPartnerParameter;
10
use OrcaServices\NovaApi\Parser\NovaApiErrorParser;
11
use OrcaServices\NovaApi\Parser\NovaMessageParser;
12
use OrcaServices\NovaApi\Result\NovaPartner;
13
use OrcaServices\NovaApi\Result\NovaSearchPartnerResult;
14
use OrcaServices\NovaApi\Soap\NovaApiSoapAction;
15
use OrcaServices\NovaApi\Soap\NovaParameterMap;
16
use OrcaServices\NovaApi\Soap\NovaParameterWriter;
17
use OrcaServices\NovaApi\Type\GenderType;
18
use OrcaServices\NovaApi\Xml\XmlDocument;
19
20
/**
21
 * SOAP method.
22
 */
23
final class NovaSearchPartnerMethod implements NovaMethod
24
{
25
    /**
26
     * @var NovaApiSoapAction
27
     */
28
    private $novaSoapAction;
29
30
    /**
31
     * @var NovaApiErrorParser
32
     */
33
    private $novaErrorParser;
34
35
    /**
36
     * @var NovaMessageParser
37
     */
38
    private $novaMessageParser;
39
40
    /**
41
     * NovaSearchPartnerMethod constructor.
42
     *
43
     * @param NovaApiSoapAction $novaSoapAction The novaSoapAction
44
     * @param NovaApiErrorParser $novaErrorParser The novaErrorParser
45
     * @param NovaMessageParser $novaMessageParser The message parser
46
     */
47 13
    public function __construct(
48
        NovaApiSoapAction $novaSoapAction,
49
        NovaApiErrorParser $novaErrorParser,
50
        NovaMessageParser $novaMessageParser
51
    ) {
52 13
        $this->novaSoapAction = $novaSoapAction;
53 13
        $this->novaErrorParser = $novaErrorParser;
54 13
        $this->novaMessageParser = $novaMessageParser;
55 13
    }
56
57
    /**
58
     * Search a NOVA partner (customer).
59
     *
60
     * https://confluence-ext.sbb.ch/display/NOVAUG/suchePartner
61
     *
62
     * @param NovaSearchPartnerParameter $parameter The parameters
63
     *
64
     * @throws Exception
65
     *
66
     * @return NovaSearchPartnerResult The partners matching the search parameter
67
     */
68 3
    public function searchPartner(NovaSearchPartnerParameter $parameter): NovaSearchPartnerResult
69
    {
70
        // The SOAP endpoint url
71
        // https://echo-api.3scale.net/novagp/geschaeftspartner/public/MAJOR.MINOR/GeschaeftspartnerService
72 3
        $url = $this->novaSoapAction->getNovaBusinessPartnerServiceUrl();
73
74
        // The SOAP action (http header)
75 3
        $soapAction = $this->novaSoapAction->getSoapAction('geschaeftspartner', 'suchePartner');
76
77
        // The SOAP content (http body)
78 3
        $body = $this->createRequestBody($parameter);
79
80
        try {
81 3
            $xmlContent = $this->novaSoapAction->invokeSoapRequest($url, $soapAction, $body);
82 3
            $xml = XmlDocument::createFromXmlString($xmlContent);
83
84 3
            return $this->createResult($xml);
85
        } catch (Exception $exception) {
86
            throw $this->novaErrorParser->createGeneralException($exception);
87
        }
88
    }
89
90
    /**
91
     * Create SOAP body XML content.
92
     *
93
     * @param NovaSearchPartnerParameter $parameter The parameters
94
     *
95
     * @return string The xml content
96
     */
97 3
    private function createRequestBody(NovaSearchPartnerParameter $parameter): string
98
    {
99 3
        $dom = new DOMDocument('1.0', 'utf-8');
100 3
        $dom->formatOutput = true;
101
102 3
        $dom->appendChild($dom->createComment(' powered by Barakuda '));
103
104 3
        $envelope = $dom->createElement('soapenv:Envelope');
105 3
        $dom->appendChild($envelope);
106 3
        $envelope->setAttribute('xmlns:soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
107
108 3
        $soapHeader = $dom->createElement('soapenv:Header');
109 3
        $envelope->appendChild($soapHeader);
110
111 3
        $body = $dom->createElement('soapenv:Body');
112 3
        $envelope->appendChild($body);
113
114 3
        $method = $dom->createElement('novagp:suchePartner');
115 3
        $body->appendChild($method);
116
117 3
        $this->novaSoapAction->appendMethodNamespaces($method);
118 3
        $this->novaSoapAction->appendDomClientIdentifier($dom, $method, $parameter, 'novagp:');
119 3
        $this->novaSoapAction->appendDomCorrelationContext($dom, $method, $parameter, 'novagp:');
120
121 3
        $partnerSearchParameter = $dom->createElement('novagp:partnerSuchParameter');
122 3
        $method->appendChild($partnerSearchParameter);
123
124 3
        $parameterWriter = new NovaParameterWriter($dom, $partnerSearchParameter);
125
126 3
        $parameterWriter->appendToDocument(
127 3
            new NovaParameterMap(
128
                [
129 3
                    'tkid' => $parameter->tkId,
130 3
                    'grundkartenNummer' => $parameter->cardNumber,
131 3
                    'ckm' => $parameter->ckm,
132 3
                    'name' => $parameter->lastName,
133 3
                    'vorname' => $parameter->firstName,
134 3
                    'mail' => $parameter->mail,
135 3
                    'land' => $parameter->country,
136 3
                    'ort' => $parameter->city,
137 3
                    'plz' => $parameter->postalCode,
138 3
                    'strasseHnr' => $parameter->street,
139 3
                    'geburtsDatum' => $parameter->dateOfBirth ? $parameter->dateOfBirth->format('Y-m-d') : null,
140
                ]
141
            )
142
        );
143
144 3
        $pagingElement = $dom->createElement('novagp:pagingParameter');
145 3
        $partnerSearchParameter->appendChild($pagingElement);
146
147 3
        return (string)$dom->saveXML();
148
    }
149
150
    /**
151
     * Create result object.
152
     *
153
     * @param XmlDocument $xml The xml document
154
     *
155
     * @return NovaSearchPartnerResult The mapped result
156
     */
157 3
    private function createResult(XmlDocument $xml): NovaSearchPartnerResult
158
    {
159 3
        $result = new NovaSearchPartnerResult();
160
161 3
        $xml = $xml->withoutNamespaces();
162
163
        // Find and append all messages
164 3
        foreach ($this->novaMessageParser->findNovaMessages($xml) as $message) {
165
            $result->addMessage($message);
166
        }
167
168
        // Root node
169 3
        $responseNode = $xml->queryFirstNode('/Envelope/Body/suchePartnerResponse');
170 3
        $partnerNodes = $xml->queryNodes('partner', $responseNode);
171
172
        /** @var DOMElement $partnerNode */
173 3
        foreach ($partnerNodes as $partnerNode) {
174 3
            $result->partners[] = $this->createPartner($partnerNode, $xml);
175
        }
176
177 3
        return $result;
178
    }
179
180
    /**
181
     * Map partner node to NovaPartner object.
182
     *
183
     * @param DOMElement $partnerNode The partnerNode
184
     * @param XmlDocument $xml The xml document
185
     *
186
     * @return NovaPartner The new NovaPartner instance
187
     */
188 3
    private function createPartner(DOMElement $partnerNode, XmlDocument $xml): NovaPartner
189
    {
190 3
        $partner = new NovaPartner();
191
192 3
        $partner->tkId = $xml->getAttributeValue('@tkid', $partnerNode);
193 3
        $partner->ckm = $xml->findAttributeValue('@ckm', $partnerNode);
194 3
        $partner->cardNumber = $xml->findAttributeValue('@grundkartenNummer', $partnerNode);
195
196 3
        $changeDate = $xml->findAttributeValue('@mutDatum', $partnerNode);
197 3
        if ($changeDate !== null) {
198 3
            $partner->changedAt = $xml->createChronosFromXsDateTime($changeDate);
199
        }
200
201 3
        $partner->lastName = $xml->findAttributeValue('name/@name', $partnerNode);
202 3
        $partner->firstName = $xml->findAttributeValue('name/@vorname', $partnerNode);
203 3
        $partner->title = $xml->findAttributeValue('@titel', $partnerNode);
204
205 3
        $deceased = $xml->findAttributeValue('@verstorben', $partnerNode);
206 3
        if ($deceased !== null) {
207 3
            $partner->deceased = $deceased === 'false' ? 0 : 1;
208
        }
209
210
        // Date of birth can be empty sometimes
211 3
        $dateOfBirth = $xml->findAttributeValue('@geburtsDatum', $partnerNode);
212 3
        if ($dateOfBirth) {
213 3
            $dateOfBirth = Chronos::createFromFormat('Y-m-d', $dateOfBirth)->setTime(0, 0);
214 3
            $partner->dateOfBirth = $dateOfBirth;
215
        }
216
217 3
        $gender = $xml->findAttributeValue('@geschlecht', $partnerNode);
218 3
        $genderTypeId = $gender === 'MAENNLICH' ? GenderType::MEN : GenderType::WOMEN;
219 3
        $partner->genderTypeId = $genderTypeId;
220
221
        // Address
222 3
        $addressNodes = $xml->queryNodes('sitz/adresse', $partnerNode);
223
224
        // Could be empty, one, or more then one address: postal addresse, communication address etc.
225 3
        if ($addressNodes->length >= 1) {
226 3
            $addressNode = $xml->getFirstNode($addressNodes);
227
228 3
            $country = $xml->findAttributeValue('@land', $addressNode);
229 3
            $partner->country = $country;
230
231 3
            $city = $xml->findAttributeValue('@ort', $addressNode);
232 3
            $partner->city = $city;
233
234 3
            $postalCode = $xml->findAttributeValue('@plz', $addressNode);
235 3
            $partner->postalCode = $postalCode;
236
237 3
            $additional = $xml->findAttributeValue('@adressZusatz', $addressNode);
238 3
            if ($additional !== null) {
239
                $partner->additional = $additional;
240
            }
241
242 3
            $street = $xml->findAttributeValue('@strasseHnr', $addressNode);
243 3
            $partner->street = $street;
244
245 3
            $poBox = $xml->findAttributeValue('@postfach', $addressNode);
246 3
            if ($poBox !== null) {
247 3
                $partner->poBox = $poBox;
248
            }
249
        }
250
251
        // MOBIL, FESTNETZ or MAIL
252 3
        $phoneNumber = $xml->findAttributeValue('festnetz/@formatiertE123', $partnerNode);
253 3
        if ($phoneNumber !== null) {
254 3
            $partner->phoneNumber = str_replace(' ', '', $phoneNumber);
255
        }
256
257 3
        $mobileNumber = $xml->findAttributeValue('mobil/@formatiertE123', $partnerNode);
258 3
        if ($mobileNumber !== null) {
259 3
            $partner->mobileNumber = str_replace(' ', '', $mobileNumber);
260
        }
261
262 3
        $email = $xml->findAttributeValue('@email', $partnerNode);
263 3
        if ($email && filter_var($email, FILTER_VALIDATE_EMAIL) !== false) {
264 3
            $partner->email = $email;
265
        }
266
267 3
        return $partner;
268
    }
269
}
270