Passed
Push — master ( b0214a...1d1e79 )
by
unknown
52s queued 14s
created

CheckoutSubmitBefore::getPaymentWhitelist()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 7
rs 10
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 - 2016 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\Observer;
28
29
use Magento\Framework\Event\ObserverInterface;
0 ignored issues
show
Bug introduced by
The type Magento\Framework\Event\ObserverInterface 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...
30
use Magento\Framework\Event\Observer;
0 ignored issues
show
Bug introduced by
The type Magento\Framework\Event\Observer 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...
31
use Magento\Framework\Exception\LocalizedException;
0 ignored issues
show
Bug introduced by
The type Magento\Framework\Exception\LocalizedException 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...
32
use Magento\Quote\Model\Quote;
0 ignored issues
show
Bug introduced by
The type Magento\Quote\Model\Quote 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\Quote\Api\Data\AddressInterface;
0 ignored issues
show
Bug introduced by
The type Magento\Quote\Api\Data\AddressInterface 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\Source\CreditratingIntegrationEvent as Event;
35
use Payone\Core\Model\Source\PersonStatus;
36
use Payone\Core\Model\Exception\FilterMethodListException;
37
38
/**
39
 * Event class to set the orderstatus to new and pending
40
 */
41
class CheckoutSubmitBefore implements ObserverInterface
42
{
43
    /**
44
     * PAYONE consumerscore request model
45
     *
46
     * @var \Payone\Core\Model\Api\Request\Consumerscore
47
     */
48
    protected $consumerscore;
49
50
    /**
51
     * Consumerscore helper
52
     *
53
     * @var \Payone\Core\Helper\Consumerscore
54
     */
55
    protected $consumerscoreHelper;
56
57
    /**
58
     * Addresscheck management object
59
     *
60
     * @var \Payone\Core\Model\Risk\Addresscheck
61
     */
62
    protected $addresscheck;
63
64
    /**
65
     * Checkout session object
66
     *
67
     * @var \Magento\Checkout\Model\Session\Proxy
0 ignored issues
show
Bug introduced by
The type Magento\Checkout\Model\Session\Proxy 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...
68
     */
69
    protected $checkoutSession;
70
71
    /**
72
     * Constructor
73
     *
74
     * @param \Payone\Core\Model\Api\Request\Consumerscore $consumerscore
75
     * @param \Payone\Core\Helper\Consumerscore            $consumerscoreHelper
76
     * @param \Payone\Core\Model\Risk\Addresscheck         $addresscheck
77
     * @param \Magento\Checkout\Model\Session\Proxy        $checkoutSession
78
     */
79
    public function __construct(
80
        \Payone\Core\Model\Api\Request\Consumerscore $consumerscore,
81
        \Payone\Core\Helper\Consumerscore $consumerscoreHelper,
82
        \Payone\Core\Model\Risk\Addresscheck $addresscheck,
83
        \Magento\Checkout\Model\Session\Proxy $checkoutSession
84
    ) {
85
        $this->consumerscore = $consumerscore;
86
        $this->consumerscoreHelper = $consumerscoreHelper;
87
        $this->addresscheck = $addresscheck;
88
        $this->checkoutSession = $checkoutSession;
89
    }
90
91
    /**
92
     * Get parameter from config
93
     *
94
     * @param  string $sParam
95
     * @param  bool   $blIsAddresscheck
96
     * @return string
97
     */
98
    public function getConfigParam($sParam, $blIsAddresscheck = false)
99
    {
100
        $sGroup = 'creditrating';
101
        if ($blIsAddresscheck === true) {
102
            $sGroup = 'address_check';
103
        }
104
        return $this->consumerscoreHelper->getConfigParam($sParam, $sGroup, 'payone_protect');
105
    }
106
107
    /**
108
     * Check if given payment methods was enabled for bonicheck in the configuration
109
     *
110
     * @param  string $sPaymentCode
111
     * @return bool
112
     */
113
    protected function isPaymentMethodEnabledForCheck($sPaymentCode)
114
    {
115
        $aPaymentTypesToCheck = $this->consumerscoreHelper->getConsumerscoreEnabledMethods();
116
        if (array_search($sPaymentCode, $aPaymentTypesToCheck) !== false) {
117
            return true;
118
        }
119
        return false;
120
    }
121
122
    /**
123
     * Determine if creditrating is needed
124
     *
125
     * @param  Quote $oQuote
126
     * @return bool
127
     */
128
    public function isCreditratingNeeded(Quote $oQuote)
129
    {
130
        if (!$this->consumerscoreHelper->isCreditratingNeeded(Event::AFTER_PAYMENT, $oQuote->getGrandTotal())) {
131
            return false;
132
        }
133
134
        if ($this->isPaymentMethodEnabledForCheck($oQuote->getPayment()->getMethodInstance()->getCode()) === false) {
135
            return false;
136
        }
137
138
        if ($oQuote->getPayment()->getMethodInstance()->getInfoInstance()->getAdditionalInformation('payone_boni_agreement') === false) { // getAdditionalInformation() returns null if field not existing
139
            return false; // agreement checkbox was not checked by the customer
140
        }
141
142
        return true;
143
    }
144
145
    /**
146
     * @param Quote $oQuote
147
     */
148
    protected function isBonicheckAgreementActiveAndNotConfirmedByCustomer($oQuote)
149
    {
150
        if (!$this->consumerscoreHelper->canShowAgreementMessage() || // check if agreement is configured
151
            !$this->isPaymentMethodEnabledForCheck($oQuote->getPayment()->getMethodInstance()->getCode()) || // check if selected payment methods is enabled for bonicheck
152
            $oQuote->getPayment()->getMethodInstance()->getInfoInstance()->getAdditionalInformation('payone_boni_agreement') !== false // check if agreement was not confirmed
153
        ) {
154
            return false;
155
        }
156
        return true;
157
    }
158
159
    /**
160
     * Determine if the payment type can be used with this score
161
     *
162
     * @param  Quote $oQuote
163
     * @param  string $sScore
164
     * @return bool
165
     */
166
    public function isPaymentApplicableForScore(Quote $oQuote, $sScore)
167
    {
168
        if ($sScore == 'G') {
169
            return true;
170
        }
171
172
        $sPaymentCode = $oQuote->getPayment()->getMethodInstance()->getCode();
173
174
        $aYellowMethods = $this->consumerscoreHelper->getAllowedMethodsForScore('Y');
175
        $aRedMethods = $this->consumerscoreHelper->getAllowedMethodsForScore('R');
176
177
        if ($sScore == 'Y' && (array_search($sPaymentCode, $aYellowMethods) !== false ||
178
                array_search($sPaymentCode, $aRedMethods) !== false)) {
179
            return true;
180
        } elseif ($sScore == 'R' && array_search($sPaymentCode, $aRedMethods) !== false) {
181
            return true;
182
        }
183
        return false;
184
    }
185
186
    /**
187
     *
188
     * @param  array $aResponse
189
     * @return bool
190
     */
191
    public function checkoutNeedsToBeStopped($aResponse)
192
    {
193
        if (!$aResponse || (isset($aResponse['status']) && $aResponse['status'] == 'ERROR'
0 ignored issues
show
Bug Best Practice introduced by
The expression $aResponse of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
194
                && $this->getConfigParam('handle_response_error') == 'stop_checkout')) {
195
            return true;
196
        }
197
        return false;
198
    }
199
200
    /**
201
     * Filter payment methods by the creditrating result if applicable
202
     *
203
     * @param  AddressInterface $oBilling
204
     * @return string
205
     * @throws LocalizedException
206
     */
207
    public function getScoreByCreditrating(AddressInterface $oBilling)
208
    {
209
        $aResponse = $this->consumerscore->sendRequest($oBilling);
210
        if ($aResponse === true) { // creditrating not executed because of a previous check
211
            $this->consumerscoreHelper->copyOldStatusToNewAddress($oBilling);
212
        }
213
214
        if ($this->checkoutNeedsToBeStopped($aResponse)) {
0 ignored issues
show
Bug introduced by
It seems like $aResponse can also be of type boolean; however, parameter $aResponse of Payone\Core\Observer\Che...ckoutNeedsToBeStopped() does only seem to accept array, 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

214
        if ($this->checkoutNeedsToBeStopped(/** @scrutinizer ignore-type */ $aResponse)) {
Loading history...
215
            $sErrorMsg = $this->getConfigParam('stop_checkout_message');
216
            if (empty($sErrorMsg)) {
217
                $sErrorMsg = 'An error occured during the credit check.';
218
            }
219
            throw new LocalizedException(__($sErrorMsg));
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

219
            throw new LocalizedException(/** @scrutinizer ignore-call */ __($sErrorMsg));
Loading history...
220
        }
221
222
        if (isset($aResponse['score'])) {
223
            $oBilling->setPayoneProtectScore($aResponse['score'])->save();
224
        }
225
226
        $sScore = $oBilling->getPayoneProtectScore();
227
        if (isset($aResponse['personstatus']) && $aResponse['personstatus'] !== PersonStatus::NONE) {
228
            $aMapping = $this->addresscheck->getPersonstatusMapping();
229
            if (array_key_exists($aResponse['personstatus'], $aMapping)) {
230
                $sScore = $this->consumerscoreHelper->getWorstScore([$sScore, $aMapping[$aResponse['personstatus']]]);
231
            }
232
        }
233
        return $sScore;
234
    }
235
236
    /**
237
     * Get error message for when the creditrating failed because the score is insufficient
238
     *
239
     * @return string
240
     */
241
    public function getInsufficientScoreMessage()
242
    {
243
        $sErrorMsg = $this->getConfigParam('insufficient_score_message');
244
        if (empty($sErrorMsg)) {
245
            $sErrorMsg = 'An error occured during the credit check.';
246
        }
247
        return $sErrorMsg;
248
    }
249
250
    /**
251
     * Returns allowed payment methods for the given score
252
     *
253
     * @param  string $sScore
254
     * @return array
255
     */
256
    protected function getPaymentWhitelist($sScore)
257
    {
258
        $aWhitelist = $this->consumerscoreHelper->getAllowedMethodsForScore('R');
259
        if ($sScore == "Y") {
260
            $aWhitelist = array_merge($aWhitelist, $this->consumerscoreHelper->getAllowedMethodsForScore('Y'));
261
        }
262
        return $aWhitelist;
263
    }
264
265
    /**
266
     * Execute certain tasks after the payment is placed and thus the order is placed
267
     *
268
     * @param  Observer $observer
269
     * @return void
270
     * @throws LocalizedException
271
     */
272
    public function execute(Observer $observer)
273
    {
274
        /** @var Quote $oQuote */
275
        $oQuote = $observer->getQuote();
276
        if (!$oQuote) {
0 ignored issues
show
introduced by
$oQuote is of type Magento\Quote\Model\Quote, thus it always evaluated to true.
Loading history...
277
            return;
278
        }
279
280
        $oBilling = $oQuote->getBillingAddress();
281
        $oShipping = $oQuote->getShippingAddress();
282
283
        $aScores = [];
284
        if ($this->getConfigParam('enabled', true)) { // is addresscheck active
285
            $aScores[] = $oBilling->getPayoneAddresscheckScore();
286
            $aScores[] = $oShipping->getPayoneAddresscheckScore();
287
        }
288
289
        if ($this->isCreditratingNeeded($oQuote) === true) {
290
            $aScores[] = $this->getScoreByCreditrating($oBilling);
291
        }
292
293
        if ($this->isBonicheckAgreementActiveAndNotConfirmedByCustomer($oQuote) === true) {
294
            $aScores[] = 'R';
295
        }
296
297
        $sScore = $this->consumerscoreHelper->getWorstScore($aScores);
298
        $blSuccess = $this->isPaymentApplicableForScore($oQuote, $sScore);
299
        if ($blSuccess === false) {
300
            $aWhitelist = $this->getPaymentWhitelist($sScore);
301
            $this->checkoutSession->setPayonePaymentWhitelist($aWhitelist);
302
            throw new FilterMethodListException(__($this->getInsufficientScoreMessage()), $aWhitelist);
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

302
            throw new FilterMethodListException(/** @scrutinizer ignore-call */ __($this->getInsufficientScoreMessage()), $aWhitelist);
Loading history...
303
        }
304
    }
305
}
306