Passed
Branch feature/ECO-573-per-item-proce... (fe5bf4)
by Andrey
04:56
created

AbstractResponseParserConverter   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 301
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 301
rs 9.8
c 0
b 0
f 0
wmc 31

17 Methods

Rating   Name   Duplication   Size   Complexity  
A extractShippingAddress() 0 16 3
A buildConstraintTransfer() 0 7 1
A extractResult() 0 5 1
A extractStatusCode() 0 3 1
A isSuccess() 0 5 2
A getStringValue() 0 3 2
A setBody() 0 3 1
A updateHeaderWithError() 0 7 1
A getConstraints() 0 7 2
A convert() 0 3 1
A extractErrorFromConstraints() 0 8 2
A mapResponseDataToTransfer() 0 9 2
B extractConstraints() 0 19 5
A convertAddressToTransfer() 0 21 2
A extractMetadata() 0 3 1
A createTransferObject() 0 3 1
B extractHeader() 0 24 3
1
<?php
2
3
/**
4
 * Apache OSL-2
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace SprykerEco\Zed\Amazonpay\Business\Api\Converter;
9
10
use ArrayObject;
11
use Generated\Shared\Transfer\AddressTransfer;
12
use Generated\Shared\Transfer\AmazonpayResponseConstraintTransfer;
13
use Generated\Shared\Transfer\AmazonpayResponseHeaderTransfer;
14
use Generated\Shared\Transfer\AmazonpayResponseTransfer;
15
use PayWithAmazon\ResponseInterface;
16
use SprykerEco\Shared\Amazonpay\AmazonpayConstants;
17
18
abstract class AbstractResponseParserConverter extends AbstractConverter implements ResponseParserConverterInterface
19
{
20
21
    const STATUS_CODE_SUCCESS = 200;
22
    const ORDER_REFERENCE_DETAILS = 'OrderReferenceDetails';
23
    const CONSTRAINTS = 'Constraints';
24
    const DESCRIPTION = 'Description';
25
    const CONSTRAINT_ID = 'ConstraintID';
26
    const REQUEST_ID = 'RequestId';
27
    const ERROR = 'Error';
28
    const RESPONSE_METADATA = 'ResponseMetadata';
29
    const RESPONSE_STATUS = 'ResponseStatus';
30
    const MESSAGE = 'Message';
31
    const CODE = 'Code';
32
    const DESTINATION = 'Destination';
33
    const PHYSICAL_DESTINATION = 'PhysicalDestination';
34
    const NAME = 'Name';
35
    const CITY = 'City';
36
    const COUNTRY_CODE = 'CountryCode';
37
    const POSTAL_CODE = 'PostalCode';
38
    const ADDRESS_LINE_1 = 'AddressLine1';
39
    const ADDRESS_LINE_2 = 'AddressLine2';
40
    const ADDRESS_LINE_3 = 'AddressLine3';
41
    const DISTRICT = 'District';
42
    const STATE_OR_REGION = 'StateOrRegion';
43
    const PHONE = 'Phone';
44
45
    /**
46
     * @var string
47
     */
48
    protected $resultKeyName;
49
50
    /**
51
     * @return string
52
     */
53
    abstract protected function getResponseType();
54
55
    /**
56
     * @return \Generated\Shared\Transfer\AmazonpayResponseTransfer
57
     */
58
    protected function createTransferObject()
59
    {
60
        return new AmazonpayResponseTransfer();
61
    }
62
63
    /**
64
     * @param \Generated\Shared\Transfer\AmazonpayResponseTransfer $responseTransfer
65
     * @param \PayWithAmazon\ResponseInterface $responseParser
66
     *
67
     * @return \Generated\Shared\Transfer\AmazonpayResponseTransfer
68
     */
69
    protected function setBody(AmazonpayResponseTransfer $responseTransfer, ResponseInterface $responseParser)
70
    {
71
        return $responseTransfer;
72
    }
73
74
    /**
75
     * @param \Generated\Shared\Transfer\AmazonpayResponseTransfer $responseTransfer
76
     * @param \PayWithAmazon\ResponseInterface $responseParser
77
     *
78
     * @return \Generated\Shared\Transfer\AmazonpayResponseTransfer
79
     */
80
    protected function mapResponseDataToTransfer(AmazonpayResponseTransfer $responseTransfer, ResponseInterface $responseParser)
81
    {
82
        $responseTransfer->setHeader($this->extractHeader($responseParser));
83
84
        if ($responseTransfer->getHeader()->getIsSuccess()) {
85
            return $this->setBody($responseTransfer, $responseParser);
86
        }
87
88
        return $responseTransfer;
89
    }
90
91
    /**
92
     * @param \PayWithAmazon\ResponseInterface $responseParser
93
     *
94
     * @return \Generated\Shared\Transfer\AmazonpayResponseTransfer
95
     */
96
    public function convert(ResponseInterface $responseParser)
97
    {
98
        return $this->mapResponseDataToTransfer($this->createTransferObject(), $responseParser);
99
    }
100
101
    /**
102
     * @param \PayWithAmazon\ResponseInterface $responseParser
103
     *
104
     * @return array
105
     */
106
    protected function extractMetadata(ResponseInterface $responseParser)
107
    {
108
        return $responseParser->toArray()[static::RESPONSE_METADATA] ?? [];
109
    }
110
111
    /**
112
     * @param \PayWithAmazon\ResponseInterface $responseParser
113
     *
114
     * @return int
115
     */
116
    protected function extractStatusCode(ResponseInterface $responseParser)
117
    {
118
        return (int)$responseParser->toArray()[static::RESPONSE_STATUS];
119
    }
120
121
    /**
122
     * @param \PayWithAmazon\ResponseInterface $responseParser
123
     *
124
     * @return \Generated\Shared\Transfer\AmazonpayResponseHeaderTransfer
125
     */
126
    protected function extractHeader(ResponseInterface $responseParser)
127
    {
128
        $statusCode = $this->extractStatusCode($responseParser);
129
        $metadata = $this->extractMetadata($responseParser);
130
        $constraints = $this->extractConstraints($responseParser);
131
132
        $header = new AmazonpayResponseHeaderTransfer();
133
        $header->setIsSuccess($this->isSuccess($responseParser));
134
        $header->setStatusCode($statusCode);
135
136
        if (isset($metadata[static::REQUEST_ID])) {
137
            $header->setRequestId($metadata[static::REQUEST_ID]);
138
            $responseArray = $responseParser->toArray();
139
140
            if (!empty($responseArray[static::ERROR])) {
141
                return $this->updateHeaderWithError($header, $responseArray);
142
            }
143
        }
144
145
146
        $header->setConstraints($constraints);
147
        $this->extractErrorFromConstraints($header);
148
149
        return $header;
150
    }
151
152
    /**
153
     * @param \Generated\Shared\Transfer\AmazonpayResponseHeaderTransfer $header
154
     * @param array $responseArray
155
     *
156
     * @return \Generated\Shared\Transfer\AmazonpayResponseHeaderTransfer
157
     */
158
    protected function updateHeaderWithError(AmazonpayResponseHeaderTransfer $header, array $responseArray)
159
    {
160
        $header->setErrorMessage($responseArray[static::ERROR][static::MESSAGE]);
161
        $header->setErrorCode($responseArray[static::ERROR][static::CODE]);
162
        $header->setRequestId($responseArray[static::REQUEST_ID]);
163
164
        return $header;
165
    }
166
167
    /**
168
     * @param \Generated\Shared\Transfer\AmazonpayResponseHeaderTransfer $header
169
     *
170
     * @return void
171
     */
172
    protected function extractErrorFromConstraints(AmazonpayResponseHeaderTransfer $header)
173
    {
174
        if ($header->getConstraints()->count() === 0) {
175
            return;
176
        }
177
178
        $constraint = $header->getConstraints()[0];
179
        $header->setErrorCode(AmazonpayConstants::PREFIX_AMAZONPAY_PAYMENT_ERROR . $constraint->getConstraintId());
180
    }
181
182
    /**
183
     * @param \PayWithAmazon\ResponseInterface $responseParser
184
     *
185
     * @return bool
186
     */
187
    protected function isSuccess(ResponseInterface $responseParser)
188
    {
189
        return
190
            $this->extractStatusCode($responseParser) === static::STATUS_CODE_SUCCESS
191
            && $this->extractConstraints($responseParser)->count() === 0;
192
    }
193
194
    /**
195
     * @param \PayWithAmazon\ResponseInterface $responseParser
196
     *
197
     * @return array
198
     */
199
    protected function extractResult(ResponseInterface $responseParser)
200
    {
201
        $responseType = $this->getResponseType();
202
203
        return $responseParser->toArray()[$responseType] ?? [];
204
    }
205
206
    /**
207
     * @param \PayWithAmazon\ResponseInterface $responseParser
208
     *
209
     * @return \ArrayObject | \Generated\Shared\Transfer\AmazonpayResponseConstraintTransfer[]
210
     */
211
    protected function extractConstraints(ResponseInterface $responseParser)
212
    {
213
        $result = $this->extractResult($responseParser);
214
215
        $constraintTransfers = new ArrayObject();
216
217
        if (empty($result[static::ORDER_REFERENCE_DETAILS][static::CONSTRAINTS])) {
218
            return $constraintTransfers;
219
        }
220
221
        $constraints = $this->getConstraints($result);
222
223
        foreach ($constraints as $constraint) {
224
            if (!empty($constraint[static::CONSTRAINT_ID]) && !empty($constraint[static::DESCRIPTION])) {
225
                $constraintTransfers[] = $this->buildConstraintTransfer($constraint);
226
            }
227
        }
228
229
        return $constraintTransfers;
230
    }
231
232
    /**
233
     * @param array $result
234
     *
235
     * @return array
236
     */
237
    protected function getConstraints(array $result)
238
    {
239
        if (count($result[static::ORDER_REFERENCE_DETAILS][static::CONSTRAINTS]) === 1) {
240
            return array_values($result[static::ORDER_REFERENCE_DETAILS][static::CONSTRAINTS]);
241
        }
242
243
        return $result[static::ORDER_REFERENCE_DETAILS][static::CONSTRAINTS];
244
    }
245
246
    /**
247
     * @param array $constraint
248
     *
249
     * @return \Generated\Shared\Transfer\AmazonpayResponseConstraintTransfer
250
     */
251
    protected function buildConstraintTransfer(array $constraint)
252
    {
253
        $constraintTransfer = new AmazonpayResponseConstraintTransfer();
254
        $constraintTransfer->setConstraintId($constraint[static::CONSTRAINT_ID]);
255
        $constraintTransfer->setConstraintDescription($constraint[static::DESCRIPTION]);
256
257
        return $constraintTransfer;
258
    }
259
260
    /**
261
     * @param \PayWithAmazon\ResponseInterface $responseParser
262
     *
263
     * @return \Generated\Shared\Transfer\AddressTransfer
264
     */
265
    protected function extractShippingAddress(ResponseInterface $responseParser)
266
    {
267
        $address = new AddressTransfer();
268
269
        if (!$this->isSuccess($responseParser)) {
270
            return $address;
271
        }
272
273
        $aResponseAddress =
274
            $this->extractResult($responseParser)[static::ORDER_REFERENCE_DETAILS][self::DESTINATION][self::PHYSICAL_DESTINATION] ?? null;
275
276
        if ($aResponseAddress !== null) {
277
            $address = $this->convertAddressToTransfer($aResponseAddress);
278
        }
279
280
        return $address;
281
    }
282
283
    /**
284
     * @param array $addressData
285
     *
286
     * @return \Generated\Shared\Transfer\AddressTransfer
287
     */
288
    protected function convertAddressToTransfer(array $addressData)
289
    {
290
        $address = new AddressTransfer();
291
292
        if (!empty($addressData[self::NAME])) {
293
            $address = $this->updateNameData($address, $addressData[self::NAME]);
294
        }
295
296
        $addressData = array_map([$this, 'getStringValue'], $addressData);
297
298
        $address->setCity($addressData[self::CITY] ?? null);
299
        $address->setIso2Code($addressData[self::COUNTRY_CODE] ?? null);
300
        $address->setZipCode($addressData[self::POSTAL_CODE] ?? null);
301
        $address->setAddress1($addressData[self::ADDRESS_LINE_1] ?? null);
302
        $address->setAddress2($addressData[self::ADDRESS_LINE_2] ?? null);
303
        $address->setAddress3($addressData[self::ADDRESS_LINE_3] ?? null);
304
        $address->setRegion($addressData[self::DISTRICT] ?? null);
305
        $address->setState($addressData[self::STATE_OR_REGION] ?? null);
306
        $address->setPhone($addressData[self::PHONE] ?? null);
307
308
        return $address;
309
    }
310
311
    /**
312
     * @param string|array $value
313
     *
314
     * @return string|null
315
     */
316
    protected function getStringValue($value)
317
    {
318
        return empty($value) ? null : (string)$value;
319
    }
320
321
}
322