Debit::getInvoiceList()   C
last analyzed

Complexity

Conditions 13
Paths 108

Size

Total Lines 33
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 13
eloc 21
c 1
b 0
f 0
nc 108
nop 2
dl 0
loc 33
rs 6.55

How to fix   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
/**
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\Model\Api\Request;
28
29
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...
30
use Magento\Sales\Model\Order;
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...
31
use Magento\Sales\Model\Order\Creditmemo;
0 ignored issues
show
Bug introduced by
The type Magento\Sales\Model\Order\Creditmemo 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\BNPL\BNPLBase;
33
use Payone\Core\Model\Methods\PayoneMethod;
34
use Magento\Payment\Model\InfoInterface;
0 ignored issues
show
Bug introduced by
The type Magento\Payment\Model\InfoInterface 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...
35
36
/**
37
 * Class for the PAYONE Server API request "debit"
38
 */
39
class Debit extends Base
40
{
41
    /**
42
     * @var \Payone\Core\Model\Api\Invoice $invoiceGenerator
43
     */
44
    protected $invoiceGenerator;
45
46
    /**
47
     * PAYONE database helper
48
     *
49
     * @var \Payone\Core\Helper\Database
50
     */
51
    protected $databaseHelper;
52
53
    /**
54
     * Constructor
55
     *
56
     * @param \Payone\Core\Helper\Shop                $shopHelper
57
     * @param \Payone\Core\Helper\Environment         $environmentHelper
58
     * @param \Payone\Core\Helper\Api                 $apiHelper
59
     * @param \Payone\Core\Helper\Toolkit             $toolkitHelper
60
     * @param \Payone\Core\Model\ResourceModel\ApiLog $apiLog
61
     * @param \Payone\Core\Model\Api\Invoice          $invoiceGenerator
62
     * @param \Payone\Core\Helper\Database            $databaseHelper
63
     */
64
    public function __construct(
65
        \Payone\Core\Helper\Shop $shopHelper,
66
        \Payone\Core\Helper\Environment $environmentHelper,
67
        \Payone\Core\Helper\Api $apiHelper,
68
        \Payone\Core\Helper\Toolkit $toolkitHelper,
69
        \Payone\Core\Model\ResourceModel\ApiLog $apiLog,
70
        \Payone\Core\Model\Api\Invoice $invoiceGenerator,
71
        \Payone\Core\Helper\Database $databaseHelper
72
    ) {
73
        parent::__construct($shopHelper, $environmentHelper, $apiHelper, $toolkitHelper, $apiLog);
74
        $this->invoiceGenerator = $invoiceGenerator;
75
        $this->databaseHelper = $databaseHelper;
76
    }
77
78
    /**
79
     * Generate position list for invoice data transmission
80
     *
81
     * @param  Order      $oOrder
82
     * @param  Creditmemo $oCreditmemo
83
     * @return array|false
84
     */
85
    protected function getInvoiceList(Order $oOrder, Creditmemo $oCreditmemo)
86
    {
87
        $aPositions = [];
88
        $blFull = true;
89
        foreach ($oOrder->getAllItems() as $oItem) {
90
            $blFound = false;
91
            foreach ($oCreditmemo->getAllItems() as $oCreditMemoItem) {
92
                if ($oCreditMemoItem->getOrderItemId() == $oItem->getItemId() && $oCreditMemoItem->getQty() > 0) {
93
                    $blFound = true;
94
                    $aPositions[$oItem->getProductId().$oItem->getSku()] = $oCreditMemoItem->getQty();
95
                    if ($oCreditMemoItem->getQty() != $oItem->getQtyOrdered()) {
96
                        $blFull = false;
97
                    }
98
                }
99
            }
100
            if ($blFound === false) {
101
                $blFull = false;
102
            }
103
        }
104
105
        if ($oCreditmemo->getBaseShippingInclTax() != 0) {
106
            $aPositions['delcost'] = $oCreditmemo->getBaseShippingInclTax();
107
        }
108
        if ($blFull !== true && $oCreditmemo->getBaseDiscountAmount() != 0) {
109
            $aPositions['discount'] = $oCreditmemo->getBaseDiscountAmount();
110
            if ($this->shopHelper->getConfigParam('currency', 'global', 'payone_general', $this->storeCode) == 'display') {
111
                $aPositions['discount'] = $oCreditmemo->getDiscountAmount();
112
            }
113
        }
114
        if ($blFull === true && $oCreditmemo->getBaseShippingInclTax() == $oOrder->getBaseShippingInclTax()) {
115
            $aPositions = false; // false = full debit
116
        }
117
        return $aPositions;
118
    }
119
120
    /**
121
     * Send request "debit" to PAYONE server API
122
     *
123
     * @param  PayoneMethod  $oPayment
124
     * @param  InfoInterface $oPaymentInfo
125
     * @param  float         $dAmount
126
     * @return array
127
     */
128
    public function sendRequest(PayoneMethod $oPayment, InfoInterface $oPaymentInfo, $dAmount)
129
    {
130
        $oOrder = $oPaymentInfo->getOrder();
131
132
        $this->setStoreCode($oOrder->getStore()->getCode());
133
134
        $oCreditmemo = $oPaymentInfo->getCreditmemo();
135
        $aPositions = $this->getInvoiceList($oOrder, $oCreditmemo);
136
137
        if ($this->shopHelper->getConfigParam('currency', 'global', 'payone_general', $this->storeCode) == 'display') {
138
            $dAmount = $oCreditmemo->getGrandTotal(); // send display amount instead of base amount
139
        }
140
141
        $iTxid = $oPaymentInfo->getParentTransactionId();
142
        if (strpos($iTxid, '-') !== false) {
143
            $iTxid = substr($iTxid, 0, strpos($iTxid, '-')); // clean the txid from the magento-suffixes
144
        }
145
146
        $this->setOrderId($oOrder->getRealOrderId());
147
148
        $this->addParameter('request', 'debit'); // Request method
149
        $this->addParameter('mode', $oPayment->getOperationMode()); // PayOne Portal Operation Mode (live or test)
150
        $this->addParameter('txid', $iTxid); // PayOne Transaction ID
151
        $this->addParameter('sequencenumber', $this->databaseHelper->getSequenceNumber($iTxid));
152
153
        // Total order sum in smallest currency unit
154
        $this->addParameter('amount', number_format((-1 * $dAmount), 2, '.', '') * 100); // add price to request
155
        $this->addParameter('currency', $this->apiHelper->getCurrencyFromOrder($oOrder)); // add currency to request
156
157
        $this->addParameter('transactiontype', 'GT');
158
159
        if ($this->apiHelper->isInvoiceDataNeeded($oPayment, $aPositions)) {
0 ignored issues
show
Bug introduced by
It seems like $aPositions can also be of type false; however, parameter $aPositions of Payone\Core\Helper\Api::isInvoiceDataNeeded() does only seem to accept array|null, 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

159
        if ($this->apiHelper->isInvoiceDataNeeded($oPayment, /** @scrutinizer ignore-type */ $aPositions)) {
Loading history...
160
            if ($oPayment instanceof BNPLBase) { // only for BNPL methods it is needed that amounts are transfered with negative amount
161
                $this->invoiceGenerator->setNegatePrice(true);
162
            }
163
            $this->invoiceGenerator->addProductInfo($this, $oOrder, $aPositions, true); // add invoice parameters
0 ignored issues
show
Bug introduced by
It seems like $aPositions can also be of type false; however, parameter $aPositions of Payone\Core\Model\Api\Invoice::addProductInfo() 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

163
            $this->invoiceGenerator->addProductInfo($this, $oOrder, /** @scrutinizer ignore-type */ $aPositions, true); // add invoice parameters
Loading history...
164
        }
165
166
        $sRefundAppendix = $this->getRefundAppendix($oOrder, $oPayment);
167
        if (!empty($sRefundAppendix)) {
168
            $this->addParameter('invoiceappendix', $sRefundAppendix);
169
        }
170
171
        $sIban = false;
172
        $sBic = false;
173
        if (!empty($oOrder->getPayoneRefundIban()) && !empty($oOrder->getPayoneRefundBic())) {
174
            $sIban = $oOrder->getPayoneRefundIban();
175
            $sBic = $oOrder->getPayoneRefundBic();
176
        } elseif ($oCreditmemo->getPayoneIban() && $oCreditmemo->getPayoneBic()) {
177
            $sIban = $oCreditmemo->getPayoneIban();
178
            $sBic = $oCreditmemo->getPayoneBic();
179
        }
180
181
        if ($sIban !== false && $sBic !== false && $this->isSepaDataValid($sIban, $sBic)) {
182
            $this->addParameter('iban', $sIban);
183
            $this->addParameter('bic', $sBic);
184
        }
185
186
        $this->aParameters = array_merge($this->aParameters, $oPayment->getPaymentSpecificDebitParameters($oOrder));
187
188
        $aResponse = $this->send($oPayment);
189
190
        return $aResponse;
191
    }
192
193
    /**
194
     * Get substituted refund appendix text
195
     *
196
     * @param  Order        $oOrder
197
     * @param  PayoneMethod $oPayment
198
     * @return string
199
     */
200
    protected function getRefundAppendix(Order $oOrder, PayoneMethod $oPayment)
201
    {
202
        $sText = $this->shopHelper->getConfigParam('invoice_appendix_refund', 'invoicing', 'payone_general', $this->storeCode);
203
        $sCreditMemoIncrId = '';
204
        $sInvoiceIncrementId = '';
205
        $sInvoiceId = '';
206
207
        $oCreditmemo = $oPayment->getCreditmemo();
208
        if ($oCreditmemo) {
209
            $sCreditMemoIncrId = $oCreditmemo->getIncrementId();
210
            $oInvoice = $oCreditmemo->getInvoice();
211
            if ($oInvoice) {
212
                $sInvoiceIncrementId = $oInvoice->getIncrementId();
213
                $sInvoiceId = $oInvoice->getId();
214
            }
215
        }
216
217
        $aSubstitutionArray = [
218
            '{order_increment_id}' => $oOrder->getIncrementId(),
219
            '{order_id}' => $oOrder->getId(),
220
            '{customer_id}' => $oOrder->getCustomerId(),
221
            '{creditmemo_increment_id}' => $sCreditMemoIncrId,
222
            '{invoice_increment_id}' => $sInvoiceIncrementId,
223
            '{invoice_id}' => $sInvoiceId,
224
        ];
225
        $sRefundAppendix = $this->toolkitHelper->handleSubstituteReplacement($sText, $aSubstitutionArray, 255);
226
        return $sRefundAppendix;
227
    }
228
229
    /**
230
     * Validate IBAN
231
     *
232
     * @param  string $sIban
233
     * @return bool
234
     */
235
    protected function isIbanValid($sIban)
236
    {
237
        $sRegex = '/^[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}(?:[a-zA-Z0-9]?){0,16}$/';
238
        return $this->checkRegex($sRegex, $sIban);
239
    }
240
241
    /**
242
     * Check if the regex validates correctly
243
     *
244
     * @param  string $sRegex
245
     * @param  string $sValue
246
     * @return bool
247
     */
248
    protected function checkRegex($sRegex, $sValue)
249
    {
250
        preg_match($sRegex, str_replace(' ', '', $sValue), $aMatches);
251
        if (empty($aMatches)) {
252
            return false;
253
        }
254
        return true;
255
    }
256
257
    /**
258
     * Validate IBAN
259
     *
260
     * @param  string $sBic
261
     * @return bool
262
     */
263
    protected function isBicValid($sBic)
264
    {
265
        $sRegex = '/^([a-zA-Z]{4}[a-zA-Z]{2}[a-zA-Z0-9]{2}([a-zA-Z0-9]{3})?)$/';
266
        return $this->checkRegex($sRegex, $sBic);
267
    }
268
269
    /**
270
     * Check IBAN and BIC fields
271
     *
272
     * @param  string $sIban
273
     * @param  string $sBic
274
     * @return bool
275
     * @throws LocalizedException
276
     */
277
    public function isSepaDataValid($sIban, $sBic)
278
    {
279
        if (!$this->isIbanValid($sIban)) {
280
            throw new LocalizedException(__('The given IBAN is invalid!'));
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

280
            throw new LocalizedException(/** @scrutinizer ignore-call */ __('The given IBAN is invalid!'));
Loading history...
281
        }
282
        if (!$this->isBicValid($sBic)) {
283
            throw new LocalizedException(__('The given BIC is invalid!'));
284
        }
285
        return true;
286
    }
287
}
288