NovaCreateServicesMethod::createRequestBody()   B
last analyzed

Complexity

Conditions 6
Paths 8

Size

Total Lines 84
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 52
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 51
c 1
b 0
f 0
nc 8
nop 1
dl 0
loc 84
ccs 52
cts 52
cp 1
crap 6
rs 8.4468

How to fix   Long Method   

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 DomainException;
6
use DOMDocument;
7
use DOMElement;
8
use Exception;
9
use OrcaServices\NovaApi\Parameter\NovaCreateServicesParameter;
10
use OrcaServices\NovaApi\Parser\NovaApiErrorParser;
11
use OrcaServices\NovaApi\Parser\NovaMessageParser;
12
use OrcaServices\NovaApi\Result\NovaCreateServicesResult;
13
use OrcaServices\NovaApi\Result\NovaServiceItem;
14
use OrcaServices\NovaApi\Soap\NovaApiSoapAction;
15
use OrcaServices\NovaApi\Xml\XmlDocument;
16
17
/**
18
 * SOAP method.
19
 */
20
final class NovaCreateServicesMethod implements NovaMethod
21
{
22
    /**
23
     * @var NovaApiSoapAction
24
     */
25
    private $novaSoapAction;
26
27
    /**
28
     * @var NovaApiErrorParser
29
     */
30
    private $novaErrorParser;
31
32
    /**
33
     * @var NovaMessageParser
34
     */
35
    private $novaMessageParser;
36
37
    /**
38
     * NovaSearchPartnerMethod constructor.
39
     *
40
     * @param NovaApiSoapAction $novaSoapAction The novaSoapAction
41
     * @param NovaApiErrorParser $novaErrorParser The novaErrorParser
42
     * @param NovaMessageParser $novaMessageParser The message parser
43
     */
44 13
    public function __construct(
45
        NovaApiSoapAction $novaSoapAction,
46
        NovaApiErrorParser $novaErrorParser,
47
        NovaMessageParser $novaMessageParser
48
    ) {
49 13
        $this->novaSoapAction = $novaSoapAction;
50 13
        $this->novaErrorParser = $novaErrorParser;
51 13
        $this->novaMessageParser = $novaMessageParser;
52 13
    }
53
54
    /**
55
     * 2. Klang.
56
     *
57
     * The next step is to accept the requested OFFER.
58
     * This subroutine checks the OFFER and whether the requested PERFORMANCE (e.g. for dynamic quotas)
59
     * is actually available. This turns the OFFER into a real PERFORMANCE, the sale of which is guaranteed by NOVA.
60
     * If desired, NOVA OFFER needs further information (e.g. about the customer) for processing.
61
     *
62
     * Service: https://confluence-ext.sbb.ch/display/NOVAUG/offeriereLeistungen
63
     *
64
     * @param NovaCreateServicesParameter $parameter The parameters
65
     *
66
     * @throws Exception if an error occurs
67
     *
68
     * @return NovaCreateServicesResult the result data
69
     */
70 3
    public function createService(NovaCreateServicesParameter $parameter): NovaCreateServicesResult
71
    {
72
        // The SOAP endpoint url
73 3
        $url = $this->novaSoapAction->getNovaSalesServiceUrl();
74
75
        // The SOAP action (http header)
76 3
        $soapAction = $this->novaSoapAction->getSoapAction('vertrieb', 'offeriereLeistungen');
77
78
        // The SOAP content (http body)
79 3
        $body = $this->createRequestBody($parameter);
80
81
        try {
82 3
            $xmlContent = $this->novaSoapAction->invokeSoapRequest($url, $soapAction, $body);
83 3
            $xml = XmlDocument::createFromXmlString($xmlContent);
84
85 3
            return $this->createResult($xml);
86
        } catch (Exception $exception) {
87
            throw $this->novaErrorParser->createGeneralException($exception);
88
        }
89
    }
90
91
    /**
92
     * Create SOAP body XML content.
93
     *
94
     * @param NovaCreateServicesParameter $parameter The parameters
95
     *
96
     * @return string The xml content
97
     */
98 3
    private function createRequestBody(NovaCreateServicesParameter $parameter): string
99
    {
100 3
        $dom = new DOMDocument('1.0', 'utf-8');
101 3
        $dom->formatOutput = true;
102
103 3
        $dom->appendChild($dom->createComment(' powered by Barakuda '));
104
105 3
        $envelope = $dom->createElement('soapenv:Envelope');
106 3
        $dom->appendChild($envelope);
107 3
        $envelope->setAttribute('xmlns:soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
108
109 3
        $soapHeader = $dom->createElement('soapenv:Header');
110 3
        $envelope->appendChild($soapHeader);
111
112 3
        $body = $dom->createElement('soapenv:Body');
113 3
        $envelope->appendChild($body);
114
115 3
        $method = $dom->createElement('offeriereLeistungen');
116 3
        $body->appendChild($method);
117
118 3
        $this->novaSoapAction->appendMethodNamespaces($method);
119
120 3
        $methodRequest = $dom->createElement('ns18:offertenRequest');
121 3
        $method->appendChild($methodRequest);
122
123 3
        $methodRequest->setAttribute('ns18:transaktionsVerhalten', 'ROLLBACK_ON_ERROR');
124 3
        $methodRequest->setAttribute('ns18:fachlogLevel', 'OFF');
125
126 3
        $this->novaSoapAction->appendDomClientIdentifier($dom, $methodRequest, $parameter, 'ns18:');
127 3
        $this->novaSoapAction->appendDomCorrelationContext($dom, $methodRequest, $parameter, 'ns18:');
128
129 3
        $serviceRequest = $dom->createElement('ns18:leistungsRequest');
130 3
        $methodRequest->appendChild($serviceRequest);
131
132 3
        $serviceRequest->setAttribute('ns18:angebotsId', $parameter->novaOfferId);
133 3
        $serviceRequest->setAttribute('ns18:externeLeistungsReferenzId', '');
134 3
        $serviceRequest->setAttribute('ns18:externeReisendenReferenzId', '');
135
136
        //
137
        // Key/Value pairs
138
        //
139
140
        // Address
141 3
        if ($parameter->country && $parameter->postalCode) {
142 1
            $addressSaleParameter = $dom->createElement('ns18:verkaufsParameter');
143 1
            $serviceRequest->appendChild($addressSaleParameter);
144 1
            $addressSaleParameter->setAttribute('ns18:code', 'ADRESSE');
145
146 1
            $addressValue = $addressSaleParameter->appendChild($dom->createElement('wert'));
147
148 1
            $distributionBase = $dom->createElement('vertriebsbase:adresse');
149 1
            $addressValue->appendChild($distributionBase);
150 1
            $distributionBase->setAttribute('base:land', $parameter->country);
151 1
            $distributionBase->setAttribute('base:ort', $parameter->postalCode);
152
        }
153
154 3
        if ($parameter->lastName && $parameter->firstName) {
155 1
            $customerSaleParameter = $dom->createElement('ns18:verkaufsParameter');
156 1
            $serviceRequest->appendChild($customerSaleParameter);
157 1
            $customerSaleParameter->setAttribute('ns18:code', 'KUNDENNAME');
158
159 1
            $customerValue = $customerSaleParameter->appendChild($dom->createElement('wert'));
160
161 1
            $distributionName = $dom->createElement('vertriebsbase:nameVorname');
162 1
            $customerValue->appendChild($distributionName);
163 1
            $distributionName->setAttribute('base:name', $parameter->lastName);
164 1
            $distributionName->setAttribute('base:vorname', $parameter->firstName);
165
        }
166
167
        // TKID
168 3
        if ($parameter->tkId) {
169 2
            $travellerParameter = $dom->createElement('ns18:verkaufsParameter');
170 2
            $serviceRequest->appendChild($travellerParameter);
171
172 2
            $travellerParameter->setAttribute('ns18:code', 'REISENDER');
173
174 2
            $travellerValue = $dom->createElement('ns18:wert');
175 2
            $travellerParameter->appendChild($travellerValue);
176
177 2
            $distributionBaseTkid = $dom->createElement('vertriebsbase:tkid', $parameter->tkId);
178 2
            $travellerValue->appendChild($distributionBaseTkid);
179
        }
180
181 3
        return (string)$dom->saveXML();
182
    }
183
184
    /**
185
     * Create result object.
186
     *
187
     * @param XmlDocument $xml The xml document
188
     *
189
     * @throws DomainException
190
     *
191
     * @return NovaCreateServicesResult The mapped result
192
     */
193 3
    private function createResult(XmlDocument $xml): NovaCreateServicesResult
194
    {
195 3
        $result = new NovaCreateServicesResult();
196
197 3
        $xml = $xml->withoutNamespaces();
198
199
        // Find and append all messages
200 3
        foreach ($this->novaMessageParser->findNovaMessages($xml) as $message) {
201
            $result->addMessage($message);
202
        }
203
204
        // Root node
205 3
        $serviceResponseNode = $xml->queryFirstNode('/Envelope/Body/offeriereLeistungenResponse');
206 3
        $serviceNodes = $xml->queryNodes('offertenResponse/leistung', $serviceResponseNode);
207
208
        /** @var DOMElement $serviceNode */
209 3
        foreach ($serviceNodes as $serviceNode) {
210 3
            $serviceItem = new NovaServiceItem();
211
212 3
            $serviceId = $serviceNode->getAttribute('leistungsId');
213
214 3
            if (empty($serviceId)) {
215
                throw new DomainException('SBB-NOVA service ID not found');
216
            }
217
218 3
            $serviceItem->serviceId = $serviceId;
219 3
            $serviceItem->serviceReference = $serviceNode->getAttribute('leistungsReferenz');
220 3
            $serviceItem->serviceStatus = $serviceNode->getAttribute('leistungsStatus');
221 3
            $serviceItem->productNumber = $serviceNode->getAttribute('produktNummer');
222 3
            $serviceItem->tkId = $xml->findNodeValue('//tkid', $serviceNode);
223 3
            $serviceItem->price = $xml->getAttributeValue('verkaufsPreis/geldBetrag/@betrag', $serviceNode);
224 3
            $serviceItem->currency = $xml->getAttributeValue('verkaufsPreis/geldBetrag/@waehrung', $serviceNode);
225 3
            $serviceItem->vatAmount = $xml->getAttributeValue('verkaufsPreis/mwstAnteil/@betrag', $serviceNode);
226 3
            $serviceItem->vatPercent = $xml->getAttributeValue('verkaufsPreis/mwstAnteil/@mwstSatz', $serviceNode);
227
228 3
            $result->services[] = $serviceItem;
229
        }
230
231 3
        return $result;
232
    }
233
}
234