NovaConfirmReceiptsMethod::confirmReceipts()   A
last analyzed

Complexity

Conditions 2
Paths 4

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2.0438

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 9
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 18
ccs 7
cts 9
cp 0.7778
crap 2.0438
rs 9.9666
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\NovaConfirmReceiptsParameter;
10
use OrcaServices\NovaApi\Parser\NovaApiErrorParser;
11
use OrcaServices\NovaApi\Parser\NovaMessageParser;
12
use OrcaServices\NovaApi\Result\NovaConfirmReceiptsResult;
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
 * 4.2. Klang
21
 */
22
final class NovaConfirmReceiptsMethod implements NovaMethod
23
{
24
    /**
25
     * @var NovaApiSoapAction
26
     */
27
    private $novaSoapAction;
28
29
    /**
30
     * @var NovaApiErrorParser
31
     */
32
    private $novaErrorParser;
33
34
    /**
35
     * @var NovaMessageParser
36
     */
37
    private $novaMessageParser;
38
39
    /**
40
     * NovaSearchPartnerMethod constructor.
41
     *
42
     * @param NovaApiSoapAction $novaSoapAction The novaSoapAction
43
     * @param NovaApiErrorParser $novaErrorParser The novaErrorParser
44
     * @param NovaMessageParser $novaMessageParser The message parser
45
     */
46 13
    public function __construct(
47
        NovaApiSoapAction $novaSoapAction,
48
        NovaApiErrorParser $novaErrorParser,
49
        NovaMessageParser $novaMessageParser
50
    ) {
51 13
        $this->novaSoapAction = $novaSoapAction;
52 13
        $this->novaErrorParser = $novaErrorParser;
53 13
        $this->novaMessageParser = $novaMessageParser;
54 13
    }
55
56
    /**
57
     * 4.2 Klang.
58
     *
59
     * Service: https://confluence-ext.sbb.ch/display/NOVAUG/bestaetigeProduktion
60
     *
61
     * @param NovaConfirmReceiptsParameter $parameter The parameters
62
     *
63
     * @throws Exception
64
     *
65
     * @return NovaConfirmReceiptsResult The result data
66
     */
67 3
    public function confirmReceipts(NovaConfirmReceiptsParameter $parameter): NovaConfirmReceiptsResult
68
    {
69
        // The SOAP endpoint url
70 3
        $url = $this->novaSoapAction->getNovaSalesServiceUrl();
71
72
        // The SOAP action (http header)
73 3
        $soapAction = $this->novaSoapAction->getSoapAction('vertrieb', 'bestaetigeProduktion');
74
75
        // The SOAP content (http body)
76 3
        $body = $this->createRequestBody($parameter);
77
78
        try {
79 3
            $xmlContent = $this->novaSoapAction->invokeSoapRequest($url, $soapAction, $body);
80 3
            $xml = XmlDocument::createFromXmlString($xmlContent);
81
82 3
            return $this->createResult($xml);
83
        } catch (Exception $exception) {
84
            throw $this->novaErrorParser->createGeneralException($exception);
85
        }
86
    }
87
88
    /**
89
     * Create SOAP body XML content.
90
     *
91
     * @param NovaConfirmReceiptsParameter $parameter The parameters
92
     *
93
     * @return string The xml content
94
     */
95 3
    private function createRequestBody(NovaConfirmReceiptsParameter $parameter): string
96
    {
97 3
        $dom = new DOMDocument('1.0', 'utf-8');
98 3
        $dom->formatOutput = true;
99
100 3
        $dom->appendChild($dom->createComment(' powered by Barakuda '));
101
102 3
        $envelope = $dom->createElement('soapenv:Envelope');
103 3
        $dom->appendChild($envelope);
104 3
        $envelope->setAttribute('xmlns:soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
105
106 3
        $soapHeader = $dom->createElement('soapenv:Header');
107 3
        $envelope->appendChild($soapHeader);
108
109 3
        $body = $dom->createElement('soapenv:Body');
110 3
        $envelope->appendChild($body);
111
112 3
        $method = $dom->createElement('bestaetigeProduktion');
113 3
        $body->appendChild($method);
114
115 3
        $this->novaSoapAction->appendMethodNamespaces($method);
116
117 3
        $methodRequest = $dom->createElement('ns18:bestaetigeProduktionRequest');
118 3
        $method->appendChild($methodRequest);
119
120 3
        $methodRequest->setAttribute('ns18:transaktionsVerhalten', 'ROLLBACK_ON_ERROR');
121 3
        $methodRequest->setAttribute('ns18:fachlogLevel', 'OFF');
122
123 3
        $this->novaSoapAction->appendDomClientIdentifier($dom, $methodRequest, $parameter, 'ns18:');
124 3
        $this->novaSoapAction->appendDomCorrelationContext($dom, $methodRequest, $parameter, 'ns18:');
125
126 3
        $serviceRequest = $dom->createElement('ns18:leistungsId', $parameter->novaServiceId);
127 3
        $methodRequest->appendChild($serviceRequest);
128
129 3
        return (string)$dom->saveXML();
130
    }
131
132
    /**
133
     * Create result object.
134
     *
135
     * @param XmlDocument $xml The xml document
136
     *
137
     * @throws DomainException
138
     *
139
     * @return NovaConfirmReceiptsResult The mapped result
140
     */
141 3
    private function createResult(XmlDocument $xml): NovaConfirmReceiptsResult
142
    {
143 3
        $result = new NovaConfirmReceiptsResult();
144
145 3
        $xml = $xml->withoutNamespaces();
146
147
        // Find and append all messages
148 3
        foreach ($this->novaMessageParser->findNovaMessages($xml) as $message) {
149
            $result->addMessage($message);
150
        }
151
152
        // Root node
153 3
        $serviceResponseNode = $xml->queryFirstNode('/Envelope/Body/bestaetigeProduktionResponse');
154 3
        $serviceNodes = $xml->queryNodes('bestaetigeProduktionResponse/leistung', $serviceResponseNode);
155
156
        /** @var DOMElement $serviceNode */
157 3
        foreach ($serviceNodes as $serviceNode) {
158 3
            $serviceItem = new NovaServiceItem();
159
160 3
            $serviceId = $serviceNode->getAttribute('leistungsId');
161
162 3
            if (empty($serviceId)) {
163
                throw new DomainException(sprintf('SBB-NOVA service ID not found'));
164
            }
165
166 3
            $serviceItem->serviceId = $serviceId;
167 3
            $serviceItem->serviceReference = $serviceNode->getAttribute('leistungsReferenz');
168 3
            $serviceItem->serviceStatus = $serviceNode->getAttribute('leistungsStatus');
169 3
            $serviceItem->productNumber = $serviceNode->getAttribute('produktNummer');
170 3
            $serviceItem->tkId = $xml->findNodeValue('//tkid', $serviceNode);
171 3
            $serviceItem->price = $xml->getAttributeValue('verkaufsPreis/geldBetrag/@betrag', $serviceNode);
172 3
            $serviceItem->currency = $xml->getAttributeValue('verkaufsPreis/geldBetrag/@waehrung', $serviceNode);
173 3
            $serviceItem->vatAmount = $xml->getAttributeValue('verkaufsPreis/mwstAnteil/@betrag', $serviceNode);
174 3
            $serviceItem->vatPercent = $xml->getAttributeValue('verkaufsPreis/mwstAnteil/@mwstSatz', $serviceNode);
175
176 3
            $result->services[] = $serviceItem;
177
        }
178
179 3
        return $result;
180
    }
181
}
182