Passed
Push — master ( 2fd05c...9d8025 )
by Bruno
02:00
created

PaymentDataRequest::build()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 30
rs 8.8177
c 0
b 0
f 0
cc 6
nc 9
nop 1
1
<?php
2
/**
3
 * Copyright © Wirecard Brasil. All rights reserved.
4
 *
5
 * @author    Bruno Elisei <[email protected]>
6
 * See COPYING.txt for license details.
7
 */
8
9
namespace Moip\Magento2\Gateway\Request;
10
11
use Magento\Payment\Gateway\Data\PaymentDataObjectInterface;
12
use Magento\Payment\Gateway\Request\BuilderInterface;
13
use Moip\Magento2\Gateway\Config\Config;
14
use Moip\Magento2\Gateway\Config\ConfigBoleto;
15
use Moip\Magento2\Gateway\Config\ConfigCc;
16
use Moip\Magento2\Gateway\Data\Order\OrderAdapterFactory;
17
use Moip\Magento2\Gateway\SubjectReader;
18
19
/**
20
 * Class PaymentDataRequest - Payment data structure.
21
 */
22
class PaymentDataRequest implements BuilderInterface
23
{
24
    /**
25
     * Payment Instrument - Block name.
26
     */
27
    const PAYMENT_INSTRUMENT = 'paymentInstrument';
28
29
    /**
30
     * Installment count - Number of payment installments.
31
     */
32
    const INSTALLMENT_COUNT = 'installmentCount';
33
34
    /**
35
     * Statement descriptor - Invoice description.
36
     */
37
    const STATEMENT_DESCRIPTOR = 'statementDescriptor';
38
39
    /**
40
     * Funding instrument - Block name.
41
     */
42
    const FUNDING_INSTRUMENT = 'fundingInstrument';
43
44
    /**
45
     * Method - Block Name.
46
     */
47
    const METHOD = 'method';
48
49
    /**
50
     * Credit card - Block name.
51
     */
52
    const TYPE_CREDIT_CARD = 'creditCard';
53
54
    /**
55
     * Credit card store - Sets whether to store the card.
56
     */
57
    const CREDIT_CARD_STORE = 'store';
58
59
    /**
60
     * Credit card hash - Card encryption data.
61
     */
62
    const CREDIT_CARD_HASH = 'hash';
63
64
    /**
65
     * Credit card id - Card Id.
66
     */
67
    const CREDIT_CARD_ID = 'id';
68
69
    /**
70
     * Credit card CVV - Card CVV data.
71
     */
72
    const CREDIT_CARD_CVV = 'cvv';
73
74
    /**
75
     * Credit card holder - Block name.
76
     */
77
    const CREDIT_HOLDER = 'holder';
78
79
    /**
80
     * Credit card holder full name.
81
     */
82
    const CREDIT_HOLDER_FULLNAME = 'fullname';
83
84
    /**
85
     * Credit card holder birth date.
86
     */
87
    const CREDIT_HOLDER_BIRTH_DATA = 'birthdate';
88
89
    /**
90
     * Credit card holder tax document - Block name.
91
     */
92
    const CREDIT_HOLDER_TAX_DOCUMENT = 'taxDocument';
93
94
    /**
95
     * Credit card holder tax document type.
96
     */
97
    const CREDIT_HOLDER_TAX_DOCUMENT_TYPE = 'type';
98
99
    /**
100
     * Credit card holder tax document number.
101
     */
102
    const CREDIT_HOLDER_TAX_DOCUMENT_NUMBER = 'number';
103
104
    /**
105
     * Credit card holder phone - Block name.
106
     */
107
    const CREDIT_HOLDER_PHONE = 'phone';
108
109
    /**
110
     * Credit card holder phone country code.
111
     */
112
    const CREDIT_HOLDER_PHONE_COUNTRY_CODE = 'countryCode';
113
114
    /**
115
     * Credit card holder phone area code.
116
     */
117
    const CREDIT_HOLDER_PHONE_AREA_CODE = 'areaCode';
118
119
    /**
120
     * Credit card holder phone number.
121
     */
122
    const CREDIT_HOLDER_PHONE_NUMBER = 'number';
123
124
    /**
125
     * Boleto - Block name.
126
     */
127
    const TYPE_BOLETO = 'boleto';
128
129
    /**
130
     * Boleto expiration date - Due date.
131
     */
132
    const BOLETO_EXPIRATION_DATE = 'expirationDate';
133
134
    /**
135
     * Boleto instruction lines - Block name.
136
     */
137
    const BOLETO_INSTRUCTION_LINES = 'instructionLines';
138
139
    /**
140
     * Boleto instruction lines first - First line impression data.
141
     */
142
    const BOLETO_INSTRUCTION_LINES_FIRST = 'first';
143
144
    /**
145
     * Boleto instruction lines second - Second line impression data.
146
     */
147
    const BOLETO_INSTRUCTION_LINES_SECOND = 'second';
148
149
    /**
150
     * Boleto instruction lines third - Third line impression data.
151
     */
152
    const BOLETO_INSTRUCTION_LINES_THIRD = 'third';
153
154
    /**
155
     * Boleto logo Uri - Url logo.
156
     */
157
    const BOLETO_LOGO_URI = 'logoUri';
158
159
    /**
160
     * @var SubjectReader
161
     */
162
    private $subjectReader;
163
164
    /**
165
     * @var OrderAdapterFactory
166
     */
167
    private $orderAdapterFactory;
168
169
    /**
170
     * @var Config
171
     */
172
    private $config;
173
174
    /**
175
     * @var Config Boleto
176
     */
177
    private $configBoleto;
178
179
    /**
180
     * @var Config Cc
181
     */
182
    private $configCc;
183
184
    /**
185
     * @param SubjectReader       $subjectReader
186
     * @param OrderAdapterFactory $orderAdapterFactory
187
     * @param Config              $config
188
     */
189 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
190
        SubjectReader $subjectReader,
191
        OrderAdapterFactory $orderAdapterFactory,
192
        Config $config,
193
        ConfigCc $configCc,
194
        ConfigBoleto $configBoleto
195
    ) {
196
        $this->subjectReader = $subjectReader;
197
        $this->orderAdapterFactory = $orderAdapterFactory;
198
        $this->config = $config;
199
        $this->configCc = $configCc;
200
        $this->configBoleto = $configBoleto;
201
    }
202
203
    /**
204
     * {@inheritdoc}
205
     */
206
    public function build(array $buildSubject)
207
    {
208
        if (!isset($buildSubject['payment'])
209
            || !$buildSubject['payment'] instanceof PaymentDataObjectInterface
0 ignored issues
show
Bug introduced by
The class Magento\Payment\Gateway\...mentDataObjectInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
210
        ) {
211
            throw new \InvalidArgumentException('Payment data object should be provided');
212
        }
213
214
        $paymentDO = $buildSubject['payment'];
215
        $payment = $paymentDO->getPayment();
216
        $orderAdapter = $this->orderAdapterFactory->create(
217
            ['order' => $payment->getOrder()]
218
        );
219
        $order = $paymentDO->getOrder();
220
        $storeId = $order->getStoreId();
221
        $result = [];
222
223
        if ($payment->getMethod() === 'moip_magento2_cc') {
224
            $result = $this->getDataPaymetCC($payment, $orderAdapter, $storeId);
225
        }
226
        if ($payment->getMethod() === 'moip_magento2_cc_vault') {
227
            $result = $this->getDataPaymetCCVault($payment, $storeId);
228
        }
229
230
        if ($payment->getMethod() === 'moip_magento2_boleto') {
231
            $result = $this->getDataPaymetBoleto($storeId);
232
        }
233
234
        return $result;
235
    }
236
237
    /**
238
     * Data for Boleto.
239
     *
240
     * @param $storeId
241
     *
242
     * @return array
243
     */
244
    public function getDataPaymetBoleto($storeId)
245
    {
246
        $instruction[self::PAYMENT_INSTRUMENT] = [
0 ignored issues
show
Coding Style Comprehensibility introduced by
$instruction was never initialized. Although not strictly required by PHP, it is generally a good practice to add $instruction = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
247
            self::FUNDING_INSTRUMENT => [
248
                self::STATEMENT_DESCRIPTOR => substr($this->config->getStatementDescriptor($storeId), 0, 13),
249
                self::METHOD               => 'BOLETO',
250
                self::TYPE_BOLETO          => [
251
                    self::BOLETO_EXPIRATION_DATE   => $this->configBoleto->getExpiration($storeId),
252
                    self::BOLETO_INSTRUCTION_LINES => [
253
                        // phpcs:ignore Generic.Files.LineLength
254
                        self::BOLETO_INSTRUCTION_LINES_FIRST  => $this->configBoleto->getInstructionLineFirst($storeId),
255
                        // phpcs:ignore Generic.Files.LineLength
256
                        self::BOLETO_INSTRUCTION_LINES_SECOND => $this->configBoleto->getInstructionLineSecond($storeId),
257
                        // phpcs:ignore Generic.Files.LineLength
258
                        self::BOLETO_INSTRUCTION_LINES_THIRD  => $this->configBoleto->getInstructionLineThird($storeId),
259
                    ],
260
                    self::BOLETO_LOGO_URI => null,
261
                ],
262
            ],
263
        ];
264
265
        return $instruction;
266
    }
267
268
    /**
269
     * Data for CC Vault.
270
     *
271
     * @param $payment
272
     * @param $orderAdapter
273
     * @param $storeId
274
     *
275
     * @return array
276
     */
277
    public function getDataPaymetCCVault($payment, $storeId)
278
    {
279
        $extensionAttributes = $payment->getExtensionAttributes();
280
        $paymentToken = $extensionAttributes->getVaultPaymentToken();
281
282
        $instruction[self::PAYMENT_INSTRUMENT] = [
0 ignored issues
show
Coding Style Comprehensibility introduced by
$instruction was never initialized. Although not strictly required by PHP, it is generally a good practice to add $instruction = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
283
            self::INSTALLMENT_COUNT    => $payment->getAdditionalInformation('cc_installments') ?: 1,
284
            self::STATEMENT_DESCRIPTOR => substr($this->config->getStatementDescriptor($storeId), 0, 13),
285
            self::FUNDING_INSTRUMENT   => [
286
                self::METHOD           => 'CREDIT_CARD',
287
                self::TYPE_CREDIT_CARD => [
288
                    self::CREDIT_CARD_ID   => $paymentToken->getGatewayToken(),
289
                    self::CREDIT_CARD_CVV  => $payment->getAdditionalInformation('cc_cid'),
290
                ],
291
            ],
292
        ];
293
294
        $payment->unsAdditionalInformation('cc_cid');
295
296
        return $instruction;
297
    }
298
299
    /**
300
     * Data for CC.
301
     *
302
     * @param $payment
303
     * @param $orderAdapter
304
     * @param $storeId
305
     *
306
     * @return array
307
     */
308
    public function getDataPaymetCC($payment, $orderAdapter, $storeId)
309
    {
310
        $phone = $payment->getAdditionalInformation('cc_holder_phone');
311
        if (!$phone) {
312
            $phone = $orderAdapter->getBillingAddress()->getTelephone();
313
        }
314
        $dob = $payment->getAdditionalInformation('cc_holder_birth_date');
315
        if (!$dob) {
316
            $dob = $orderAdapter->getCustomerDob() ? $orderAdapter->getCustomerDob() : '1985-10-10';
317
        }
318
        $stored = $payment->getAdditionalInformation('is_active_payment_token_enabler');
319
        $instruction[self::PAYMENT_INSTRUMENT] = [
0 ignored issues
show
Coding Style Comprehensibility introduced by
$instruction was never initialized. Although not strictly required by PHP, it is generally a good practice to add $instruction = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
320
            self::INSTALLMENT_COUNT    => $payment->getAdditionalInformation('cc_installments') ?: 1,
321
            self::STATEMENT_DESCRIPTOR => substr($this->config->getStatementDescriptor($storeId), 0, 13),
322
            self::FUNDING_INSTRUMENT   => [
323
                self::METHOD           => 'CREDIT_CARD',
324
                self::TYPE_CREDIT_CARD => [
325
                    self::CREDIT_CARD_HASH   => $payment->getAdditionalInformation('cc_hash'),
326
                    self::CREDIT_CARD_STORE  => (bool) $stored,
327
                    self::CREDIT_HOLDER      => [
328
                        self::CREDIT_HOLDER_FULLNAME   => $payment->getAdditionalInformation('cc_holder_fullname'),
329
                        self::CREDIT_HOLDER_BIRTH_DATA => date('Y-m-d', strtotime($dob)),
330
                        self::CREDIT_HOLDER_PHONE      => $this->structurePhone($phone),
331
                    ],
332
333
                ],
334
            ],
335
        ];
336
337
        $taxDocument = $payment->getAdditionalInformation('cc_holder_tax_document');
338
        if (!$taxDocument) {
339
            $taxDocument = $this->getValueForTaxDocument($orderAdapter);
340
        }
341
342
        $taxDocument = preg_replace('/[^0-9]/', '', $taxDocument);
343
        $typeDocument = 'CPF';
344
        if (strlen($taxDocument) === 14) {
345
            $typeDocument = 'CNPJ';
346
        }
347
348
        if ($typeDocument) {
349
            // phpcs:ignore Generic.Files.LineLength
350
            $instruction[self::PAYMENT_INSTRUMENT][self::FUNDING_INSTRUMENT][self::TYPE_CREDIT_CARD][self::CREDIT_HOLDER][self::CREDIT_HOLDER_TAX_DOCUMENT] = [
351
                self::CREDIT_HOLDER_TAX_DOCUMENT_TYPE   => $typeDocument,
352
                self::CREDIT_HOLDER_TAX_DOCUMENT_NUMBER => $taxDocument,
353
            ];
354
        }
355
356
        return $instruction;
357
    }
358
359
    /**
360
     * Value For Field Address.
361
     *
362
     * @param $param_telefone
363
     * @param $return_ddd
364
     *
365
     * @return string value
366
     */
367
    public function getNumberOrDDD($param_telefone, $return_ddd = false)
368
    {
369
        $cust_ddd = '11';
370
        $cust_telephone = preg_replace('/[^0-9]/', '', $param_telefone);
371
        if (strlen($cust_telephone) == 11) {
372
            $str = strlen($cust_telephone) - 9;
373
            $indice = 9;
374
        } else {
375
            $str = strlen($cust_telephone) - 8;
376
            $indice = 8;
377
        }
378
379
        if ($str > 0) {
380
            $cust_ddd = substr($cust_telephone, 0, 2);
381
            $cust_telephone = substr($cust_telephone, $str, $indice);
382
        }
383
        if ($return_ddd === false) {
384
            $result = $cust_telephone;
385
        } else {
386
            $result = $cust_ddd;
387
        }
388
389
        return $result;
390
    }
391
392
    /**
393
     * ValueForTaxDocument.
394
     *
395
     * @param $orderAdapter
396
     *
397
     * @return value
398
     */
399 View Code Duplication
    public function getValueForTaxDocument($orderAdapter)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
400
    {
401
        $obtainTaxDocFrom = $this->config->getAddtionalValue('type_cpf');
402
403
        if ($obtainTaxDocFrom === 'customer') {
404
            $taxDocument = $orderAdapter->getCustomerTaxvat();
405
            $attTaxDocCus = $this->config->getAddtionalValue('cpf_for_customer');
406
407
            if ($attTaxDocCus !== 'taxvat') {
408
                $taxDocument = $orderAdapter->getData($attTaxDocCus);
409
            }
410
        } else {
411
            $taxDocument = $orderAdapter->getBillingAddress()->getVatId();
412
            $attTaxDocAddress = $this->config->getAddtionalValue('cpf_for_address');
413
414
            if ($attTaxDocAddress !== 'vat_id') {
415
                $taxDocument = $orderAdapter->getBillingAddress()->getData($attTaxDocAddress);
416
            }
417
        }
418
419
        // * Contigência para caso não haja o atributo informado pelo Admin busque me 2 outros campos comuns.
420
        if (!$taxDocument) {
421
            $taxDocument = $orderAdapter->getBillingAddress()->getVatId();
422
423
            $obtainTaxDocFrom = $this->config->getAddtionalValue('type_cpf');
424
            if ($obtainTaxDocFrom === 'customer') {
425
                $taxDocument = $orderAdapter->getCustomerTaxvat();
426
            }
427
        }
428
429
        return $taxDocument;
430
    }
431
432
    /**
433
     * StructurePhone.
434
     *
435
     * @param  $phone
436
     *
437
     * @return array
438
     */
439
    public function structurePhone($phone)
440
    {
441
        return [
442
            self::CREDIT_HOLDER_PHONE_COUNTRY_CODE => (int) 55,
443
            self::CREDIT_HOLDER_PHONE_AREA_CODE    => (int) $this->getNumberOrDDD($phone, true),
444
            self::CREDIT_HOLDER_PHONE_NUMBER       => (int) $this->getNumberOrDDD($phone),
445
        ];
446
    }
447
}
448