PaymentRelease::createPaymentRelease()   B
last analyzed

Complexity

Conditions 10
Paths 20

Size

Total Lines 81
Code Lines 50

Duplication

Lines 0
Ratio 0 %

Importance

Changes 10
Bugs 1 Features 0
Metric Value
cc 10
eloc 50
c 10
b 1
f 0
nc 20
nop 3
dl 0
loc 81
rs 7.2242

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Copyright © Getnet. All rights reserved.
4
 *
5
 * @author    Bruno Elisei <[email protected]>
6
 * See LICENSE for license details.
7
 */
8
9
namespace Getnet\PaymentMagento\Model\Console\Command\Marketplace;
10
11
use Exception;
12
use Getnet\PaymentMagento\Gateway\Config\Config as GetnetConfig;
13
use Getnet\PaymentMagento\Model\Console\Command\AbstractModel;
14
use Magento\Framework\App\State;
15
use Magento\Framework\Exception\LocalizedException;
16
use Magento\Framework\HTTP\ZendClient;
17
use Magento\Framework\HTTP\ZendClientFactory;
0 ignored issues
show
Bug introduced by
The type Magento\Framework\HTTP\ZendClientFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use Magento\Framework\Phrase;
19
use Magento\Framework\Serialize\Serializer\Json;
20
use Magento\Payment\Model\Method\Logger;
21
use Magento\Sales\Api\Data\OrderInterfaceFactory;
0 ignored issues
show
Bug introduced by
The type Magento\Sales\Api\Data\OrderInterfaceFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use Magento\Sales\Api\Data\TransactionSearchResultInterfaceFactory as TransactionSearch;
0 ignored issues
show
Bug introduced by
The type Magento\Sales\Api\Data\T...hResultInterfaceFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use Magento\Sales\Model\Service\OrderService;
24
25
/**
26
 * Payment Release - release the payment amount to the sub seller.
27
 *
28
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
29
 */
30
class PaymentRelease extends AbstractModel
31
{
32
    public const RELEASE_PAYMENT_DATE = 'release_payment_date';
33
    public const SUBSELLER_ID = 'subseller_id';
34
    public const ORDER_ITEM_RELEASE = 'order_item_release';
35
    public const ORDER_ITEM_RELEASE_ID = 'id';
36
    public const ORDER_ITEM_RELEASE_AMOUNT = 'amount';
37
38
    /**
39
     * @var State
40
     */
41
    protected $state;
42
43
    /**
44
     * @var Logger
45
     */
46
    protected $logger;
47
48
    /**
49
     * @var GetnetConfig
50
     */
51
    protected $getnetConfig;
52
53
    /**
54
     * @var TransactionSearch
55
     */
56
    protected $transactionSearch;
57
58
    /**
59
     * @var Json
60
     */
61
    protected $json;
62
63
    /**
64
     * @var ZendClientFactory
65
     */
66
    protected $httpClientFactory;
67
68
    /**
69
     * @var OrderInterfaceFactory
70
     */
71
    protected $orderFactory;
72
73
    /**
74
     * @var OrderService
75
     */
76
    protected $orderService;
77
78
    /**
79
     * @param State                 $state
80
     * @param Logger                $logger
81
     * @param GetnetConfig          $getnetConfig
82
     * @param TransactionSearch     $transactionSearch
83
     * @param Json                  $json
84
     * @param ZendClientFactory     $httpClientFactory
85
     * @param OrderInterfaceFactory $orderFactory
86
     * @param OrderService          $orderService
87
     */
88
    public function __construct(
89
        State $state,
90
        Logger $logger,
91
        GetnetConfig $getnetConfig,
92
        TransactionSearch $transactionSearch,
93
        Json $json,
94
        ZendClientFactory $httpClientFactory,
95
        OrderInterfaceFactory $orderFactory,
96
        OrderService $orderService
97
    ) {
98
        parent::__construct(
99
            $logger
100
        );
101
        $this->state = $state;
102
        $this->getnetConfig = $getnetConfig;
103
        $this->transactionSearch = $transactionSearch;
104
        $this->json = $json;
105
        $this->httpClientFactory = $httpClientFactory;
106
        $this->orderFactory = $orderFactory;
107
        $this->orderService = $orderService;
108
    }
109
110
    /**
111
     * Command Preference.
112
     *
113
     * @param int         $orderId
114
     * @param string      $date
115
     * @param string|null $subSellerId
116
     *
117
     * @return void
118
     */
119
    public function create(
120
        int $orderId,
121
        string $date,
122
        string $subSellerId = null
123
    ) {
124
        $this->writeln('Init Payment Release');
125
        $this->createPaymentRelease($orderId, $date, $subSellerId);
126
        $this->writeln(__('Finished'));
127
    }
128
129
    /**
130
     * Create Sub Seller.
131
     *
132
     * @param int         $orderId
133
     * @param string      $date
134
     * @param string|null $subSellerId
135
     *
136
     * @return void
137
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
138
     * @SuppressWarnings(PHPMD.NPathComplexity)
139
     */
140
    public function createPaymentRelease(
141
        int $orderId,
142
        string $date,
143
        string $subSellerId = null
144
    ) {
145
        try {
146
            $transaction = $this->transactionSearch->create()->addOrderIdFilter($orderId)->getFirstItem();
147
            $transactionId = $transaction->getTxnId();
148
        } catch (LocalizedException $exc) {
149
            $this->writeln('<error>'.$exc->getMessage().'</error>');
150
151
            return;
152
        }
153
154
        if (!$transactionId) {
155
            $messageInfo = __(
156
                'Unable to get order transaction'
157
            );
158
            $this->writeln(sprintf('<error>%s</error>', $messageInfo));
159
160
            return;
161
        }
162
163
        $sellersItems = $transaction->getOrder()->getPayment()->getAdditionalInformation('marketplace');
164
165
        if (!$sellersItems) {
166
            $messageInfo = __(
167
                'Unable to get order transaction marketplace'
168
            );
169
            $this->writeln(sprintf('<error>%s</error>', $messageInfo));
170
171
            return;
172
        }
173
174
        $sellersItems = $this->json->unserialize($sellersItems);
175
176
        foreach ($sellersItems as $sellerId => $items) {
177
            $subSellersInPayment[] = $sellerId;
178
            foreach ($items as $item) {
179
                if ((int) $item['amount']) {
180
                    $orderItems[$sellerId][] = [
181
                        'id'     => $item['id'],
182
                        'amount' => $item['amount'],
183
                    ];
184
                }
185
            }
186
        }
187
188
        if ($subSellerId) {
189
            $data = [
190
                self::RELEASE_PAYMENT_DATE => $date,
191
                self::SUBSELLER_ID         => $subSellerId,
192
                self::ORDER_ITEM_RELEASE   => $orderItems[$subSellerId],
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $orderItems does not seem to be defined for all execution paths leading up to this point.
Loading history...
193
            ];
194
            $messageInfo = __(
195
                'Releasing payment from seller %1, for date of %2',
196
                $subSellerId,
197
                $date
198
            );
199
            $response = $this->sendData($transactionId, $data);
200
            $this->setMessages($response, $messageInfo, $orderId);
201
202
            return $response;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $response returns the type Magento\Framework\DataObject which is incompatible with the documented return type void.
Loading history...
203
        }
204
205
        if (!$subSellerId) {
206
            foreach ($subSellersInPayment as $subSellerId) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $subSellersInPayment seems to be defined by a foreach iteration on line 176. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
207
                $data = [
208
                    self::RELEASE_PAYMENT_DATE => $date,
209
                    self::SUBSELLER_ID         => $subSellerId,
210
                    self::ORDER_ITEM_RELEASE   => $orderItems[$subSellerId],
211
                ];
212
                $messageInfo = __(
213
                    'Releasing payment from seller %1, for date of %2',
214
                    $subSellerId,
215
                    $date
216
                );
217
                $response = $this->sendData($transactionId, $data);
218
                $this->setMessages($response, $messageInfo, $orderId);
219
220
                return $response;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $response returns the type Magento\Framework\DataObject which is incompatible with the documented return type void.
Loading history...
221
            }
222
        }
223
    }
224
225
    /**
226
     * Send Data.
227
     *
228
     * @param string $transactionId
229
     * @param string $data
230
     *
231
     * @return \Magento\Framework\DataObject
232
     */
233
    public function sendData(
234
        string $transactionId,
235
        array $data
236
    ): \Magento\Framework\DataObject {
237
        $uri = $this->getnetConfig->getApiUrl();
238
        $bearer = $this->getnetConfig->getMerchantGatewayOauth(0);
239
        $client = $this->httpClientFactory->create();
240
        $uri = $uri.'v1/marketplace/payments/'.$transactionId.'/release';
241
        $client->setUri($uri);
242
        $client->setHeaders('Authorization', 'Bearer '.$bearer);
243
        $client->setConfig(['maxredirects' => 0, 'timeout' => 40]);
244
        $client->setRawData($this->json->serialize($data), 'application/json');
245
        $client->setMethod(ZendClient::POST);
246
        $getnetData = new \Magento\Framework\DataObject();
247
248
        try {
249
            $result = $client->request()->getBody();
250
            $response = $this->json->unserialize($result);
251
252
            $this->logger->debug([
253
                'url'      => $uri,
254
                'send'     => $this->json->serialize($data),
255
                'response' => $this->json->serialize($response),
256
            ]);
257
258
            $getnetData->setData($response);
259
        } catch (Exception $e) {
260
            $this->logger->debug([
261
                'error' => $e->getMessage(),
262
            ]);
263
264
            $getnetData->getMessage('Connection Error');
265
            $getnetData->setDetails(
266
                [
267
                    'error_code'  => 401,
268
                    'description' => $e->getMessage(),
269
                ]
270
            );
271
        }
272
273
        return $getnetData;
274
    }
275
276
    /**
277
     * Set Messages.
278
     *
279
     * @param \Magento\Framework\DataObject $response
280
     * @param Phrase                        $messageInfo
281
     * @param int                           $orderId
282
     *
283
     * @return void;
284
     */
285
    public function setMessages(
286
        \Magento\Framework\DataObject $response,
287
        Phrase $messageInfo,
288
        int $orderId
289
    ) {
290
        $this->writeln(sprintf('<info>%s</info>', $messageInfo));
291
        if ($response->getSuccess()) {
292
            $messageDone = __(
293
                'Payment release requested successfully'
294
            );
295
            $this->writeln(sprintf('<info>%s</info>', $messageDone));
296
            $this->addReleaseComment($messageInfo, $orderId);
297
298
            return $messageDone;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $messageDone returns the type Magento\Framework\Phrase which is incompatible with the documented return type void.
Loading history...
299
        }
300
301
        if ($response->getMessage()) {
302
            $this->writeln(sprintf('<error>%s</error>', $response->getMessage()));
303
            foreach ($response->getDetails() as $message) {
304
                $messageInfo = __(
305
                    'Error: %1, description: %2',
306
                    $message['error_code'],
307
                    $message['description']
308
                );
309
                $this->writeln(sprintf('<error>%s</error>', $messageInfo));
310
            }
311
312
            return $messageInfo;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $messageInfo returns the type Magento\Framework\Phrase which is incompatible with the documented return type void.
Loading history...
313
        }
314
    }
315
316
    /**
317
     * Add Release Comment.
318
     *
319
     * @param Phrase $messageInfo
320
     * @param int    $orderId
321
     *
322
     * @return void
323
     */
324
    public function addReleaseComment(
325
        Phrase $messageInfo,
326
        int $orderId
327
    ) {
328
        /** @var OrderInterfaceFactory $order */
329
        $order = $this->orderFactory->create()->load($orderId);
330
        $history = $order->addStatusHistoryComment($messageInfo, $order->getStatus());
331
        $history->setIsVisibleOnFront(false);
332
        $history->setIsCustomerNotified(false);
333
        $this->orderService->addComment($orderId, $history);
334
    }
335
}
336