InstallmentPlan::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 11
dl 0
loc 24
rs 9.9
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 * PAYONE Magento 2 Connector is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU Lesser General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * PAYONE Magento 2 Connector is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public License
15
 * along with PAYONE Magento 2 Connector. If not, see <http://www.gnu.org/licenses/>.
16
 *
17
 * PHP version 5
18
 *
19
 * @category  Payone
20
 * @package   Payone_Magento2_Plugin
21
 * @author    FATCHIP GmbH <[email protected]>
22
 * @copyright 2003 - 2017 Payone GmbH
23
 * @license   <http://www.gnu.org/licenses/> GNU Lesser General Public License
24
 * @link      http://www.payone.de
25
 */
26
27
namespace Payone\Core\Service\V1;
28
29
use Payone\Core\Api\InstallmentPlanInterface;
30
use Payone\Core\Helper\Api;
31
use Payone\Core\Service\V1\Data\InstallmentPlanResponse;
32
use Payone\Core\Api\Data\InstallmentPlanResponseInterfaceFactory;
0 ignored issues
show
Bug introduced by
The type Payone\Core\Api\Data\Ins...esponseInterfaceFactory 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...
33
use Magento\Checkout\Model\Session;
0 ignored issues
show
Bug introduced by
The type Magento\Checkout\Model\Session 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...
34
use Payone\Core\Model\Api\Request\Genericpayment\Calculation;
35
use Payone\Core\Model\Api\Request\Genericpayment\PreCheck;
36
use Payone\Core\Model\Api\Request\Genericpayment\InstallmentOptions;
37
use Payone\Core\Model\Methods\Payolution\Installment;
38
use Payone\Core\Block\Payolution\InstallmentPlan as Block;
39
use Payone\Core\Block\BNPL\InstallmentPlan as BNPLBlock;
40
use Payone\Core\Helper\Ratepay;
41
use Payone\Core\Model\Methods\Ratepay\Installment as RatepayInstallment;
42
43
/**
44
 * Web API model for the PAYONE addresscheck
45
 */
46
class InstallmentPlan implements InstallmentPlanInterface
47
{
48
    /**
49
     * Factory for the response object
50
     *
51
     * @var InstallmentPlanResponseInterfaceFactory
52
     */
53
    protected $responseFactory;
54
55
    /**
56
     * Checkout session object
57
     *
58
     * @var Session
59
     */
60
    protected $checkoutSession;
61
62
    /**
63
     * Calculation Genericpayment request object
64
     *
65
     * @var Calculation
66
     */
67
    protected $calculation;
68
69
    /**
70
     * Payone Payolution Installment payment method
71
     *
72
     * @var Installment
73
     */
74
    protected $payolution;
75
76
    /**
77
     * InstallmentRate Block object
78
     *
79
     * @var Block
80
     */
81
    protected $block;
82
83
    /**
84
     * PreCheck Genericpayment request object
85
     *
86
     * @var PreCheck
87
     */
88
    protected $precheck;
89
90
    /**
91
     * @var Ratepay
92
     */
93
    protected $ratepayHelper;
94
95
    /**
96
     * @var RatepayInstallment
97
     */
98
    protected $ratepayInstallment;
99
100
    /**
101
     * @var Api
102
     */
103
    protected $apiHelper;
104
105
    /**
106
     * InstallmentOptions Genericpayment request object
107
     *
108
     * @var InstallmentOptions
109
     */
110
    protected $installmentOptions;
111
112
    /**
113
     * @var BNPLBlock
114
     */
115
    protected $bnplBlock;
116
117
    /**
118
     * Constructor.
119
     *
120
     * @param InstallmentPlanResponseInterfaceFactory $responseFactory
121
     * @param Session                                 $checkoutSession
122
     * @param PreCheck                                $precheck
123
     * @param Calculation                             $calculation
124
     * @param Installment                             $payolution
125
     * @param Block                                   $block
126
     * @param Ratepay                                 $ratepayHelper
127
     * @param RatepayInstallment                      $ratepayInstallment
128
     * @param Api                                     $apiHelper
129
     * @param InstallmentOptions                      $installmentOptions
130
     * @param BNPLBlock                               $bnplBlock
131
     */
132
    public function __construct(
133
        InstallmentPlanResponseInterfaceFactory $responseFactory,
134
        Session $checkoutSession,
135
        PreCheck $precheck,
136
        Calculation $calculation,
137
        Installment $payolution,
138
        Block $block,
139
        Ratepay $ratepayHelper,
140
        RatepayInstallment $ratepayInstallment,
141
        Api $apiHelper,
142
        InstallmentOptions $installmentOptions,
143
        BNPLBlock $bnplBlock
144
    ) {
145
        $this->responseFactory = $responseFactory;
146
        $this->checkoutSession = $checkoutSession;
147
        $this->precheck = $precheck;
148
        $this->calculation = $calculation;
149
        $this->payolution = $payolution;
150
        $this->block = $block;
151
        $this->ratepayInstallment = $ratepayInstallment;
152
        $this->ratepayHelper = $ratepayHelper;
153
        $this->apiHelper = $apiHelper;
154
        $this->installmentOptions = $installmentOptions;
155
        $this->bnplBlock = $bnplBlock;
156
    }
157
158
    /**
159
     * Write installment draft download link array to session
160
     *
161
     * @param  $aInstallmentData
162
     * @return void
163
     */
164
    protected function setInstallmentDraftDownloadLinks($aInstallmentData)
165
    {
166
        $aDownloadLinks = array();
167
        foreach ($aInstallmentData as $aInstallment) {
168
            $aDownloadLinks[$aInstallment['duration']] = $aInstallment['standardcreditinformationurl'];
169
        }
170
        $this->checkoutSession->setInstallmentDraftLinks($aDownloadLinks);
171
    }
172
173
    /**
174
     * Check responses for errors and add them to the response object if needed
175
     *
176
     * @param  InstallmentPlanResponse $oResponse
177
     * @param  array                   $aResponsePreCheck
178
     * @param  array                   $aResponseCalculation
179
     * @return InstallmentPlanResponse
180
     */
181
    protected function checkForErrors($oResponse, $aResponsePreCheck, $aResponseCalculation)
182
    {
183
        $sErrorMessage = false;
184
        if (isset($aResponsePreCheck['status']) && $aResponsePreCheck['status'] == 'ERROR') {
185
            $sErrorMessage = __($aResponsePreCheck['errorcode'] . ' - ' . $aResponsePreCheck['customermessage']);
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

185
            $sErrorMessage = /** @scrutinizer ignore-call */ __($aResponsePreCheck['errorcode'] . ' - ' . $aResponsePreCheck['customermessage']);
Loading history...
186
        } elseif (isset($aResponseCalculation['status']) && $aResponseCalculation['status'] == 'ERROR') {
187
            $sErrorMessage = __($aResponseCalculation['errorcode'] . ' - ' . $aResponseCalculation['customermessage']);
188
        } elseif (!$aResponsePreCheck || (isset($aResponsePreCheck['status']) && $aResponsePreCheck['status'] == 'OK' && !$aResponseCalculation)) {
189
            $sErrorMessage = __('An unknown error occurred');
190
        }
191
        if ($sErrorMessage !== false) {
192
            $oResponse->setData('errormessage', $sErrorMessage);
193
        }
194
        return $oResponse;
195
    }
196
197
    /**
198
     * PAYONE addresscheck
199
     * The full class-paths must be given here otherwise the Magento 2 WebApi
200
     * cant handle this with its fake type system!
201
     *
202
     * @param  string $cartId
203
     * @param  string $birthday
204
     * @param  string $email
205
     * @return \Payone\Core\Service\V1\Data\InstallmentPlanResponse
206
     */
207
    public function getInstallmentPlan($cartId, $birthday, $email = false)
208
    {
209
        $oResponse = $this->responseFactory->create();
210
        $oResponse->setData('success', false); // set success to false as default, set to true later if true
211
212
        $oQuote = $this->checkoutSession->getQuote();
213
        $aResponsePreCheck = $this->precheck->sendRequest($this->payolution, $oQuote, false, $birthday, $email);
214
        $aResponseCalculation = false;
215
        if (isset($aResponsePreCheck['status']) && $aResponsePreCheck['status'] == 'OK') {
216
            $aResponseCalculation = $this->calculation->sendRequest($this->payolution, $oQuote);
217
            $aInstallmentData = $this->parseResponse($aResponseCalculation);
218
            if (isset($aResponseCalculation['status']) && $aResponseCalculation['status'] == 'OK' && $aInstallmentData !== false) {
219
                $oResponse->setData('success', true); // set success to false as default, set to true later if true
220
                $this->setInstallmentDraftDownloadLinks($aInstallmentData);
221
                $this->checkoutSession->setInstallmentWorkorderId($aResponseCalculation['workorderid']);
222
223
                $this->block->setInstallmentData($aInstallmentData);
224
                $this->block->setCode($this->payolution->getCode());
225
226
                $oResponse->setData('installmentPlanHtml', $this->block->toHtml());
227
            }
228
        }
229
        $oResponse = $this->checkForErrors($oResponse, $aResponsePreCheck, $aResponseCalculation);
230
        return $oResponse;
231
    }
232
233
    /**
234
     * PAYONE addresscheck
235
     * The full class-paths must be given here otherwise the Magento 2 WebApi
236
     * cant handle this with its fake type system!
237
     *
238
     * @param  string $cartId
239
     * @param  string $calcType
240
     * @param  int $calcValue
241
     * @return \Payone\Core\Service\V1\Data\InstallmentPlanResponse
242
     */
243
    public function getInstallmentPlanRatepay($cartId, $calcType, $calcValue)
244
    {
245
        $oResponse = $this->responseFactory->create();
246
        $oResponse->setData('success', false); // set success to false as default, set to true later if true
247
248
        $oQuote = $this->checkoutSession->getQuote();
249
250
        $sRatepayShopId = $this->ratepayHelper->getRatepayShopId($this->ratepayInstallment->getCode(), $oQuote->getBillingAddress()->getCountryId(), $this->apiHelper->getCurrencyFromQuote($oQuote), $this->apiHelper->getQuoteAmount($oQuote));
251
252
        $aResponseCalculation = $this->calculation->sendRequestRatepay($this->ratepayInstallment, $oQuote, $sRatepayShopId, $calcType, $calcValue);
253
        if ($aResponseCalculation['status'] == "OK") {
254
            unset($aResponseCalculation['status']);
255
            unset($aResponseCalculation['workorderid']);
256
            $aInstallmentPlan = [];
257
            foreach ($aResponseCalculation as $sKey => $sValue) {
258
                $sKey = str_replace("add_paydata", "", $sKey);
259
                $sKey = str_replace(["[", "]"], "", $sKey);
260
                $sKey = str_replace("-", "_", $sKey);
261
                $aInstallmentPlan[$sKey] = $sValue;
262
            }
263
            $oResponse->setData('installmentPlan', json_encode($aInstallmentPlan));
264
            $oResponse->setData('success', true);
265
        }
266
        return $oResponse;
267
    }
268
269
    /**
270
     * Extract number from given string
271
     *
272
     * @param  string $sString
273
     * @return string|false
274
     */
275
    protected function getNumberFromString($sString)
276
    {
277
        preg_match('/^[^0-9]*_([0-9])$/m', $sString, $matches);
278
279
        if (count($matches) == 2) {
280
            return $matches[1];
281
        }
282
        return false;
283
    }
284
285
    protected function formatInstallmentOptions($aResponse)
286
    {
287
        unset($aResponse['status']);
288
        unset($aResponse['workorderid']);
289
290
        $aInstallmentOptions = ['runtimes' => []];
291
292
        foreach ($aResponse as $sKey => $sValue) {
293
            $sKey = str_replace("add_paydata", "", $sKey);
294
            $sKey = str_replace(["[", "]"], "", $sKey);
295
            $sKey = str_replace("-", "_", $sKey);
296
297
            $iIndex = $this->getNumberFromString($sKey);
298
            if ($iIndex !== false) {
299
                $sKey = str_replace("_".$iIndex, "", $sKey);
300
                if (!isset($aInstallmentOptions['runtimes'][$iIndex])) {
301
                    $aInstallmentOptions['runtimes'][$iIndex] = [];
302
                }
303
                $aInstallmentOptions['runtimes'][$iIndex][$sKey] = $sValue;
304
            } else {
305
                $aInstallmentOptions[$sKey] = $sValue;
306
            }
307
        }
308
        return $aInstallmentOptions;
309
    }
310
311
    /**
312
     * PAYONE BNPL installment plan getter
313
     * The full class-paths must be given here otherwise the Magento 2 WebApi
314
     * cant handle this with its fake type system!
315
     *
316
     * @param  string $cartId
317
     * @param  string $paymentCode
318
     * @return \Payone\Core\Service\V1\Data\InstallmentPlanResponse
319
     */
320
    public function getInstallmentPlanBNPL($cartId, $paymentCode)
321
    {
322
        $oResponse = $this->responseFactory->create();
323
        $oResponse->setData('success', false); // set success to false as default, set to true later if true
324
325
        $oQuote = $this->checkoutSession->getQuote();
326
327
        $aResponseCalculation = $this->installmentOptions->sendRequest($oQuote, $paymentCode);
328
329
        if ($aResponseCalculation['status'] == "OK") {
330
            $this->checkoutSession->setInstallmentWorkorderId($aResponseCalculation['workorderid']);
331
            $aInstallmentPlan = $this->formatInstallmentOptions($aResponseCalculation);
332
333
            $this->bnplBlock->setInstallmentData($aInstallmentPlan);
334
            $this->bnplBlock->setCode($paymentCode);
335
336
            $oResponse->setData('installmentPlanHtml', $this->bnplBlock->toHtml());
337
            $oResponse->setData('success', true);
338
        }
339
        return $oResponse;
340
    }
341
342
    /**
343
     * Collects allowed runtimes afterwards
344
     * Needed for guest checkout since the billing country is not known when checkout is loaded
345
     *
346
     * @param  string $cartId
347
     * @return \Payone\Core\Service\V1\Data\InstallmentPlanResponse
348
     */
349
    public function getAllowedMonths($cartId)
350
    {
351
        $oResponse = $this->responseFactory->create();
352
        $oResponse->setData('success', false); // set success to false as default, set to true later if true
353
354
        $oQuote = $this->checkoutSession->getQuote();
355
356
        $aAllowedMonths = $this->ratepayInstallment->getAllowedMonths($oQuote);
357
358
        $oResponse->setData('allowedMonths', json_encode($aAllowedMonths));
359
        $oResponse->setData('success', true);
360
361
        return $oResponse;
362
    }
363
364
    /**
365
     * @param array $aResponse
366
     * @return array
367
     */
368
    public function getPayDataArray($aResponse)
369
    {
370
        $aPayData = array();
371
        foreach($aResponse as $sKey => $sValue) {
372
            $sCorrectedKey = str_ireplace('add_paydata[', '', $sKey);
373
            $sCorrectedKey = rtrim($sCorrectedKey, ']');
0 ignored issues
show
Bug introduced by
It seems like $sCorrectedKey can also be of type array; however, parameter $string of rtrim() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

373
            $sCorrectedKey = rtrim(/** @scrutinizer ignore-type */ $sCorrectedKey, ']');
Loading history...
374
            $sCorrectedKey = strtolower($sCorrectedKey);
375
            $sCorrectedKey = str_replace('-', '_', $sCorrectedKey);
376
            $aPayData[$sCorrectedKey] = $sValue;
377
        }
378
379
        ksort($aPayData);
380
        return $aPayData;
381
    }
382
383
    /**
384
     * Parse the response array into a readable array
385
     *
386
     * @param $aResponse
387
     * @return array|false
388
     */
389
    protected function parseResponse($aResponse)
390
    {
391
        $aInstallmentData = array();
392
393
        $aPayData = $this->getPayDataArray($aResponse);
394
        foreach ($aPayData as $sKey => $sValue) {
395
            $aSplit = explode('_', $sKey);
396
            for($i = count($aSplit); $i > 0; $i--) {
397
                if($i == count($aSplit)) {
398
                    $aTmp = array($aSplit[$i-1] => $sValue);
399
                } else {
400
                    $aTmp = array($aSplit[$i-1] => $aTmp);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $aTmp does not seem to be defined for all execution paths leading up to this point.
Loading history...
401
                }
402
            }
403
404
            $aInstallmentData = array_replace_recursive($aInstallmentData, $aTmp);
405
        }
406
407
        if(isset($aInstallmentData['paymentdetails']) && count($aInstallmentData['paymentdetails']) > 0) {
408
            return $aInstallmentData['paymentdetails'];
409
        }
410
411
        return false;
412
    }
413
}
414