Issues (112)

Controller/Payment/Index.php (1 issue)

1
<?php
2
3
namespace Pagantis\Pagantis\Controller\Payment;
4
5
use Magento\Framework\App\Action\Action;
6
use Magento\Framework\App\Action\Context;
7
use Magento\Quote\Model\QuoteRepository;
8
use Magento\Sales\Model\ResourceModel\Order\Collection as OrderCollection;
9
use Magento\Checkout\Model\Session;
10
use Pagantis\OrdersApiClient\Model\Order;
11
use Pagantis\Pagantis\Helper\Config;
12
use Pagantis\Pagantis\Helper\ExtraConfig;
13
use Magento\Framework\App\ResourceConnection;
14
use Magento\Framework\App\ProductMetadataInterface;
15
use Magento\Framework\Module\ModuleList;
16
use Magento\Store\Api\Data\StoreInterface;
17
use Pagantis\OrdersApiClient\Model\Order\User\Address;
18
use Magento\Framework\DB\Ddl\Table;
19
use Pagantis\OrdersApiClient\Model\Order\User;
20
use Pagantis\OrdersApiClient\Model\Order\User\OrderHistory;
21
use Pagantis\OrdersApiClient\Model\Order\ShoppingCart\Details;
22
use Pagantis\OrdersApiClient\Model\Order\ShoppingCart;
23
use Pagantis\OrdersApiClient\Model\Order\ShoppingCart\Details\Product;
24
use Pagantis\OrdersApiClient\Model\Order\Metadata;
25
use Pagantis\OrdersApiClient\Model\Order\Configuration\Urls;
26
use Pagantis\OrdersApiClient\Model\Order\Configuration\Channel;
27
use Pagantis\OrdersApiClient\Model\Order\Configuration;
28
use Pagantis\OrdersApiClient\Client;
29
use Pagantis\Pagantis\Model\Ui\ConfigProvider;
30
31
/**
32
 * Class Index
33
 * @package Pagantis\Pagantis\Controller\Payment
34
 */
35
class Index extends Action
36
{
37
    /** Orders tablename */
38
    const ORDERS_TABLE = 'cart_process';
39
40
    /** Concurrency tablename */
41
    const LOGS_TABLE = 'Pagantis_logs';
42
43
    /** @var Context $context */
44
    protected $context;
45
46
    /** @var QuoteRepository  $quoteRepository */
47
    protected $quoteRepository;
48
49
    /** @var OrderCollection $orderCollection */
50
    protected $orderCollection;
51
52
    /** @var Session $session */
53
    protected $session;
54
55
    /** @var mixed $config */
56
    protected $config;
57
58
    /** @var ResourceConnection $dbObject */
59
    protected $dbObject;
60
61
    /** @var ProductMetadataInterface $productMetadataInterface */
62
    protected $productMetadataInterface;
63
64
    /** @var ModuleList $moduleList */
65
    protected $moduleList;
66
67
    /** @var ExtraConfig $extraConfig */
68
    protected $extraConfig;
69
    
70
    /** @var StoreInterface $store */
71
    protected $store;
72
73
    /**
74
     * Index constructor.
75
     *
76
     * @param Context                  $context
77
     * @param QuoteRepository          $quoteRepository
78
     * @param OrderCollection          $orderCollection
79
     * @param Session                  $session
80
     * @param Config                   $config
81
     * @param ResourceConnection       $dbObject
82
     * @param ProductMetadataInterface $productMetadataInterface
83
     * @param ModuleList               $moduleList
84
     * @param ExtraConfig              $extraConfig
85
     * @param StoreInterface           $storeInterface
86
     */
87
    public function __construct(
88
        Context $context,
89
        QuoteRepository $quoteRepository,
90
        OrderCollection $orderCollection,
91
        Session $session,
92
        Config $config,
93
        ResourceConnection $dbObject,
94
        ProductMetadataInterface $productMetadataInterface,
95
        ModuleList $moduleList,
96
        ExtraConfig $extraConfig,
97
        StoreInterface $storeInterface
98
    ) {
99
        parent::__construct($context);
100
        $this->session = $session;
101
        $this->context = $context;
102
        $this->config = $config->getConfig();
103
        $this->quoteRepository = $quoteRepository;
104
        $this->orderCollection = $orderCollection;
105
        $this->dbObject = $dbObject;
106
        $this->moduleList = $moduleList;
107
        $this->productMetadataInterface = $productMetadataInterface;
108
        $this->extraConfig = $extraConfig->getExtraConfig();
0 ignored issues
show
Documentation Bug introduced by
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...
109
        $this->store = $storeInterface;
110
    }
111
112
    /**
113
     * Main function
114
     *
115
     * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void
116
     * @throws \Zend_Db_Exception
117
     */
118
    public function execute()
119
    {
120
        try {
121
            $cancelUrl = $this->_url->getUrl('checkout', ['_fragment' => 'payment']);
122
            $quote = $this->session->getQuote();
123
            /** @var Order $order */
124
            $lastOrder = $this->session->getLastRealOrder();
125
            $params = $this->getRequest()->getParams();
126
            $pgProduct = (isset($params['product']) && $params['product']===ConfigProvider::CODE4X) ? ConfigProvider::CODE4X : ConfigProvider::CODE;
127
128
            $urlToken = strtoupper(md5(uniqid(rand(), true)));
129
            $token = md5($urlToken);
130
131
            $customer = $quote->getCustomer();
132
            $shippingAddress = $quote->getShippingAddress();
133
134
            if (isset($params['email']) && $params['email']!='') {
135
                $this->session->setEmail($params['email']); //Get guest email after refresh page
136
                $customer->setEmail($params['email']);
137
                $quote->setCheckoutMethod('guest');
138
                $quote->getBillingAddress()->setEmail($params['email']);
139
            } elseif ($customer->getEmail()=='') {
140
                $customer->setEmail($this->session->getEmail());
141
                $quote->setCheckoutMethod('guest');
142
                $quote->getBillingAddress()->setEmail($this->session->getEmail());
143
            }
144
145
            /** @var Quote $currentQuote */
146
            $currentQuote = $this->quoteRepository->get($quote->getId());
147
            $currentQuote->setCustomerEmail($customer->getEmail());
148
            $this->quoteRepository->save($currentQuote);
149
150
            $userAddress =  new Address();
151
            $userAddress
152
                ->setZipCode($shippingAddress->getPostcode())
153
                ->setFullName($shippingAddress->getFirstname()." ".$shippingAddress->getLastname())
154
                ->setCountryCode($shippingAddress->getCountry())
155
                ->setCity($shippingAddress->getCity())
156
                ->setAddress($shippingAddress->getStreetFull())
157
            ;
158
159
            $tax_id = $this->getTaxId($quote->getBillingAddress());
160
            $orderShippingAddress = new Address();
161
            $orderShippingAddress
162
                ->setZipCode($shippingAddress->getPostcode())
163
                ->setFullName($shippingAddress->getFirstname()." ".$shippingAddress->getLastname())
164
                ->setCountryCode($shippingAddress->getCountry())
165
                ->setCity($shippingAddress->getCity())
166
                ->setAddress($shippingAddress->getStreetFull())
167
                ->setFixPhone($shippingAddress->getTelephone())
168
                ->setMobilePhone($shippingAddress->getTelephone())
169
                ->setTaxId($tax_id)
170
            ;
171
172
            $orderBillingAddress =  new Address();
173
            $billingAddress = $quote->getBillingAddress();
174
            $orderBillingAddress
175
                ->setZipCode($billingAddress->getPostcode())
176
                ->setFullName($billingAddress->getFirstname()." ".$shippingAddress->getLastname())
177
                ->setCountryCode($billingAddress->getCountry())
178
                ->setCity($billingAddress->getCity())
179
                ->setAddress($billingAddress->getStreetFull())
180
                ->setFixPhone($billingAddress->getTelephone())
181
                ->setMobilePhone($billingAddress->getTelephone())
182
                ->setTaxId($tax_id)
183
            ;
184
185
            $orderUser = new User();
186
            $billingAddress->setEmail($customer->getEmail());
187
            $orderUser
188
                ->setAddress($userAddress)
189
                ->setFullName($shippingAddress->getFirstname()." ".$shippingAddress->getLastname())
190
                ->setBillingAddress($orderBillingAddress)
191
                ->setEmail($customer->getEmail())
192
                ->setFixPhone($shippingAddress->getTelephone())
193
                ->setMobilePhone($shippingAddress->getTelephone())
194
                ->setShippingAddress($orderShippingAddress)
195
                ->setTaxId($tax_id)
196
            ;
197
198
            if ($customer->getDob()) {
199
                $orderUser->setDateOfBirth($customer->getDob());
200
            }
201
            if ($customer->getTaxvat()!='') {
202
                $orderUser->setDni($customer->getTaxvat());
203
                $orderBillingAddress->setDni($customer->getTaxvat());
204
                $orderShippingAddress->setDni($customer->getTaxvat());
205
                $orderUser->setNationalId($customer->getTaxvat());
206
                $orderBillingAddress->setNationalId($customer->getTaxvat());
207
                $orderShippingAddress->setNationalId($customer->getTaxvat());
208
            }
209
210
            $previousOrders = $this->getOrders($customer->getId());
211
            foreach ($previousOrders as $orderElement) {
212
                $orderHistory = new OrderHistory();
213
                $orderHistory
214
                    ->setAmount(intval(100 * $orderElement['grand_total']))
215
                    ->setDate(new \DateTime($orderElement['created_at']))
216
                ;
217
                $orderUser->addOrderHistory($orderHistory);
218
            }
219
220
            $metadataOrder = new Metadata();
221
            $metadata = $this->getMetadata();
222
            foreach ($metadata as $key => $metadatum) {
223
                $metadataOrder->addMetadata($key, $metadatum);
224
            }
225
226
            $details = new Details();
227
            $shippingCost = $quote->collectTotals()->getTotals()['shipping']->getData('value');
228
            $details->setShippingCost(intval(strval(100 * $shippingCost)));
229
            $items = $quote->getAllVisibleItems();
230
            $promotedAmount = 0;
231
            foreach ($items as $key => $item) {
232
                $product = new Product();
233
                $product
234
                    ->setAmount(intval(100 * $item->getPrice()))
235
                    ->setQuantity($item->getQty())
236
                    ->setDescription($item->getName());
237
                $details->addProduct($product);
238
239
                $promotedProduct = $this->isPromoted($item);
240
                if ($promotedProduct == 'true') {
241
                    $promotedAmount+=$product->getAmount()*$item->getQty();
242
                    $promotedMessage = 'Promoted Item: ' . $item->getName() .
243
                                       ' Price: ' . $item->getPrice() .
244
                                       ' Qty: ' . $item->getQty() .
245
                                       ' Item ID: ' . $item->getItemId();
246
                    $metadataOrder->addMetadata('promotedProduct', $promotedMessage);
247
                }
248
            }
249
250
            $orderShoppingCart = new ShoppingCart();
251
            $orderShoppingCart
252
                ->setDetails($details)
253
                ->setOrderReference($quote->getId())
254
                ->setPromotedAmount(0)
255
                ->setTotalAmount(intval(100 * $quote->getGrandTotal()))
256
            ;
257
258
            $orderConfigurationUrls = new Urls();
259
            $quoteId = $quote->getId();
260
261
            $uriRoute = 'pagantis/notify/index';
262
            if (version_compare($metadata['pg_version'], '2.3.0') >= 0) {
263
                $uriRoute = 'pagantis/notify/indexV2';
264
            }
265
266
            $okUrlUser = $this->_url->getUrl($uriRoute, ['_query' => ['quoteId'=>$quoteId,'origin'=>'redirect','product'=>$pgProduct, 'token'=>$token]]);
267
            $okUrl     = $this->_url->getUrl($uriRoute, ['_query' => ['quoteId'=>$quoteId,'origin'=>'redirect','product'=>$pgProduct, 'token'=>$token]]);
268
            $okUrlNot  = $this->_url->getUrl($uriRoute, ['_query' => ['quoteId'=>$quoteId,'origin'=>'notification','product'=>$pgProduct, 'token'=>$token]]);
269
270
            $orderConfigurationUrls
271
                ->setCancel($cancelUrl)
272
                ->setKo($okUrl)
273
                ->setAuthorizedNotificationCallback($okUrlNot)
274
                ->setOk($okUrlUser)
275
            ;
276
277
            $orderChannel = new Channel();
278
            $orderChannel
279
                ->setAssistedSale(false)
280
                ->setType(Channel::ONLINE)
281
            ;
282
283
            $haystack  = ($this->store->getLocale()!=null) ? $this->store->getLocale() : $this->getResolverCountry();
284
            $langCountry = strtolower(strstr($haystack, '_', true));
285
            $allowedCountries = unserialize($this->extraConfig['PAGANTIS_ALLOWED_COUNTRIES']);
286
287
            $purchaseCountry =
288
                in_array($langCountry, $allowedCountries) ? $langCountry :
289
                in_array(strtolower($shippingAddress->getCountry()), $allowedCountries)? $shippingAddress->getCountry():
290
                in_array(strtolower($billingAddress->getCountry()), $allowedCountries)? $billingAddress->getCountry() :
291
                null;
292
293
            $orderConfiguration = new Configuration();
294
            $orderConfiguration
295
                ->setChannel($orderChannel)
296
                ->setUrls($orderConfigurationUrls)
297
                ->setPurchaseCountry($purchaseCountry)
298
            ;
299
300
301
            $order = new Order();
302
            $order
303
                ->setConfiguration($orderConfiguration)
304
                ->setMetadata($metadataOrder)
305
                ->setShoppingCart($orderShoppingCart)
306
                ->setUser($orderUser)
307
            ;
308
309
            if ($pgProduct === ConfigProvider::CODE4X) {
310
                if ($this->config['pagantis_public_key_4x']=='' || $this->config['pagantis_private_key_4x']=='') {
311
                    throw new \Exception('Public and Secret Key not found');
312
                } else {
313
                    $orderClient = new Client(
314
                        $this->config['pagantis_public_key_4x'],
315
                        $this->config['pagantis_private_key_4x']
316
                    );
317
                }
318
            } else {
319
                if ($this->config['pagantis_public_key']=='' || $this->config['pagantis_private_key']=='') {
320
                    throw new \Exception('Public and Secret Key not found');
321
                } else {
322
                    $orderClient = new Client(
323
                        $this->config['pagantis_public_key'],
324
                        $this->config['pagantis_private_key']
325
                    );
326
                }
327
            }
328
329
            $order = $orderClient->createOrder($order);
330
            if ($order instanceof Order) {
331
                $url = $order->getActionUrls()->getForm();
332
                $result = $this->insertRow($quote->getId(), $order->getId(), $token);
333
                if (!$result) {
334
                    throw new \Exception('Unable to save pagantis-order-id');
335
                }
336
            } else {
337
                throw new \Exception('Order not created');
338
            }
339
        } catch (\Exception $exception) {
340
            $this->insertLog($exception);
341
            echo $cancelUrl;
342
            exit;
343
        }
344
345
        $displayMode = $this->extraConfig['PAGANTIS_FORM_DISPLAY_TYPE'];
346
        if ($displayMode==='0') {
347
            echo $url;
348
            exit;
349
        } else {
350
            $iframeUrl = $this->_url->getUrl(
351
                "pagantis/Payment/iframe",
352
                ['_query' => ["orderId"=>$order->getId()]]
353
            );
354
            echo $iframeUrl;
355
            exit;
356
        }
357
    }
358
359
    /**
360
     * Get the orders of a customer
361
     * @param $customerId
362
     *
363
     * @return array
364
     */
365
    private function getOrders($customerId)
366
    {
367
        $orderCollection = array();
368
        if ($customerId!='') {
369
            $this->orderCollection->addAttributeToFilter('customer_id', $customerId)
370
                            ->addAttributeToFilter(
371
                                'status',
372
                                ['in' => ['processing','pending','complete']]
373
                            )
374
                            ->load();
375
            $orderCollection = $this->orderCollection->getData();
376
        }
377
        return $orderCollection;
378
    }
379
380
    /**
381
     * @return void|\Zend_Db_Statement_Interface
382
     * @throws \Zend_Db_Exception
383
     */
384
    private function checkDbTable()
385
    {
386
        $dbConnection = $this->dbObject->getConnection();
387
        $tableName = $this->dbObject->getTableName(self::ORDERS_TABLE);
388
        if (!$dbConnection->isTableExists($tableName)) {
389
            $table = $dbConnection
390
                ->newTable($tableName)
391
                ->addColumn('id', Table::TYPE_INTEGER, 10, array('primary'=>true, 'nullable' => false))
392
                ->addColumn('order_id', Table::TYPE_TEXT, 50, array('primary'=>true, 'nullable' => true))
393
                ->addColumn('mg_order_id', Table::TYPE_TEXT, 50)
394
                ->addColumn('token', Table::TYPE_TEXT, 32);
395
            return $dbConnection->createTable($table);
396
        }
397
398
        return;
399
    }
400
401
    /**
402
     * Create relationship between quote_id & Pagantis_order_id & token
403
     * @param $quoteId
404
     * @param $pagantisOrderId
405
     * @param $token
406
     *
407
     * @return int
408
     * @throws \Zend_Db_Exception
409
     */
410
    private function insertRow($quoteId, $pagantisOrderId, $token)
411
    {
412
        $this->checkDbTable();
413
        $dbConnection = $this->dbObject->getConnection();
414
        $tableName = $this->dbObject->getTableName(self::ORDERS_TABLE);
415
        return $dbConnection->insert(
416
            $tableName,
417
            array('id'=>$quoteId,'order_id'=>$pagantisOrderId,'token'=>$token),
418
            array('order_id')
419
        );
420
    }
421
422
    /**
423
     * @return array
424
     */
425
    private function getMetadata()
426
    {
427
        $magentoVersion = $this->productMetadataInterface->getVersion();
428
        $moduleInfo = $this->moduleList->getOne('Pagantis_Pagantis');
429
        return array(
430
            'pg_module' => 'magento2x',
431
            'pg_version' => $moduleInfo['setup_version'],
432
            'ec_module' => 'magento',
433
            'ec_version' => $magentoVersion
434
        );
435
    }
436
437
    /**
438
     * Check if log table exists, otherwise create it
439
     *
440
     * @return void|\Zend_Db_Statement_Interface
441
     * @throws \Zend_Db_Exception
442
     */
443
    private function checkDbLogTable()
444
    {
445
        /** @var \Magento\Framework\DB\Adapter\AdapterInterface $dbConnection */
446
        $dbConnection = $this->dbObject->getConnection();
447
        $tableName = $this->dbObject->getTableName(self::LOGS_TABLE);
448
        if (!$dbConnection->isTableExists($tableName)) {
449
            $table = $dbConnection
450
                ->newTable($tableName)
451
                ->addColumn('id', Table::TYPE_SMALLINT, null, array('nullable'=>false, 'auto_increment'=>true, 'primary'=>true))
452
                ->addColumn('log', Table::TYPE_TEXT, null, array('nullable'=>false))
453
                ->addColumn('createdAt', Table::TYPE_TIMESTAMP, null, array('nullable'=>false, 'default'=>Table::TIMESTAMP_INIT));
454
            return $dbConnection->createTable($table);
455
        }
456
457
        return;
458
    }
459
460
    /**
461
     * @param $exceptionMessage
462
     *
463
     * @throws \Zend_Db_Exception
464
     */
465
    private function insertLog($exceptionMessage)
466
    {
467
        if ($exceptionMessage instanceof \Exception) {
468
            $this->checkDbLogTable();
469
            $logObject          = new \stdClass();
470
            $logObject->message = $exceptionMessage->getMessage();
471
            $logObject->code    = $exceptionMessage->getCode();
472
            $logObject->line    = $exceptionMessage->getLine();
473
            $logObject->file    = $exceptionMessage->getFile();
474
            $logObject->trace   = $exceptionMessage->getTraceAsString();
475
476
            /** @var \Magento\Framework\DB\Adapter\AdapterInterface $dbConnection */
477
            $dbConnection = $this->dbObject->getConnection();
478
            $tableName    = $this->dbObject->getTableName(self::LOGS_TABLE);
479
            $dbConnection->insert($tableName, array('log' => json_encode($logObject)));
480
        }
481
    }
482
483
    /**
484
     * @param $billingAdd
485
     *
486
     * @return null
487
     */
488
    private function getTaxId($billingAdd)
489
    {
490
        if (isset($billingAdd['vat_id'])) {
491
            return $billingAdd['vat_id'];
492
        } elseif (isset($billingAdd['cod_fisc'])) {
493
            return $billingAdd['cod_fisc'];
494
        } else {
495
            return null;
496
        }
497
    }
498
499
    /**
500
     * @param $item
501
     *
502
     * @return string
503
     */
504
    private function isPromoted($item)
505
    {
506
        $magentoProductId = $item->getProductId();
507
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
508
        $product = $objectManager->create('Magento\Catalog\Model\Product')->load($magentoProductId);
509
        return ($product->getData('pagantis_promoted') === '1') ? 'true' : 'false';
510
    }
511
512
    /**
513
     * @return mixed
514
     */
515
    private function getResolverCountry()
516
    {
517
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
518
        $store = $objectManager->get('Magento\Framework\Locale\Resolver');
519
520
        if (method_exists($store, 'getLocale')) {
521
            return $store->getLocale();
522
        }
523
524
        return null;
525
    }
526
}
527