Passed
Push — master ( 1b84e5...95ac4e )
by Florian
42s queued 12s
created

Api::isInvoiceDataNeeded()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 9
nc 6
nop 2
dl 0
loc 16
rs 8.8333
c 0
b 0
f 0
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\Helper;
28
29
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...
30
use Payone\Core\Model\Methods\PayoneMethod;
31
use Magento\Sales\Model\Order as SalesOrder;
0 ignored issues
show
Bug introduced by
The type Magento\Sales\Model\Order 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 Payone\Core\Model\Methods\Ratepay\RatepayBase;
33
34
/**
35
 * Helper class for everything that has to do with APIs
36
 *
37
 * @category  Payone
38
 * @package   Payone_Magento2_Plugin
39
 * @author    FATCHIP GmbH <[email protected]>
40
 * @copyright 2003 - 2016 Payone GmbH
41
 * @license   <http://www.gnu.org/licenses/> GNU Lesser General Public License
42
 * @link      http://www.payone.de
43
 */
44
class Api extends Base
45
{
46
    /**
47
     * PAYONE connection curl php
48
     *
49
     * @var \Payone\Core\Helper\Connection\CurlPhp
50
     */
51
    protected $connCurlPhp;
52
53
    /**
54
     * PAYONE connection curl cli
55
     *
56
     * @var \Payone\Core\Helper\Connection\CurlCli
57
     */
58
    protected $connCurlCli;
59
60
    /**
61
     * PAYONE connection fsockopen
62
     *
63
     * @var \Payone\Core\Helper\Connection\Fsockopen
64
     */
65
    protected $connFsockopen;
66
67
    /**
68
     * Checkout session object
69
     *
70
     * @var \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...
71
     */
72
    protected $checkoutSession;
73
74
    /**
75
     * Fields to copy from the request array to the order
76
     *
77
     * @var array
78
     */
79
    protected $requestToOrder = [
80
        'reference' => 'payone_refnr',
81
        'request' => 'payone_authmode',
82
        'mode' => 'payone_mode',
83
        'mandate_identification' => 'payone_mandate_id',
84
        'workorderid' => 'payone_workorder_id',
85
        'add_paydata[installment_duration]' => 'payone_installment_duration',
86
        'add_paydata[shop_id]' => 'payone_ratepay_shop_id',
87
    ];
88
89
    /**
90
     * Fields to copy from the response to the order
91
     *
92
     * @var array
93
     */
94
    protected $responseToOrder = [
95
        'txid' => 'payone_txid',
96
        'mandate_identification' => 'payone_mandate_id',
97
        'clearing_reference' => 'payone_clearing_reference',
98
        'add_paydata[clearing_reference]' => 'payone_clearing_reference',
99
        'add_paydata[workorderid]' => 'payone_workorder_id',
100
        'clearing_bankaccount' => 'payone_clearing_bankaccount',
101
        'clearing_bankcode' => 'payone_clearing_bankcode',
102
        'clearing_bankcountry' => 'payone_clearing_bankcountry',
103
        'clearing_bankname' => 'payone_clearing_bankname',
104
        'clearing_bankaccountholder' => 'payone_clearing_bankaccountholder',
105
        'clearing_bankcity' => 'payone_clearing_bankcity',
106
        'clearing_bankiban' => 'payone_clearing_bankiban',
107
        'clearing_bankbic' => 'payone_clearing_bankbic'
108
    ];
109
110
    /**
111
     * Fields to copy from the session to the order
112
     *
113
     * @var array
114
     */
115
    protected $sessionToOrder = [
116
        'payone_express_type' => 'payone_express_type',
117
    ];
118
119
    /**
120
     * Constructor
121
     *
122
     * @param \Magento\Framework\App\Helper\Context      $context
123
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
124
     * @param \Payone\Core\Helper\Shop                   $shopHelper
125
     * @param \Payone\Core\Helper\Connection\CurlPhp     $connCurlPhp
126
     * @param \Payone\Core\Helper\Connection\CurlCli     $connCurlCli
127
     * @param \Payone\Core\Helper\Connection\Fsockopen   $connFsockopen
128
     * @param \Magento\Checkout\Model\Session            $checkoutSession
129
     */
130
    public function __construct(
131
        \Magento\Framework\App\Helper\Context $context,
0 ignored issues
show
Bug introduced by
The type Magento\Framework\App\Helper\Context 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...
132
        \Magento\Store\Model\StoreManagerInterface $storeManager,
0 ignored issues
show
Bug introduced by
The type Magento\Store\Model\StoreManagerInterface 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...
133
        \Payone\Core\Helper\Shop $shopHelper,
134
        \Payone\Core\Helper\Connection\CurlPhp $connCurlPhp,
135
        \Payone\Core\Helper\Connection\CurlCli $connCurlCli,
136
        \Payone\Core\Helper\Connection\Fsockopen $connFsockopen,
137
        \Magento\Checkout\Model\Session $checkoutSession
138
    ) {
139
        parent::__construct($context, $storeManager, $shopHelper);
140
        $this->connCurlPhp = $connCurlPhp;
141
        $this->connCurlCli = $connCurlCli;
142
        $this->connFsockopen = $connFsockopen;
143
        $this->checkoutSession = $checkoutSession;
144
    }
145
146
    /**
147
     * Check which communication possibilities are existing and send the request
148
     *
149
     * @param  string $sRequestUrl
150
     * @return array
151
     */
152
    public function sendApiRequest($sRequestUrl)
153
    {
154
        $aParsedRequestUrl = parse_url($sRequestUrl);
155
        if ($aParsedRequestUrl === false) {
156
            return ["errormessage" => "Payone API request URL could not be parsed."];
157
        }
158
159
        if ($this->connCurlPhp->isApplicable()) {
160
            // php native curl exists so we gonna use it for requesting
161
            $aResponse = $this->connCurlPhp->sendCurlPhpRequest($aParsedRequestUrl);
162
        } elseif ($this->connCurlCli->isApplicable()) {
163
            // cli version of curl exists on server
164
            $aResponse = $this->connCurlCli->sendCurlCliRequest($aParsedRequestUrl);
165
        } else {
166
            // last resort => via sockets
167
            $aResponse = $this->connFsockopen->sendSocketRequest($aParsedRequestUrl);
168
        }
169
170
        $aResponse = $this->formatOutputByResponse($aResponse);
171
172
        if (!array_key_exists('status', $aResponse)) {
173
            $aResponse['status'] = 'ERROR';
174
            $aResponse['errorcode'] = '0';
175
            $aResponse['customermessage'] = 'No connection to external service provider possible (timeout)';
176
        }
177
178
        return $aResponse;
179
    }
180
181
    /**
182
     * Format response to a clean output array
183
     *
184
     * @param  array $aResponse
185
     * @return array
186
     */
187
    protected function formatOutputByResponse($aResponse)
188
    {
189
        $aOutput = [];
190
191
        if (is_array($aResponse)) { // correct response existing?
0 ignored issues
show
introduced by
The condition is_array($aResponse) is always true.
Loading history...
192
            foreach ($aResponse as $iLinenum => $sLine) { // go through line by line
193
                $iPos = strpos($sLine, "=");
194
                if ($iPos > 0) { // is a "=" as delimiter existing?
195
                    $aOutput[substr($sLine, 0, $iPos)] = trim(substr($sLine, $iPos + 1));
196
                } elseif (!empty($sLine)) { // is line not empty?
197
                    $aOutput[$iLinenum] = $sLine; // add the line unedited
198
                }
199
            }
200
        }
201
202
        return $aOutput;
203
    }
204
205
    /**
206
     * Generate the request url out of the params and die api url
207
     *
208
     * @param  array  $aParameters
209
     * @param  string $sApiUrl
210
     * @return string
211
     */
212
    public function getRequestUrl($aParameters, $sApiUrl)
213
    {
214
        $sRequestUrl = '';
215
        foreach ($aParameters as $sKey => $mValue) {
216
            if (is_array($mValue)) { // might be array
217
                foreach ($mValue as $i => $sSubValue) {
218
                    $sRequestUrl .= "&".$sKey."[".$i."]=".urlencode($sSubValue);
219
                }
220
            } else {
221
                $sRequestUrl .= "&".$sKey."=".urlencode($mValue);
222
            }
223
        }
224
        $sRequestUrl = $sApiUrl."?".substr($sRequestUrl, 1);
225
        return $sRequestUrl;
226
    }
227
228
    /**
229
     * Copy Data to order by given map
230
     *
231
     * @param SalesOrder $oOrder
232
     * @param array $aData
233
     * @param array $aMap
234
     * @return SalesOrder
235
     */
236
    protected function addDataToOrder(SalesOrder $oOrder, $aData, $aMap)
237
    {
238
        foreach ($aMap as $sFrom => $sTo) {
239
            if (isset($aData[$sFrom])) {
240
                $oOrder->setData($sTo, $aData[$sFrom]);
241
            }
242
        }
243
        return $oOrder;
244
    }
245
246
    /**
247
     * Get data from session
248
     *
249
     * @return array
250
     */
251
    protected function getSessionData()
252
    {
253
        $aData = [];
254
        foreach ($this->sessionToOrder as $from => $to) {
255
            $aData[$from] = $this->checkoutSession->getData($from, true); // get data and clear
256
        }
257
        return $aData;
258
    }
259
260
    /**
261
     * Add PAYONE information to the order object to be saved in the DB
262
     *
263
     * @param  SalesOrder  $oOrder
264
     * @param  array|false $aRequest
265
     * @param  array       $aResponse
266
     * @return void
267
     */
268
    public function addPayoneOrderData(SalesOrder $oOrder, $aRequest, $aResponse)
269
    {
270
        $this->addDataToOrder($oOrder, $aRequest, $this->requestToOrder);
0 ignored issues
show
Bug introduced by
It seems like $aRequest can also be of type false; however, parameter $aData of Payone\Core\Helper\Api::addDataToOrder() 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

270
        $this->addDataToOrder($oOrder, /** @scrutinizer ignore-type */ $aRequest, $this->requestToOrder);
Loading history...
271
        $this->addDataToOrder($oOrder, $aResponse, $this->responseToOrder);
272
        $this->addDataToOrder($oOrder, $this->getSessionData(), $this->sessionToOrder);
273
    }
274
275
    /**
276
     * Check if invoice-data has to be added to the authorization request
277
     *
278
     * @param  PayoneMethod $oPayment
279
     * @param  array|null   $aPositions
280
     * @return bool
281
     */
282
    public function isInvoiceDataNeeded(PayoneMethod $oPayment, $aPositions = null)
283
    {
284
        $sStoreCode = null;
285
        if ($oPayment->getInfoInstance()->getOrder()) {
286
            $sStoreCode = $oPayment->getInfoInstance()->getOrder()->getStore()->getCode();
287
        }
288
289
        if ($oPayment instanceof RatepayBase && is_array($aPositions) && empty($aPositions)) { // empty array means products and shipping costs were deselected
290
            return false; // RatePay demands that adjustment refunds without products and shipping costs are sent without basket info
291
        }
292
293
        $blInvoiceEnabled = (bool)$this->getConfigParam('transmit_enabled', 'invoicing', 'payone_general', $sStoreCode); // invoicing enabled?
294
        if ($blInvoiceEnabled || $oPayment->needsProductInfo()) {
295
            return true; // invoice data needed
296
        }
297
        return false; // invoice data not needed
298
    }
299
300
    /**
301
     * Return base or display currency of the order depending on the config
302
     *
303
     * @param  SalesOrder $oOrder
304
     * @return null|string
305
     */
306
    public function getCurrencyFromOrder(SalesOrder $oOrder)
307
    {
308
        $sCurrency = $oOrder->getBaseCurrencyCode();
309
        if ($this->getConfigParam('currency', 'global', 'payone_general', $oOrder->getStore()->getCode()) == 'display') {
310
            $sCurrency = $oOrder->getOrderCurrencyCode();
311
        }
312
        return $sCurrency;
313
    }
314
315
    /**
316
     * Return base or display amount of the order depending on the config
317
     *
318
     * @param  SalesOrder $oQuote
319
     * @return float
320
     */
321
    public function getOrderAmount(SalesOrder $oOrder)
322
    {
323
        $dAmount = $oOrder->getBaseGrandTotal();
324
        if ($this->getConfigParam('currency', 'global', 'payone_general', $oOrder->getStore()->getCode()) == 'display') {
325
            $dAmount = $oOrder->getGrandTotal(); // send display amount instead of base amount
326
        }
327
        return $dAmount;
328
    }
329
330
    /**
331
     * Return base or display currency of the quote depending on the config
332
     *
333
     * @param  Quote $oQuote
334
     * @return string
335
     */
336
    public function getCurrencyFromQuote(Quote $oQuote)
337
    {
338
        $sCurrency = $oQuote->getBaseCurrencyCode();
339
        if ($this->getConfigParam('currency', 'global', 'payone_general', $oQuote->getStore()->getCode()) == 'display') {
340
            $sCurrency = $oQuote->getQuoteCurrencyCode();
341
        }
342
        return $sCurrency;
343
    }
344
345
    /**
346
     * Return base or display amount of the quote depending on the config
347
     *
348
     * @param  Quote $oQuote
349
     * @return float
350
     */
351
    public function getQuoteAmount(Quote $oQuote)
352
    {
353
        $dAmount = $oQuote->getBaseGrandTotal();
354
        if ($this->getConfigParam('currency', 'global', 'payone_general', $oQuote->getStore()->getCode()) == 'display') {
355
            $dAmount = $oQuote->getGrandTotal(); // send display amount instead of base amount
356
        }
357
        return $dAmount;
358
    }
359
}
360