FetchSubSellerIdToSplitPayment::aroundBuild()   B
last analyzed

Complexity

Conditions 10
Paths 18

Size

Total Lines 91
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 48
c 1
b 0
f 0
nc 18
nop 3
dl 0
loc 91
rs 7.2678

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\SplitExampleMagento\Plugin\Getnet\PaymentMagento\Gateway\Request;
10
11
use Getnet\PaymentMagento\Gateway\Config\Config;
12
use Getnet\PaymentMagento\Gateway\Config\ConfigCc;
13
use Getnet\PaymentMagento\Gateway\Data\Order\OrderAdapterFactory;
0 ignored issues
show
Bug introduced by
The type Getnet\PaymentMagento\Ga...der\OrderAdapterFactory 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...
14
use Getnet\PaymentMagento\Gateway\Request\SplitPaymentDataRequest;
15
use Getnet\PaymentMagento\Gateway\SubjectReader;
16
use Getnet\SplitExampleMagento\Helper\Data as SplitHelper;
17
use Magento\Framework\App\Config\ScopeConfigInterface;
18
use Magento\Framework\Serialize\Serializer\Json;
19
20
/**
21
 * Class Fetch Sub Seller Id To Split Payment - add Sub Seller in Transaction.
22
 */
23
class FetchSubSellerIdToSplitPayment
24
{
25
    /**
26
     * @var SubjectReader
27
     */
28
    protected $subjectReader;
29
30
    /**
31
     * @var OrderAdapterFactory
32
     */
33
    protected $orderAdapterFactory;
34
35
    /**
36
     * @var Config
37
     */
38
    protected $config;
39
40
    /**
41
     * @var configCc
42
     */
43
    protected $configCc;
44
45
    /**
46
     * @var SplitHelper;
47
     */
48
    protected $splitHelper;
49
    /**
50
     * @var ScopeConfigInterface
51
     */
52
    protected $scopeConfig;
53
54
    /**
55
     * @var Json
56
     */
57
    protected $json;
58
59
    /**
60
     * @param SubjectReader        $subjectReader
61
     * @param OrderAdapterFactory  $orderAdapterFactory
62
     * @param Config               $config
63
     * @param ConfigCc             $configCc
64
     * @param SplitHelper          $splitHelper
65
     * @param Json                 $json
66
     * @param ScopeConfigInterface $scopeConfig
67
     */
68
    public function __construct(
69
        SubjectReader $subjectReader,
70
        OrderAdapterFactory $orderAdapterFactory,
71
        Config $config,
72
        ConfigCc $configCc,
73
        SplitHelper $splitHelper,
74
        Json $json,
75
        ScopeConfigInterface $scopeConfig
76
    ) {
77
        $this->subjectReader = $subjectReader;
78
        $this->orderAdapterFactory = $orderAdapterFactory;
79
        $this->config = $config;
80
        $this->configCc = $configCc;
81
        $this->splitHelper = $splitHelper;
82
        $this->json = $json;
83
        $this->scopeConfig = $scopeConfig;
84
    }
85
86
    /**
87
     * Around method Build.
88
     *
89
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
90
     *
91
     * @param SplitPaymentDataRequest $subject
92
     * @param \Closure                $proceed
93
     * @param array                   $buildSubject
94
     *
95
     * @return mixin
0 ignored issues
show
Bug introduced by
The type Getnet\SplitExampleMagen...o\Gateway\Request\mixin 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...
96
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
97
     */
98
    public function aroundBuild(
99
        SplitPaymentDataRequest $subject,
0 ignored issues
show
Unused Code introduced by
The parameter $subject is not used and could be removed. ( Ignorable by Annotation )

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

99
        /** @scrutinizer ignore-unused */ SplitPaymentDataRequest $subject,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
100
        \Closure $proceed,
101
        $buildSubject
102
    ) {
103
        $result = $proceed($buildSubject);
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
104
105
        $paymentDO = $this->subjectReader->readPayment($buildSubject);
106
107
        $payment = $paymentDO->getPayment();
108
109
        $result = [];
110
111
        $marketplace = [];
112
113
        $installment = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $installment is dead and can be removed.
Loading history...
114
115
        /** @var OrderAdapterFactory $orderAdapter * */
116
        $orderAdapter = $this->orderAdapterFactory->create(
117
            ['order' => $payment->getOrder()]
118
        );
119
120
        $order = $paymentDO->getOrder();
121
122
        $dataSellers = $this->getDataForSplit($order);
123
124
        $shippingAmount = $orderAdapter->getShippingAmount();
125
126
        $payment = $paymentDO->getPayment();
127
128
        $installment = $payment->getAdditionalInformation('cc_installments') ?: 1;
129
130
        if ($payment->getMethod() === 'getnet_paymentmagento_boleto'
0 ignored issues
show
Bug introduced by
The method getMethod() does not exist on Magento\Payment\Model\InfoInterface. Did you maybe mean getMethodInstance()? ( Ignorable by Annotation )

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

130
        if ($payment->/** @scrutinizer ignore-call */ getMethod() === 'getnet_paymentmagento_boleto'

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
131
            || $payment->getMethod() === 'getnet_paymentmagento_pix'
132
            || $payment->getMethod() === 'getnet_paymentmagento_getpay'
133
        ) {
134
            $installment = 0;
135
        }
136
137
        $storeId = $order->getStoreId();
138
139
        if (!isset($dataSellers['productBySeller'])) {
140
            return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result returns the type array which is incompatible with the documented return type Getnet\SplitExampleMagen...o\Gateway\Request\mixin.
Loading history...
141
        }
142
143
        foreach ($dataSellers['productBySeller'] as $sellerId => $products) {
144
            $priceShippingBySeller = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $priceShippingBySeller is dead and can be removed.
Loading history...
145
            $productAmount = array_sum(array_column($dataSellers['pricesBySeller'][$sellerId], 'totalAmount'));
146
147
            $shippingProduct = $this->addSplitShippingInSellerData($order, $shippingAmount, $sellerId, $dataSellers);
148
149
            $products['product'][] = $shippingProduct['products'][$sellerId];
150
151
            $priceShippingBySeller = $shippingProduct['amount'][$sellerId];
152
153
            $commissionAmount = $productAmount + $priceShippingBySeller;
154
155
            if ($installment > 1) {
156
                $interestData = $this->addSplitInterestInSellerData(
157
                    $sellerId,
158
                    $dataSellers,
159
                    $installment,
160
                    $commissionAmount,
161
                    $storeId
162
                );
163
164
                if ($interestData['amount'][$sellerId] > 0) {
165
                    $products['product'][] = $interestData['products'][$sellerId];
166
167
                    $commissionAmount = $commissionAmount + $interestData['amount'][$sellerId];
168
                }
169
            }
170
171
            $result[SplitPaymentDataRequest::BLOCK_NAME_MARKETPLACE_SUBSELLER_PAYMENTS][] = [
172
                SplitPaymentDataRequest::BLOCK_NAME_SUB_SELLER_ID          => $sellerId,
173
                SplitPaymentDataRequest::BLOCK_NAME_SUBSELLER_SALES_AMOUNT => $this->config->formatPrice($commissionAmount),
174
                SplitPaymentDataRequest::BLOCK_NAME_ORDER_ITEMS            => $products['product'],
175
            ];
176
        }
177
178
        foreach ($result[SplitPaymentDataRequest::BLOCK_NAME_MARKETPLACE_SUBSELLER_PAYMENTS] as $sellers) {
179
            $seller = $sellers[SplitPaymentDataRequest::BLOCK_NAME_SUB_SELLER_ID];
180
            $marketplace[$seller] = $sellers[SplitPaymentDataRequest::BLOCK_NAME_ORDER_ITEMS];
181
        }
182
183
        $payment->setAdditionalInformation(
184
            'marketplace',
185
            $this->json->serialize($marketplace)
186
        );
187
188
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result returns the type array which is incompatible with the documented return type Getnet\SplitExampleMagen...o\Gateway\Request\mixin.
Loading history...
189
    }
190
191
    /**
192
     * Get Data for Split.
193
     *
194
     * @param OrderAdapterFactory $order
195
     *
196
     * @return array
197
     */
198
    public function getDataForSplit(
199
        $order
200
    ): array {
201
        $data = [];
202
203
        $storeId = $order->getStoreId();
204
205
        $items = $order->getItems();
206
207
        $qtyOrderedInOrder = 0;
208
209
        foreach ($items as $item) {
210
211
            // If product is configurable not apply
212
            if ($item->getParentItem()) {
213
                continue;
214
            }
215
216
            if (!$item->getProduct()->getGetnetSubSellerId()) {
217
                continue;
218
            }
219
220
            $sellerId = $item->getProduct()->getGetnetSubSellerId();
221
            $price = $item->getPrice() * $item->getQtyOrdered();
222
223
            $rulesToSplit = $this->splitHelper->getSplitCommissionsBySubSellerId($sellerId, $storeId);
224
            $commissionPercentage = $rulesToSplit['commission_percentage'] / 100;
225
            $commissionPerProduct = $price * $commissionPercentage;
226
227
            $data['productBySeller'][$sellerId]['product'][] = [
228
                SplitPaymentDataRequest::BLOCK_NAME_AMOUNT      => $this->config->formatPrice($price),
229
                SplitPaymentDataRequest::BLOCK_NAME_CURRENCY    => $order->getCurrencyCode(),
230
                SplitPaymentDataRequest::BLOCK_NAME_ID          => $item->getSku(),
231
                SplitPaymentDataRequest::BLOCK_NAME_DESCRIPTION => __(
232
                    'Product Name: %1 | Qty: %2',
233
                    $item->getName(),
234
                    $item->getQtyOrdered()
235
                ),
236
                SplitPaymentDataRequest::BLOCK_NAME_TAX_AMOUNT => $this->config->formatPrice(
237
                    $price - $commissionPerProduct
238
                ),
239
            ];
240
241
            $data['pricesBySeller'][$sellerId][] = [
242
                'totalAmount'     => $price,
243
                'qty'             => $item->getQtyOrdered(),
244
            ];
245
246
            $data['subSellerSettings'][$sellerId] = [
247
                'commission' => $rulesToSplit,
248
            ];
249
250
            $qtyOrderedInOrder = $qtyOrderedInOrder + $item->getQtyOrdered();
251
        }
252
253
        $data['qtyOrderedInOrder'] = $qtyOrderedInOrder;
254
255
        return $data;
256
    }
257
258
    /**
259
     * Add Split Shipping in Seller Data.
260
     *
261
     * @param OrderAdapterFactory $order
262
     * @param float               $shippingAmount
263
     * @param string              $sellerId
264
     * @param array               $dataSellers
265
     *
266
     * @return array
267
     */
268
    public function addSplitShippingInSellerData(
269
        $order,
270
        $shippingAmount,
271
        $sellerId,
272
        $dataSellers
273
    ): array {
274
        $shippingProduct = [];
275
276
        $qtyOrderedBySeller = array_sum(array_column($dataSellers['pricesBySeller'][$sellerId], 'qty'));
277
278
        $priceShippingBySeller = ($shippingAmount / $dataSellers['qtyOrderedInOrder']) * $qtyOrderedBySeller;
279
280
        $rule = $dataSellers['subSellerSettings'][$sellerId]['commission'];
281
282
        $shippingProduct['products'][$sellerId] = [
283
            SplitPaymentDataRequest::BLOCK_NAME_AMOUNT      => $this->config->formatPrice($priceShippingBySeller),
284
            SplitPaymentDataRequest::BLOCK_NAME_CURRENCY    => $order->getCurrencyCode(),
285
            SplitPaymentDataRequest::BLOCK_NAME_ID          => __('shipping-order-%1', $order->getOrderIncrementId()),
286
            SplitPaymentDataRequest::BLOCK_NAME_DESCRIPTION => __('Shipping for %1 products', $qtyOrderedBySeller),
287
            SplitPaymentDataRequest::BLOCK_NAME_TAX_AMOUNT  => ($rule['include_freight']) ? 0 : $this->config->formatPrice($priceShippingBySeller),
288
        ];
289
290
        $shippingProduct['amount'][$sellerId] = $priceShippingBySeller;
291
292
        return $shippingProduct;
293
    }
294
295
    /**
296
     * Add Split Interest In Seller Data.
297
     *
298
     * @param string   $sellerId
299
     * @param array    $dataSellers
300
     * @param int      $installment
301
     * @param float    $commissionAmount
302
     * @param int|null $storeId
303
     *
304
     * @return array
305
     */
306
    public function addSplitInterestInSellerData(
307
        string $sellerId,
308
        array $dataSellers,
309
        int $installment,
310
        float $commissionAmount,
311
        int $storeId = null
312
    ): array {
313
        $rule = $dataSellers['subSellerSettings'][$sellerId]['commission'];
314
315
        $amountInterest = $this->configCc->getInterestToAmount($installment, $commissionAmount, $storeId);
316
317
        $amountInterestProduct['products'][$sellerId] = [
0 ignored issues
show
Comprehensibility Best Practice introduced by
$amountInterestProduct was never initialized. Although not strictly required by PHP, it is generally a good practice to add $amountInterestProduct = array(); before regardless.
Loading history...
318
            SplitPaymentDataRequest::BLOCK_NAME_AMOUNT      => $this->config->formatPrice($amountInterest),
319
            SplitPaymentDataRequest::BLOCK_NAME_CURRENCY    => 'BRL',
320
            SplitPaymentDataRequest::BLOCK_NAME_ID          => __('interest-to-total-%1', $commissionAmount),
321
            SplitPaymentDataRequest::BLOCK_NAME_DESCRIPTION => __(
322
                'Interest for %1 installment in %2 total',
323
                $installment,
324
                $commissionAmount
325
            ),
326
            SplitPaymentDataRequest::BLOCK_NAME_TAX_AMOUNT => ($rule['include_interest']) ? 0 : $this->config->formatPrice($amountInterest),
327
        ];
328
329
        $amountInterestProduct['amount'][$sellerId] = $amountInterest;
330
331
        return $amountInterestProduct;
332
    }
333
}
334