Index   F
last analyzed

Complexity

Total Complexity 84

Size/Duplication

Total Lines 758
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 352
c 1
b 0
f 0
dl 0
loc 758
rs 2
wmc 84

29 Methods

Rating   Name   Duplication   Size   Complexity  
A validateAmount() 0 6 2
A __construct() 0 29 3
B blockConcurrency() 0 39 6
A isNotification() 0 3 1
A checkPagantisStatus() 0 10 3
A rollbackMerchantOrder() 0 8 2
A setProduct() 0 3 1
A getQuoteId() 0 5 2
A checkOrderStatus() 0 10 3
A getOrigin() 0 3 1
A getPagantisOrder() 0 10 2
A checkConcurrency() 0 6 1
A setOrigin() 0 3 1
A unblockConcurrency() 0 13 4
A isRedirect() 0 3 1
A saveOrder() 0 41 5
A getPagantisOrderId() 0 14 3
A checkMerchantOrderStatus() 0 5 2
A checkDbLogTable() 0 28 3
C execute() 0 77 9
A insertLog() 0 21 5
A getMagentoOrderId() 0 23 3
A checkDbTable() 0 11 2
A getProduct() 0 3 1
A getMerchantOrder() 0 7 2
A processMerchantOrder() 0 7 2
A updateBdInfo() 0 14 2
B getRedirectUrl() 0 54 10
A confirmpagantisOrder() 0 14 2

How to fix   Complexity   

Complex Class

Complex classes like Index often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Index, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Pagantis\Pagantis\Controller\Notify;
4
5
use Magento\Quote\Model\QuoteManagement;
6
use Magento\Quote\Api\Data\PaymentInterface;
7
use Magento\Sales\Api\Data\OrderInterface;
8
use Magento\Sales\Api\OrderRepositoryInterface;
9
use Magento\Quote\Model\Quote;
10
use Magento\Quote\Model\QuoteRepository;
11
use Magento\Framework\App\Action\Context;
12
use Magento\Framework\App\Action\Action;
13
use Pagantis\ModuleUtils\Exception\MerchantOrderNotFoundException;
14
use Pagantis\OrdersApiClient\Client;
15
use Pagantis\Pagantis\Helper\Config;
16
use Pagantis\Pagantis\Helper\ExtraConfig;
17
use Magento\Framework\App\ResourceConnection;
18
use Magento\Checkout\Model\Session;
19
use Magento\Framework\DB\Ddl\Table;
20
use Pagantis\ModuleUtils\Exception\AmountMismatchException;
21
use Pagantis\ModuleUtils\Exception\ConcurrencyException;
22
use Pagantis\ModuleUtils\Exception\NoIdentificationException;
23
use Pagantis\ModuleUtils\Exception\OrderNotFoundException;
24
use Pagantis\ModuleUtils\Exception\QuoteNotFoundException;
25
use Pagantis\ModuleUtils\Exception\UnknownException;
26
use Pagantis\ModuleUtils\Exception\WrongStatusException;
27
use Pagantis\ModuleUtils\Model\Response\JsonSuccessResponse;
28
use Pagantis\ModuleUtils\Model\Response\JsonExceptionResponse;
29
use Pagantis\ModuleUtils\Exception\AlreadyProcessedException;
30
use Pagantis\ModuleUtils\Model\Log\LogEntry;
31
use Magento\Framework\App\RequestInterface;
32
use Pagantis\Pagantis\Model\Ui\ConfigProvider;
33
34
/**
35
 * Class Index
36
 * @package Pagantis\Pagantis\Controller\Notify
37
 */
38
class Index extends Action
39
{
40
    /** Orders tablename */
41
    const ORDERS_TABLE = 'cart_process';
42
43
    /** Concurrency tablename */
44
    const CONCURRENCY_TABLE = 'Pagantis_orders';
45
46
    /** Concurrency tablename */
47
    const LOGS_TABLE = 'Pagantis_logs';
48
49
    /** Seconds to expire a locked request */
50
    const CONCURRENCY_TIMEOUT = 10;
51
52
    /**
53
     * EXCEPTION RESPONSES
54
     */
55
    const CPO_ERR_MSG = 'Order not confirmed';
56
    const CPO_OK_MSG = 'Order confirmed';
57
58
    /** @var QuoteManagement */
59
    protected $quoteManagement;
60
61
    /** @var PaymentInterface $paymentInterface */
62
    protected $paymentInterface;
63
64
    /** @var OrderRepositoryInterface $orderRepositoryInterface */
65
    protected $orderRepositoryInterface;
66
67
    /** @var Quote $quote */
68
    protected $quote;
69
70
    /** @var QuoteRepository $quoteRepository */
71
    protected $quoteRepository;
72
73
    /** @var mixed $config */
74
    protected $config;
75
76
    /** @var mixed $quoteId */
77
    protected $quoteId;
78
79
    /** @var array $notifyResult */
80
    protected $notifyResult;
81
82
    /** @var mixed $magentoOrderId */
83
    protected $magentoOrderId;
84
85
    /** @var mixed $pagantisOrder */
86
    protected $pagantisOrder;
87
88
    /** @var ResourceConnection $dbObject */
89
    protected $dbObject;
90
91
    /** @var Session $checkoutSession */
92
    protected $checkoutSession;
93
94
    /** @var Client $orderClient */
95
    protected $orderClient;
96
97
    /** @var mixed $pagantisOrderId */
98
    protected $pagantisOrderId;
99
100
    /** @var  OrderInterface $magentoOrder */
101
    protected $magentoOrder;
102
103
    /** @var ExtraConfig $extraConfig */
104
    protected $extraConfig;
105
106
    /** @var mixed $origin */
107
    protected $origin;
108
109
    /** @var mixed $product */
110
    protected $product;
111
112
    /** @var RequestInterface $_request*/
113
    protected $_request;
114
115
    /** @var mixed $origin */
116
    protected $token;
117
118
    /**
119
     * Index constructor.
120
     *
121
     * @param Context                  $context
122
     * @param Quote                    $quote
123
     * @param QuoteManagement          $quoteManagement
124
     * @param PaymentInterface         $paymentInterface
125
     * @param Config                   $config
126
     * @param QuoteRepository          $quoteRepository
127
     * @param OrderRepositoryInterface $orderRepositoryInterface
128
     * @param ResourceConnection       $dbObject
129
     * @param Session                  $checkoutSession
130
     * @param ExtraConfig              $extraConfig
131
     * @param RequestInterface         $request
132
     */
133
    public function __construct(
134
        Context $context,
135
        Quote $quote,
136
        QuoteManagement $quoteManagement,
137
        PaymentInterface $paymentInterface,
138
        Config $config,
139
        QuoteRepository $quoteRepository,
140
        OrderRepositoryInterface $orderRepositoryInterface,
141
        ResourceConnection $dbObject,
142
        Session $checkoutSession,
143
        ExtraConfig $extraConfig,
144
        RequestInterface $request
145
    ) {
146
        parent::__construct($context);
147
        $this->quote = $quote;
148
        $this->quoteManagement = $quoteManagement;
149
        $this->paymentInterface = $paymentInterface;
150
        $this->extraConfig = $extraConfig->getExtraConfig();
0 ignored issues
show
Documentation Bug introduced by pgarces
It seems like $extraConfig->getExtraConfig() of type array or array is incompatible with the declared type Pagantis\Pagantis\Helper\ExtraConfig of property $extraConfig.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
151
        $this->config = $config->getConfig();
152
        $this->quoteRepository = $quoteRepository;
153
        $this->orderRepositoryInterface = $orderRepositoryInterface;
154
        $this->dbObject = $dbObject;
155
        $this->checkoutSession = $checkoutSession;
156
        $this->_request = $request;
157
        $this->origin = (
158
            $this->_request->isPost() || $this->_request->getParam('origin')=='notification'
0 ignored issues
show
Bug introduced by pgarces
The method isPost() does not exist on Magento\Framework\App\RequestInterface. It seems like you code against a sub-type of Magento\Framework\App\RequestInterface such as Magento\Framework\Webapi\Request or Magento\Framework\App\Request\Http. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

158
            $this->_request->/** @scrutinizer ignore-call */ 
159
                             isPost() || $this->_request->getParam('origin')=='notification'
Loading history...
159
        ) ? 'Notification' : 'Order';
160
        $this->product = $this->_request->getParam('product');
161
        $this->token = $this->_request->getParam('token');
162
    }
163
164
    /**
165
     * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void
166
     * @throws UnknownException
167
     */
168
    public function execute()
169
    {
170
        $thrownException = false;
171
        try {
172
            if ($this->_request->isGet() && $this->isNotification()) {
0 ignored issues
show
Bug introduced by pgarces
The method isGet() does not exist on Magento\Framework\App\RequestInterface. It seems like you code against a sub-type of Magento\Framework\App\RequestInterface such as Magento\Framework\Webapi\Request or Magento\Framework\App\Request\Http. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

172
            if ($this->_request->/** @scrutinizer ignore-call */ isGet() && $this->isNotification()) {
Loading history...
173
                echo 'OK';
174
                die;
0 ignored issues
show
Best Practice introduced by pgarces
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
175
            }
176
177
            if ($this->_request->isGet() && $this->isRedirect()) {
178
                $redirectMessage = sprintf(
179
                    "[origin=%s][quoteId=%s]",
180
                    $this->getOrigin(),
181
                    $this->getRequest()->getParam('quoteId')
182
                );
183
                $this->insertLog(null, $redirectMessage);
184
            }
185
186
            $this->checkConcurrency();
187
            $this->getMerchantOrder();
188
            $this->getPagantisOrderId();
189
            $this->getPagantisOrder();
190
            $this->checkOrderStatus();
191
            $this->checkMerchantOrderStatus();
192
            $this->validateAmount();
193
            $this->processMerchantOrder();
194
        } catch (\Exception $exception) {
195
            $thrownException = true;
196
            $jsonResponse = new JsonExceptionResponse();
197
            $jsonResponse->setMerchantOrderId($this->magentoOrderId);
198
            $jsonResponse->setpagantisOrderId($this->pagantisOrderId);
199
            $jsonResponse->setException($exception);
200
            $this->insertLog($exception);
201
        }
202
203
        try {
204
            if (!$thrownException) {
205
                $this->confirmpagantisOrder();
206
                $jsonResponse = new JsonSuccessResponse();
207
                $jsonResponse->setMerchantOrderId($this->magentoOrderId);
208
                $jsonResponse->setpagantisOrderId($this->pagantisOrderId);
209
            }
210
        } catch (\Exception $exception) {
211
            $this->rollbackMerchantOrder();
212
            $jsonResponse = new JsonExceptionResponse();
213
            $jsonResponse->setMerchantOrderId($this->magentoOrderId);
214
            $jsonResponse->setpagantisOrderId($this->pagantisOrderId);
215
            $jsonResponse->setException($exception);
216
            $jsonResponse->toJson();
217
            $this->insertLog($exception);
218
        }
219
220
        $this->unblockConcurrency(true);
221
222
        if ($this->isNotification()) {
223
            $returnMessage = sprintf(
224
                "[origin=%s][quoteId=%s][magentoOrderId=%s][pagantisOrderId=%s][message=%s]",
225
                $this->getOrigin(),
226
                $this->quoteId,
227
                $this->magentoOrderId,
228
                $this->pagantisOrderId,
229
                $jsonResponse->getResult()
0 ignored issues
show
Comprehensibility Best Practice introduced by pgarces
The variable $jsonResponse does not seem to be defined for all execution paths leading up to this point.
Loading history...
230
            );
231
            $this->insertLog(null, $returnMessage);
232
            $jsonResponse->printResponse();
233
        } else {
234
            $returnUrl = $this->getRedirectUrl();
235
            $returnMessage = sprintf(
236
                "[origin=%s][quoteId=%s][magentoOrderId=%s][pagantisOrderId=%s][returnUrl=%s]",
237
                $this->getOrigin(),
238
                $this->quoteId,
239
                $this->magentoOrderId,
240
                $this->pagantisOrderId,
241
                $returnUrl
242
            );
243
            $this->insertLog(null, $returnMessage);
244
            $this->_redirect($returnUrl);
245
        }
246
    }
247
248
    /**
249
     * COMMON FUNCTIONS
250
     */
251
252
    /**
253
     * @throws ConcurrencyException
254
     * @throws QuoteNotFoundException
255
     * @throws UnknownException
256
     */
257
    private function checkConcurrency()
258
    {
259
        $this->getQuoteId();
260
        $this->checkDbTable();
261
        $this->unblockConcurrency();
262
        $this->blockConcurrency();
263
    }
264
265
    /**
266
     * @throws MerchantOrderNotFoundException
267
     */
268
    private function getMerchantOrder()
269
    {
270
        try {
271
            /** @var Quote quote */
272
            $this->quote = $this->quoteRepository->get($this->quoteId);
273
        } catch (\Exception $e) {
274
            throw new MerchantOrderNotFoundException();
275
        }
276
    }
277
278
    /**
279
     * @throws UnknownException
280
     */
281
    private function getPagantisOrderId()
282
    {
283
        try {
284
            /** @var \Magento\Framework\DB\Adapter\AdapterInterface $dbConnection */
285
            $dbConnection     = $this->dbObject->getConnection();
286
            $tableName        = $this->dbObject->getTableName(self::ORDERS_TABLE);
287
            $query            = "select order_id from $tableName where id='.$this->quoteId.' and token='.$this->token.'";
288
            $queryResult      = $dbConnection->fetchRow($query);
289
            $this->pagantisOrderId = $queryResult['order_id'];
290
            if ($this->pagantisOrderId == '') {
291
                throw new NoIdentificationException();
292
            }
293
        } catch (\Exception $e) {
294
            throw new UnknownException($e->getMessage());
295
        }
296
    }
297
298
    /**
299
     * @throws OrderNotFoundException
300
     */
301
    private function getPagantisOrder()
302
    {
303
        try {
304
            $this->orderClient = new Client(
305
                $this->config['pagantis_public_key'],
306
                $this->config['pagantis_private_key']
307
            );
308
            $this->pagantisOrder = $this->orderClient->getOrder($this->pagantisOrderId);
309
        } catch (\Exception $e) {
310
            throw new OrderNotFoundException();
311
        }
312
    }
313
314
    /**
315
     * @throws AlreadyProcessedException
316
     * @throws WrongStatusException
317
     */
318
    private function checkOrderStatus()
319
    {
320
        try {
321
            $this->checkPagantisStatus(array('AUTHORIZED'));
322
        } catch (\Exception $e) {
323
            $this->getMagentoOrderId();
324
            if ($this->magentoOrderId!='') {
325
                throw new AlreadyProcessedException();
326
            } else {
327
                throw new WrongStatusException($this->pagantisOrder->getStatus());
328
            }
329
        }
330
    }
331
332
    /**
333
     * @throws AlreadyProcessedException
334
     */
335
    private function checkMerchantOrderStatus()
336
    {
337
        if ($this->quote->getIsActive()=='0') {
338
            $this->getMagentoOrderId();
339
            throw new AlreadyProcessedException();
340
        }
341
    }
342
343
    /**
344
     * @throws AmountMismatchException
345
     */
346
    private function validateAmount()
347
    {
348
        $pagantisAmount = $this->pagantisOrder->getShoppingCart()->getTotalAmount();
349
        $merchantAmount = intval(100 * $this->quote->getGrandTotal());
350
        if ($pagantisAmount != $merchantAmount) {
351
            throw new AmountMismatchException($pagantisAmount, $merchantAmount);
352
        }
353
    }
354
355
    /**
356
     * @throws UnknownException
357
     */
358
    private function processMerchantOrder()
359
    {
360
        try {
361
            $this->saveOrder();
362
            $this->updateBdInfo();
363
        } catch (\Exception $e) {
364
            throw new UnknownException($e->getMessage());
365
        }
366
    }
367
368
    /**
369
     * @return false|string
370
     * @throws UnknownException
371
     */
372
    private function confirmpagantisOrder()
373
    {
374
        try {
375
            $this->pagantisOrder = $this->orderClient->confirmOrder($this->pagantisOrderId);
376
        } catch (\Exception $e) {
377
            throw new UnknownException(sprintf("[%s]%s", $this->getOrigin(), $e->getMessage()));
378
        }
379
380
        $jsonResponse = new JsonSuccessResponse();
381
        $jsonResponse->setStatusCode(200);
382
        $jsonResponse->setMerchantOrderId($this->magentoOrderId);
383
        $jsonResponse->setpagantisOrderId($this->pagantisOrderId);
384
        $jsonResponse->setResult(self::CPO_OK_MSG);
385
        return $jsonResponse->toJson();
386
    }
387
388
    /**
389
     * UTILS FUNCTIONS
390
     */
391
392
    /** STEP 1 CC - Check concurrency
393
     * @throws QuoteNotFoundException
394
     */
395
    private function getQuoteId()
396
    {
397
        $this->quoteId = $this->getRequest()->getParam('quoteId');
398
        if ($this->quoteId == '') {
399
            throw new QuoteNotFoundException();
400
        }
401
    }
402
403
    /**
404
     * @return \Zend_Db_Statement_Interface
405
     * @throws UnknownException
406
     */
407
    private function checkDbTable()
408
    {
409
        try {
410
            /** @var \Magento\Framework\DB\Adapter\AdapterInterface $dbConnection */
411
            $dbConnection = $this->dbObject->getConnection();
412
            $tableName    = $this->dbObject->getTableName(self::CONCURRENCY_TABLE);
413
            $query        = "CREATE TABLE IF NOT EXISTS $tableName(`id` int not null,`timestamp` int not null,PRIMARY KEY (`id`))";
414
415
            return $dbConnection->query($query);
416
        } catch (\Exception $e) {
417
            throw new UnknownException($e->getMessage());
418
        }
419
    }
420
421
    /**
422
     * @return void|\Zend_Db_Statement_Interface
423
     * @throws UnknownException
424
     */
425
    private function checkDbLogTable()
426
    {
427
        try {
428
            /** @var \Magento\Framework\DB\Adapter\AdapterInterface $dbConnection */
429
            $dbConnection = $this->dbObject->getConnection();
430
            $tableName = $this->dbObject->getTableName(self::LOGS_TABLE);
431
            if (!$dbConnection->isTableExists($tableName)) {
432
                $table = $dbConnection
433
                    ->newTable($tableName)
434
                    ->addColumn(
435
                        'id',
436
                        Table::TYPE_SMALLINT,
437
                        null,
438
                        array('nullable'=>false, 'auto_increment'=>true, 'primary'=>true)
439
                    )
440
                    ->addColumn('log', Table::TYPE_TEXT, null, array('nullable'=>false))
441
                    ->addColumn(
442
                        'createdAt',
443
                        Table::TYPE_TIMESTAMP,
444
                        null,
445
                        array('nullable'=>false, 'default'=>Table::TIMESTAMP_INIT)
446
                    );
447
                return $dbConnection->createTable($table);
448
            }
449
450
            return;
451
        } catch (\Exception $e) {
452
            throw new UnknownException($e->getMessage());
453
        }
454
    }
455
456
    /**
457
     * @param bool $mode
458
     *
459
     * @throws \Exception
460
     */
461
    private function unblockConcurrency($mode = false)
462
    {
463
        try {
464
            /** @var \Magento\Framework\DB\Adapter\AdapterInterface $dbConnection */
465
            $dbConnection = $this->dbObject->getConnection();
466
            $tableName    = $this->dbObject->getTableName(self::CONCURRENCY_TABLE);
467
            if ($mode == false) {
0 ignored issues
show
Coding Style Best Practice introduced by pgarces
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
468
                $dbConnection->delete($tableName, "timestamp<".(time() - 5));
469
            } elseif ($this->quoteId!='') {
470
                $dbConnection->delete($tableName, "id=".$this->quoteId);
471
            }
472
        } catch (Exception $exception) {
0 ignored issues
show
Bug introduced by pgarces
The type Pagantis\Pagantis\Controller\Notify\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
473
            throw new ConcurrencyException();
474
        }
475
    }
476
477
    /**
478
     * @throws ConcurrencyException
479
     * @throws UnknownException
480
     */
481
    private function blockConcurrency()
482
    {
483
        /** @var \Magento\Framework\DB\Adapter\AdapterInterface $dbConnection */
484
        $dbConnection = $this->dbObject->getConnection();
485
        $tableName    = $this->dbObject->getTableName(self::CONCURRENCY_TABLE);
486
        $query = "SELECT timestamp FROM $tableName where id='$this->quoteId'";
487
        $resultsSelect = $dbConnection->fetchRow($query);
488
        if (isset($resultsSelect['timestamp'])) {
489
            if ($this->isNotification()) {
490
                throw new ConcurrencyException();
491
            } else {
492
                $query = sprintf(
493
                    "SELECT timestamp - %s as rest FROM %s %s",
494
                    (time() - self::CONCURRENCY_TIMEOUT),
495
                    $tableName,
496
                    "WHERE id='".$this->quoteId."'"
497
                );
498
                $resultsSelect = $dbConnection->fetchRow($query);
499
                $restSeconds   = isset($resultsSelect['rest']) ? ($resultsSelect['rest']) : 0;
500
                $expirationSec = ($restSeconds > self::CONCURRENCY_TIMEOUT) ? self::CONCURRENCY_TIMEOUT : $restSeconds;
501
                if ($expirationSec > 0) {
502
                    sleep($expirationSec + 1);
503
                }
504
505
                $this->getPagantisOrderId();
506
                $this->getMagentoOrderId();
507
508
                $logMessage  = sprintf(
509
                    "User waiting %s seconds, default seconds %s, bd time to expire %s seconds[quoteId=%s][origin=%s]",
510
                    $expirationSec,
511
                    self::CONCURRENCY_TIMEOUT,
512
                    $restSeconds,
513
                    $this->quoteId,
514
                    $this->getOrigin()
515
                );
516
                throw new UnknownException($logMessage);
517
            }
518
        } else {
519
            $dbConnection->insert($tableName, array('id'=>$this->quoteId, 'timestamp'=>time()));
520
        }
521
    }
522
523
    /** STEP 2 GMO - Get Merchant Order */
524
    /** STEP 3 GPOI - Get Pagantis OrderId */
525
    /** STEP 4 GPO - Get Pagantis Order */
526
    /** STEP 5 COS - Check Order Status */
527
    /**
528
     * @param $statusArray
529
     *
530
     * @throws \Exception
531
     */
532
    private function checkPagantisStatus($statusArray)
533
    {
534
        $pagantisStatus = array();
535
        foreach ($statusArray as $status) {
536
            $pagantisStatus[] = constant("\Pagantis\OrdersApiClient\Model\Order::STATUS_$status");
537
        }
538
539
        $payed = in_array($this->pagantisOrder->getStatus(), $pagantisStatus);
540
        if (!$payed) {
541
            throw new WrongStatusException($this->pagantisOrder->getStatus());
542
        }
543
    }
544
545
    /** STEP 6 CMOS - Check Merchant Order Status */
546
    /**
547
     * @throws \Exception
548
     */
549
    private function getMagentoOrderId()
550
    {
551
        try {
552
            /** @var \Magento\Framework\DB\Adapter\AdapterInterface $dbConnection */
553
            $dbConnection = $this->dbObject->getConnection();
554
            $tableName    = $this->dbObject->getTableName(self::ORDERS_TABLE);
555
556
            if ($this->pagantisOrderId == '') {
557
                $this->getPagantisOrderId();
558
            }
559
            $pagantisOrderId   = $this->pagantisOrderId;
560
561
            $query = sprintf(
562
                "select mg_order_id from %s where id='%s' and order_id='%s' and token='%s'",
563
                $tableName,
564
                $this->quoteId,
565
                $pagantisOrderId,
566
                $this->token
567
            );
568
            $queryResult  = $dbConnection->fetchRow($query);
569
            $this->magentoOrderId = $queryResult['mg_order_id'];
570
        } catch (\Exception $e) {
571
            throw new UnknownException($e->getMessage());
572
        }
573
    }
574
575
    /** STEP 7 VA - Validate Amount */
576
    /** STEP 8 PMO - Process Merchant Order */
577
    /**
578
     * @throws UnknownException
579
     */
580
    private function saveOrder()
581
    {
582
        try {
583
            $this->paymentInterface->setMethod($this->getProduct());
584
            $this->magentoOrderId = $this->quoteManagement->placeOrder($this->quoteId, $this->paymentInterface);
585
586
            /** @var OrderRepositoryInterface magentoOrder */
587
            $this->magentoOrder = $this->orderRepositoryInterface->get($this->magentoOrderId);
588
            $metadataOrder = $this->pagantisOrder->getMetadata();
589
            $metadataInfo = null;
590
            foreach ($metadataOrder as $metadataKey => $metadataValue) {
591
                if ($metadataKey == 'promotedProduct') {
592
                    $metadataInfo.= " Producto promocionado = $metadataValue //";
593
                }
594
            }
595
596
            $this->magentoOrder->addStatusHistoryComment($metadataInfo)
597
                               ->setIsCustomerNotified(false)
598
                               ->setEntityName('order')
599
                               ->setTitle($this->getProduct())
600
                               ->setPayment($this->getProduct())
601
                               ->save();
602
603
            $comment = sprintf(
604
                'pagantisOrderId: %s || pagantisOrderStatus: %s  || via: %s  || product: %s',
605
                $this->pagantisOrder->getId(),
606
                $this->pagantisOrder->getStatus(),
607
                $this->getOrigin(),
608
                $this->getProduct()
609
            );
610
611
            $this->magentoOrder->addStatusHistoryComment($comment)
612
                               ->setIsCustomerNotified(false)
613
                               ->setEntityName('order')
614
                               ->save();
615
616
            if ($this->magentoOrderId == '') {
617
                throw new UnknownException('Order can not be saved');
618
            }
619
        } catch (\Exception $e) {
620
            throw new UnknownException($e->getMessage());
621
        }
622
    }
623
624
    /**
625
     * @throws UnknownException
626
     */
627
    private function updateBdInfo()
628
    {
629
        try {
630
            /** @var \Magento\Framework\DB\Adapter\AdapterInterface $dbConnection */
631
            $dbConnection = $this->dbObject->getConnection();
632
            $tableName    = $this->dbObject->getTableName(self::ORDERS_TABLE);
633
            $pagantisOrderId   = $this->pagantisOrder->getId();
634
            $dbConnection->update(
635
                $tableName,
636
                array('mg_order_id' => $this->magentoOrderId),
637
                "order_id='$pagantisOrderId' and id='$this->quoteId'"
638
            );
639
        } catch (\Exception $e) {
640
            throw new UnknownException($e->getMessage());
641
        }
642
    }
643
644
    /** STEP 9 CPO - Confirmation Pagantis Order */
645
    /**
646
     * @throws UnknownException
647
     */
648
    private function rollbackMerchantOrder()
649
    {
650
        try {
651
            $this->magentoOrder->setState(\Magento\Sales\Model\Order::STATE_PENDING_PAYMENT, true);
0 ignored issues
show
Unused Code introduced by pgarces
The call to Magento\Sales\Api\Data\OrderInterface::setState() has too many arguments starting with true. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

651
            $this->magentoOrder->/** @scrutinizer ignore-call */ 
652
                                 setState(\Magento\Sales\Model\Order::STATE_PENDING_PAYMENT, true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
652
            $this->magentoOrder->setStatus(\Magento\Sales\Model\Order::STATE_PENDING_PAYMENT);
653
            $this->magentoOrder->save();
654
        } catch (\Exception $e) {
655
            throw new UnknownException($e->getMessage());
656
        }
657
    }
658
659
    /**
660
     * @return mixed
661
     */
662
    public function getOrigin()
663
    {
664
        return $this->origin;
665
    }
666
667
    /**
668
     * @param mixed $origin
669
     */
670
    public function setOrigin($origin)
671
    {
672
        $this->origin = $origin;
673
    }
674
675
676
    /**
677
     * @return mixed
678
     */
679
    public function getProduct()
680
    {
681
        return $this->product;
682
    }
683
684
    /**
685
     * @param mixed $product
686
     */
687
    public function setProduct($product)
688
    {
689
        $this->product = $product;
690
    }
691
692
    /**
693
     * @return string
694
     * @throws UnknownException
695
     */
696
    private function getRedirectUrl()
697
    {
698
        //$returnUrl = 'checkout/#payment';
699
        $returnUrl = $this->_url->getUrl('checkout', ['_fragment' => 'payment']);
700
701
        if ($this->pagantisOrderId == '') {
702
            $this->getPagantisOrderId();
703
        }
704
705
        if ($this->magentoOrderId == '') {
706
            $this->getMagentoOrderId();
707
        }
708
709
        if ($this->magentoOrderId!='') {
710
            /** @var Order $this->magentoOrder */
711
            $this->magentoOrder = $this->orderRepositoryInterface->get($this->magentoOrderId);
712
            if (!$this->_objectManager->get(\Magento\Checkout\Model\Session\SuccessValidator::class)->isValid()) {
713
                $checkoutMessage = sprintf(
714
                    "[origin=%s][quoteId=%s][magentoOrderId=%s][pagantisOrderId=%s]Setting checkout session",
715
                    $this->getOrigin(),
716
                    $this->quoteId,
717
                    $this->magentoOrderId,
718
                    $this->pagantisOrderId
719
                );
720
                $this->insertLog(null, $checkoutMessage);
721
722
                $this->checkoutSession
723
                    ->setLastOrderId($this->magentoOrderId)
724
                    ->setLastRealOrderId($this->magentoOrder->getIncrementId())
725
                    ->setLastQuoteId($this->quoteId)
726
                    ->setLastSuccessQuoteId($this->quoteId)
727
                    ->setLastOrderStatus($this->magentoOrder->getStatus());
728
            }
729
730
            //Magento status flow => https://docs.magento.com/m2/ce/user_guide/sales/order-status-workflow.html
731
            //Order Workflow => https://docs.magento.com/m2/ce/user_guide/sales/order-workflow.html
732
            $orderStatus    = strtolower($this->magentoOrder->getStatus());
733
            $acceptedStatus = array('processing', 'completed');
734
            if (in_array($orderStatus, $acceptedStatus)) {
735
                if (isset($this->extraConfig['PAGANTIS_OK_URL']) &&  $this->extraConfig['PAGANTIS_OK_URL']!= '') {
736
                    $returnUrl = $this->extraConfig['PAGANTIS_OK_URL'];
737
                } else {
738
                    $returnUrl = 'checkout/onepage/success';
739
                }
740
            } else {
741
                if (isset($this->extraConfig['PAGANTIS_KO_URL']) && $this->extraConfig['PAGANTIS_KO_URL'] != '') {
742
                    $returnUrl = $this->extraConfig['PAGANTIS_KO_URL'];
743
                } else {
744
                    //$returnUrl = 'checkout/#payment';
745
                    $returnUrl = $this->_url->getUrl('checkout', ['_fragment' => 'payment']);
746
                }
747
            }
748
        }
749
        return $returnUrl;
750
    }
751
752
    /**
753
     * @param null $exceptionMessage
0 ignored issues
show
Documentation Bug introduced by pgarces
Are you sure the doc-type for parameter $exceptionMessage is correct as it would always require null to be passed?
Loading history...
754
     * @param null $logMessage
0 ignored issues
show
Documentation Bug introduced by pgarces
Are you sure the doc-type for parameter $logMessage is correct as it would always require null to be passed?
Loading history...
755
     *
756
     * @throws UnknownException
757
     */
758
    private function insertLog($exceptionMessage = null, $logMessage = null)
759
    {
760
        try {
761
            $this->checkDbLogTable();
762
            $logEntryJson = '';
763
            if ($exceptionMessage instanceof \Exception) {
764
                $logEntry     = new LogEntry();
765
                $logEntryJson = $logEntry->error($exceptionMessage)->toJson();
766
            } elseif ($logMessage != null) {
0 ignored issues
show
introduced by pgarces
The condition $logMessage != null is always false.
Loading history...
767
                $logEntry     = new LogEntry();
768
                $logEntryJson = $logEntry->info($logMessage)->toJson();
769
            }
770
771
            if ($logEntryJson != '') {
772
                /** @var \Magento\Framework\DB\Adapter\AdapterInterface $dbConnection */
773
                $dbConnection = $this->dbObject->getConnection();
774
                $tableName    = $this->dbObject->getTableName(self::LOGS_TABLE);
775
                $dbConnection->insert($tableName, array('log' => $logEntryJson));
776
            }
777
        } catch (\Exception $e) {
778
            throw new UnknownException($e->getMessage());
779
        }
780
    }
781
782
    /**
783
     * @return bool
784
     */
785
    private function isNotification()
786
    {
787
        return ($this->getOrigin() == 'Notification');
788
    }
789
790
    /**
791
     * @return bool
792
     */
793
    private function isRedirect()
794
    {
795
        return ($this->getOrigin() == 'Order');
796
    }
797
}
798