Completed
Push — master ( 9097d5...0ce82e )
by Florian
06:13
created

Debit::isSepaDataValid()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 2
dl 0
loc 9
rs 9.6666
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\Model\Api\Request;
28
29
use Magento\Framework\Exception\LocalizedException;
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 Payone\Core\Model\Methods\PayoneMethod;
32
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...
33
34
/**
35
 * Class for the PAYONE Server API request "debit"
36
 */
37
class Debit extends Base
38
{
39
    /**
40
     * @var \Payone\Core\Model\Api\Invoice $invoiceGenerator
41
     */
42
    protected $invoiceGenerator;
43
44
    /**
45
     * PAYONE database helper
46
     *
47
     * @var \Payone\Core\Helper\Database
48
     */
49
    protected $databaseHelper;
50
51
    /**
52
     * PAYONE toolkit helper
53
     *
54
     * @var \Payone\Core\Helper\Toolkit
55
     */
56
    protected $toolkitHelper;
57
58
    /**
59
     * Constructor
60
     *
61
     * @param \Payone\Core\Helper\Shop                $shopHelper
62
     * @param \Payone\Core\Helper\Environment         $environmentHelper
63
     * @param \Payone\Core\Helper\Api                 $apiHelper
64
     * @param \Payone\Core\Model\ResourceModel\ApiLog $apiLog
65
     * @param \Payone\Core\Model\Api\Invoice          $invoiceGenerator
66
     * @param \Payone\Core\Helper\Database            $databaseHelper
67
     * @param \Payone\Core\Helper\Toolkit             $toolkitHelper
68
     */
69
    public function __construct(
70
        \Payone\Core\Helper\Shop $shopHelper,
71
        \Payone\Core\Helper\Environment $environmentHelper,
72
        \Payone\Core\Helper\Api $apiHelper,
73
        \Payone\Core\Model\ResourceModel\ApiLog $apiLog,
74
        \Payone\Core\Model\Api\Invoice $invoiceGenerator,
75
        \Payone\Core\Helper\Database $databaseHelper,
76
        \Payone\Core\Helper\Toolkit $toolkitHelper
77
    ) {
78
        parent::__construct($shopHelper, $environmentHelper, $apiHelper, $apiLog);
79
        $this->invoiceGenerator = $invoiceGenerator;
80
        $this->databaseHelper = $databaseHelper;
81
        $this->toolkitHelper = $toolkitHelper;
82
    }
83
84
    /**
85
     * Get creditmemo array from request parameters
86
     *
87
     * @return mixed
88
     */
89
    protected function getCreditmemoRequestParams()
90
    {
91
        return $this->shopHelper->getRequestParameter('creditmemo');
92
    }
93
94
    /**
95
     * Generate position list for invoice data transmission
96
     *
97
     * @param Order $oOrder
98
     * @return array|false
99
     */
100
    protected function getInvoiceList(Order $oOrder)
101
    {
102
        $aCreditmemo = $this->getCreditmemoRequestParams();
103
104
        $aPositions = [];
105
        $blFull = true;
106
        if ($aCreditmemo && array_key_exists('items', $aCreditmemo) !== false) {
107
            foreach ($oOrder->getAllItems() as $oItem) {
108
                if (isset($aCreditmemo['items'][$oItem->getItemId()]) && $aCreditmemo['items'][$oItem->getItemId()]['qty'] > 0) {
109
                    $aPositions[$oItem->getProductId().$oItem->getSku()] = $aCreditmemo['items'][$oItem->getItemId()]['qty'];
110
                    if ($aCreditmemo['items'][$oItem->getItemId()]['qty'] != $oItem->getQtyOrdered()) {
111
                        $blFull = false;
112
                    }
113
                } else {
114
                    $blFull = false;
115
                }
116
            }
117
        }
118
        if (isset($aCreditmemo['shipping_amount']) && $aCreditmemo['shipping_amount'] != 0) {
119
            $aPositions['delcost'] = $aCreditmemo['shipping_amount'];
120
        }
121
        if ($blFull === true && (!isset($aCreditmemo['shipping_amount']) || $aCreditmemo['shipping_amount'] == $oOrder->getBaseShippingInclTax())) {
122
            $aPositions = false; // false = full debit
123
        }
124
        return $aPositions;
125
    }
126
127
    /**
128
     * Send request "debit" to PAYONE server API
129
     *
130
     * @param  PayoneMethod  $oPayment
131
     * @param  InfoInterface $oPaymentInfo
132
     * @param  float         $dAmount
133
     * @return array
134
     */
135
    public function sendRequest(PayoneMethod $oPayment, InfoInterface $oPaymentInfo, $dAmount)
136
    {
137
        $oOrder = $oPaymentInfo->getOrder();
138
139
        $aPositions = $this->getInvoiceList($oOrder);
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);
155
        $this->addParameter('currency', $oOrder->getOrderCurrencyCode()); // Currency
156
        $this->addParameter('transactiontype', 'GT');
157
158
        $sRefundAppendix = $this->getRefundAppendix($oOrder, $oPayment);
159
        if (!empty($sRefundAppendix)) {
160
            $this->addParameter('invoiceappendix', $sRefundAppendix);
161
        }
162
163
        if ($this->apiHelper->isInvoiceDataNeeded($oPayment)) {
164
            $this->invoiceGenerator->addProductInfo($this, $oOrder, $aPositions, true); // add invoice parameters
0 ignored issues
show
Bug introduced by
$aPositions of type false is incompatible with the type array expected by parameter $aPositions of Payone\Core\Model\Api\Invoice::addProductInfo(). ( Ignorable by Annotation )

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

164
            $this->invoiceGenerator->addProductInfo($this, $oOrder, /** @scrutinizer ignore-type */ $aPositions, true); // add invoice parameters
Loading history...
165
        }
166
167
        $aCreditmemo = $this->getCreditmemoRequestParams();
168
        $sIban = false;
169
        $sBic = false;
170
        if (!empty($oOrder->getPayoneRefundIban()) && !empty($oOrder->getPayoneRefundBic())) {
171
            $sIban = $oOrder->getPayoneRefundIban();
172
            $sBic = $oOrder->getPayoneRefundBic();
173
        } elseif (isset($aCreditmemo['payone_iban']) && isset($aCreditmemo['payone_bic'])) {
174
            $sIban = $aCreditmemo['payone_iban'];
175
            $sBic = $aCreditmemo['payone_bic'];
176
        }
177
178
        if ($sIban !== false && $sBic !== false && $this->isSepaDataValid($sIban, $sBic)) {
179
            $this->addParameter('iban', $sIban);
180
            $this->addParameter('bic', $sBic);
181
        }
182
183
        $aResponse = $this->send($oPayment);
184
185
        return $aResponse;
186
    }
187
188
    /**
189
     * Get substituted refund appendix text
190
     *
191
     * @param  Order        $oOrder
192
     * @param  PayoneMethod $oPayment
193
     * @return string
194
     */
195
    protected function getRefundAppendix(Order $oOrder, PayoneMethod $oPayment)
196
    {
197
        $sText = $this->shopHelper->getConfigParam('invoice_appendix_refund', 'invoicing');
198
        $sCreditMemoIncrId = '';
199
        $sInvoiceIncrementId = '';
200
        $sInvoiceId = '';
201
202
        $oCreditmemo = $oPayment->getCreditmemo();
203
        if ($oCreditmemo) {
204
            $sCreditMemoIncrId = $oCreditmemo->getIncrementId();
205
            $oInvoice = $oCreditmemo->getInvoice();
206
            if ($oInvoice) {
207
                $sInvoiceIncrementId = $oInvoice->getIncrementId();
208
                $sInvoiceId = $oInvoice->getId();
209
            }
210
        }
211
212
        $aSubstitutionArray = [
213
            '{{order_increment_id}}' => $oOrder->getIncrementId(),
214
            '{{order_id}}' => $oOrder->getId(),
215
            '{{customer_id}}' => $oOrder->getCustomerId(),
216
            '{{creditmemo_increment_id}}' => $sCreditMemoIncrId,
217
            '{{invoice_increment_id}}' => $sInvoiceIncrementId,
218
            '{{invoice_id}}' => $sInvoiceId,
219
        ];
220
        $sRefundAppendix = $this->toolkitHelper->handleSubstituteReplacement($sText, $aSubstitutionArray, 255);
0 ignored issues
show
Bug introduced by
$aSubstitutionArray of type array is incompatible with the type string expected by parameter $aSubstitutionArray of Payone\Core\Helper\Toolk...SubstituteReplacement(). ( Ignorable by Annotation )

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

220
        $sRefundAppendix = $this->toolkitHelper->handleSubstituteReplacement($sText, /** @scrutinizer ignore-type */ $aSubstitutionArray, 255);
Loading history...
221
        return $sRefundAppendix;
222
    }
223
224
    /**
225
     * Validate IBAN
226
     *
227
     * @param  string $sIban
228
     * @return bool
229
     */
230
    protected function isIbanValid($sIban)
231
    {
232
        $sRegex = '/^[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}(?:[a-zA-Z0-9]?){0,16}$/';
233
        return $this->checkRegex($sRegex, $sIban);
234
    }
235
236
    /**
237
     * Check if the regex validates correctly
238
     *
239
     * @param  string $sRegex
240
     * @param  string $sValue
241
     * @return bool
242
     */
243
    protected function checkRegex($sRegex, $sValue)
244
    {
245
        preg_match($sRegex, str_replace(' ', '', $sValue), $aMatches);
246
        if (empty($aMatches)) {
247
            return false;
248
        }
249
        return true;
250
    }
251
252
    /**
253
     * Validate IBAN
254
     *
255
     * @param  string $sBic
256
     * @return bool
257
     */
258
    protected function isBicValid($sBic)
259
    {
260
        $sRegex = '/^([a-zA-Z]{4}[a-zA-Z]{2}[a-zA-Z0-9]{2}([a-zA-Z0-9]{3})?)$/';
261
        return $this->checkRegex($sRegex, $sBic);
262
    }
263
264
    /**
265
     * Check IBAN and BIC fields
266
     *
267
     * @param  string $sIban
268
     * @param  string $sBic
269
     * @return bool
270
     * @throws LocalizedException
271
     */
272
    public function isSepaDataValid($sIban, $sBic)
273
    {
274
        if (!$this->isIbanValid($sIban)) {
275
            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

275
            throw new LocalizedException(/** @scrutinizer ignore-call */ __('The given IBAN is invalid!'));
Loading history...
276
        }
277
        if (!$this->isBicValid($sBic)) {
278
            throw new LocalizedException(__('The given BIC is invalid!'));
279
        }
280
        return true;
281
    }
282
}
283