1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Shopware 5 |
4
|
|
|
* Copyright (c) shopware AG |
5
|
|
|
* |
6
|
|
|
* According to our dual licensing model, this program can be used either |
7
|
|
|
* under the terms of the GNU Affero General Public License, version 3, |
8
|
|
|
* or under a proprietary license. |
9
|
|
|
* |
10
|
|
|
* The texts of the GNU Affero General Public License with an additional |
11
|
|
|
* permission and of our proprietary license can be found at and |
12
|
|
|
* in the LICENSE file you have received along with this program. |
13
|
|
|
* |
14
|
|
|
* This program is distributed in the hope that it will be useful, |
15
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
16
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17
|
|
|
* GNU Affero General Public License for more details. |
18
|
|
|
* |
19
|
|
|
* "Shopware" is a registered trademark of shopware AG. |
20
|
|
|
* The licensing of the program under the AGPLv3 does not imply a |
21
|
|
|
* trademark license. Therefore any rights, title and interest in |
22
|
|
|
* our trademarks remain entirely with us. |
23
|
|
|
*/ |
24
|
|
|
use Enlight_Controller_Request_Request as Request; |
25
|
|
|
use Shopware\Components\BasketSignature\Basket; |
26
|
|
|
use Shopware\Components\BasketSignature\BasketPersister; |
27
|
|
|
use Shopware\Components\BasketSignature\BasketSignatureGeneratorInterface; |
28
|
|
|
use Shopware\Components\CSRFGetProtectionAware; |
29
|
|
|
use Shopware\Models\Customer\Address; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @category Shopware |
33
|
|
|
* |
34
|
|
|
* @copyright Copyright (c) shopware AG (http://www.shopware.de) |
35
|
|
|
*/ |
36
|
|
|
class Shopware_Controllers_Frontend_Checkout extends Enlight_Controller_Action implements CSRFGetProtectionAware |
37
|
|
|
{ |
38
|
|
|
/** |
39
|
|
|
* Reference to sAdmin object (core/class/sAdmin.php) |
40
|
|
|
* |
41
|
|
|
* @var sAdmin |
42
|
|
|
*/ |
43
|
|
|
protected $admin; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Reference to sBasket object (core/class/sBasket.php) |
47
|
|
|
* |
48
|
|
|
* @var sBasket |
49
|
|
|
*/ |
50
|
|
|
protected $basket; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Reference to Shopware session object (Shopware()->Session) |
54
|
|
|
* |
55
|
|
|
* @var Enlight_Components_Session_Namespace |
56
|
|
|
*/ |
57
|
|
|
protected $session; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Init method that get called automatically |
61
|
|
|
* |
62
|
|
|
* Set class properties |
63
|
|
|
*/ |
64
|
|
|
public function init() |
65
|
|
|
{ |
66
|
|
|
$this->admin = Shopware()->Modules()->Admin(); |
67
|
|
|
$this->basket = Shopware()->Modules()->Basket(); |
68
|
|
|
$this->session = Shopware()->Session(); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* @return array |
73
|
|
|
*/ |
74
|
|
|
public function getCSRFProtectedActions() |
75
|
|
|
{ |
76
|
|
|
return [ |
77
|
|
|
'ajaxAddArticle', |
78
|
|
|
'addArticle', |
79
|
|
|
'ajaxAddArticleCart', |
80
|
|
|
'ajaxDeleteArticle', |
81
|
|
|
'ajaxDeleteArticleCart', |
82
|
|
|
'deleteArticle', |
83
|
|
|
'addAccessories', |
84
|
|
|
'changeQuantity', |
85
|
|
|
'addPremium', |
86
|
|
|
'setAddress', |
87
|
|
|
]; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Pre dispatch method |
92
|
|
|
*/ |
93
|
|
|
public function preDispatch() |
94
|
|
|
{ |
95
|
|
|
$events = Shopware()->Container()->get('events'); |
96
|
|
|
$events->addListener('Shopware_Modules_Admin_Payment_Fallback', [$this, 'flagPaymentBlocked']); |
97
|
|
|
|
98
|
|
|
$this->View()->setScope(Enlight_Template_Manager::SCOPE_PARENT); |
99
|
|
|
|
100
|
|
|
$this->View()->sUserLoggedIn = $this->admin->sCheckUser(); |
101
|
|
|
$this->View()->sUserData = $this->getUserData(); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Called if the sAdmin resets the selected customer payment to the shop preset |
106
|
|
|
*/ |
107
|
|
|
public function flagPaymentBlocked() |
108
|
|
|
{ |
109
|
|
|
$this->View()->assign('paymentBlocked', true); |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* Save basket to session |
114
|
|
|
*/ |
115
|
|
|
public function postDispatch() |
116
|
|
|
{ |
117
|
|
|
$this->session->sBasketCurrency = Shopware()->Shop()->getCurrency()->getId(); |
118
|
|
|
$this->session->sBasketQuantity = $this->basket->sCountBasket(); |
119
|
|
|
$amount = $this->basket->sGetAmount(); |
120
|
|
|
$this->session->sBasketAmount = empty($amount) ? 0 : array_shift($amount); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* Forward to cart or confirm action depending on user state |
125
|
|
|
*/ |
126
|
|
|
public function indexAction() |
127
|
|
|
{ |
128
|
|
|
if ($this->basket->sCountBasket() < 1 || empty($this->View()->sUserLoggedIn)) { |
129
|
|
|
$this->forward('cart'); |
130
|
|
|
} else { |
131
|
|
|
$this->forward('confirm'); |
132
|
|
|
} |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Read all data from objects / models that are required in cart view |
137
|
|
|
* (User-Data / Payment-Data / Basket-Data etc.) |
138
|
|
|
*/ |
139
|
|
|
public function cartAction() |
140
|
|
|
{ |
141
|
|
|
$this->View()->sCountry = $this->getSelectedCountry(); |
142
|
|
|
$this->View()->sPayment = $this->getSelectedPayment(); |
143
|
|
|
$this->View()->sDispatch = $this->getSelectedDispatch(); |
144
|
|
|
$this->View()->sCountryList = $this->getCountryList(); |
145
|
|
|
$this->View()->sPayments = $this->getPayments(); |
146
|
|
|
$this->View()->sDispatches = $this->getDispatches(); |
147
|
|
|
$this->View()->sDispatchNoOrder = $this->getDispatchNoOrder(); |
148
|
|
|
$this->View()->sState = $this->getSelectedState(); |
149
|
|
|
|
150
|
|
|
$this->View()->sUserData = $this->getUserData(); |
151
|
|
|
$this->View()->sBasket = $this->getBasket(); |
152
|
|
|
|
153
|
|
|
$this->View()->sShippingcosts = $this->View()->sBasket['sShippingcosts']; |
154
|
|
|
$this->View()->sShippingcostsDifference = $this->View()->sBasket['sShippingcostsDifference']; |
155
|
|
|
$this->View()->sAmount = $this->View()->sBasket['sAmount']; |
156
|
|
|
$this->View()->sAmountWithTax = $this->View()->sBasket['sAmountWithTax']; |
157
|
|
|
$this->View()->sAmountTax = $this->View()->sBasket['sAmountTax']; |
158
|
|
|
$this->View()->sAmountNet = $this->View()->sBasket['AmountNetNumeric']; |
159
|
|
|
|
160
|
|
|
$this->View()->sMinimumSurcharge = $this->getMinimumCharge(); |
161
|
|
|
$this->View()->sPremiums = $this->getPremiums(); |
162
|
|
|
|
163
|
|
|
$this->View()->sInquiry = $this->getInquiry(); |
164
|
|
|
$this->View()->sInquiryLink = $this->getInquiryLink(); |
165
|
|
|
|
166
|
|
|
$this->View()->sTargetAction = 'cart'; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* Mostly equivalent to cartAction |
171
|
|
|
* Get user, basket and payment data for view assignment |
172
|
|
|
* Create temporary entry in s_order table |
173
|
|
|
* Check some conditions (minimum charge) |
174
|
|
|
*/ |
175
|
|
|
public function confirmAction() |
176
|
|
|
{ |
177
|
|
|
if (empty($this->View()->sUserLoggedIn)) { |
178
|
|
|
return $this->forward( |
179
|
|
|
'login', |
180
|
|
|
'account', |
181
|
|
|
null, |
182
|
|
|
['sTarget' => 'checkout', 'sTargetAction' => 'confirm', 'showNoAccount' => true] |
183
|
|
|
); |
184
|
|
|
} elseif ($this->basket->sCountBasket() < 1) { |
185
|
|
|
return $this->forward('cart'); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
$this->View()->sCountry = $this->getSelectedCountry(); |
189
|
|
|
$this->View()->sState = $this->getSelectedState(); |
190
|
|
|
|
191
|
|
|
$payment = $this->getSelectedPayment(); |
192
|
|
|
if (array_key_exists('validation', $payment) && !empty($payment['validation'])) { |
193
|
|
|
$this->onPaymentMethodValidationFail(); |
194
|
|
|
|
195
|
|
|
return; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
$this->View()->sPayment = $payment; |
199
|
|
|
|
200
|
|
|
$userData = $this->View()->sUserData; |
201
|
|
|
$userData['additional']['payment'] = $this->View()->sPayment; |
202
|
|
|
$this->View()->sUserData = $userData; |
203
|
|
|
|
204
|
|
|
$this->View()->sDispatch = $this->getSelectedDispatch(); |
205
|
|
|
$this->View()->sPayments = $this->getPayments(); |
206
|
|
|
$this->View()->sDispatches = $this->getDispatches(); |
207
|
|
|
|
208
|
|
|
$this->View()->sBasket = $this->getBasket(); |
209
|
|
|
|
210
|
|
|
$this->View()->sLaststock = $this->basket->sCheckBasketQuantities(); |
211
|
|
|
$this->View()->sShippingcosts = $this->View()->sBasket['sShippingcosts']; |
212
|
|
|
$this->View()->sShippingcostsDifference = $this->View()->sBasket['sShippingcostsDifference']; |
213
|
|
|
$this->View()->sAmount = $this->View()->sBasket['sAmount']; |
214
|
|
|
$this->View()->sAmountWithTax = $this->View()->sBasket['sAmountWithTax']; |
215
|
|
|
$this->View()->sAmountTax = $this->View()->sBasket['sAmountTax']; |
216
|
|
|
$this->View()->sAmountNet = $this->View()->sBasket['AmountNetNumeric']; |
217
|
|
|
|
218
|
|
|
$this->View()->sPremiums = $this->getPremiums(); |
219
|
|
|
|
220
|
|
|
$this->View()->sNewsletter = isset($this->session['sNewsletter']) ? $this->session['sNewsletter'] : null; |
221
|
|
|
$this->View()->sComment = isset($this->session['sComment']) ? $this->session['sComment'] : null; |
222
|
|
|
|
223
|
|
|
$this->View()->sShowEsdNote = $this->getEsdNote(); |
224
|
|
|
$this->View()->sDispatchNoOrder = $this->getDispatchNoOrder(); |
225
|
|
|
$this->View()->sRegisterFinished = !empty($this->session['sRegisterFinished']); |
226
|
|
|
|
227
|
|
|
$this->saveTemporaryOrder(); |
228
|
|
|
|
229
|
|
|
if ($this->getMinimumCharge() || count($this->View()->sBasket['content']) <= 0) { |
230
|
|
|
return $this->forward('cart'); |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
$sOrderVariables = $this->View()->getAssign(); |
234
|
|
|
$sOrderVariables['sBasketView'] = $sOrderVariables['sBasket']; |
235
|
|
|
$sOrderVariables['sBasket'] = $this->getBasket(false); |
236
|
|
|
|
237
|
|
|
$this->session['sOrderVariables'] = new ArrayObject($sOrderVariables, ArrayObject::ARRAY_AS_PROPS); |
238
|
|
|
|
239
|
|
|
$agbChecked = $this->Request()->getParam('sAGB'); |
240
|
|
|
if (!empty($agbChecked)) { |
241
|
|
|
$this->View()->assign('sAGBChecked', true); |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
$this->View()->sTargetAction = 'confirm'; |
245
|
|
|
|
246
|
|
|
$this->View()->assign('hasMixedArticles', $this->basketHasMixedArticles($this->View()->sBasket)); |
247
|
|
|
$this->View()->assign('hasServiceArticles', $this->basketHasServiceArticles($this->View()->sBasket)); |
248
|
|
|
|
249
|
|
|
if (Shopware()->Config()->get('showEsdWarning')) { |
250
|
|
|
$this->View()->assign('hasEsdArticles', $this->basketHasEsdArticles($this->View()->sBasket)); |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
$serviceChecked = $this->Request()->getParam('serviceAgreementChecked'); |
254
|
|
|
if (!empty($serviceChecked)) { |
255
|
|
|
$this->View()->assign('serviceAgreementChecked', true); |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
$esdChecked = $this->Request()->getParam('esdAgreementChecked'); |
259
|
|
|
if (!empty($esdChecked)) { |
260
|
|
|
$this->View()->assign('esdAgreementChecked', true); |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
$errors = $this->Request()->getParam('agreementErrors'); |
264
|
|
|
if (!empty($errors)) { |
265
|
|
|
$this->View()->assign('agreementErrors', $errors); |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
$voucherErrors = $this->Request()->getParam('voucherErrors'); |
269
|
|
|
if (!empty($voucherErrors)) { |
270
|
|
|
$this->View()->assign('sVoucherError', $voucherErrors); |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
if (empty($activeBillingAddressId = $this->session->offsetGet('checkoutBillingAddressId'))) { |
274
|
|
|
$activeBillingAddressId = $userData['additional']['user']['default_billing_address_id']; |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
if (empty($activeShippingAddressId = $this->session->offsetGet('checkoutShippingAddressId'))) { |
278
|
|
|
$activeShippingAddressId = $userData['additional']['user']['default_shipping_address_id']; |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
$this->View()->assign('activeBillingAddressId', $activeBillingAddressId); |
282
|
|
|
$this->View()->assign('activeShippingAddressId', $activeShippingAddressId); |
283
|
|
|
|
284
|
|
|
$this->View()->assign('invalidBillingAddress', !$this->isValidAddress($activeBillingAddressId)); |
285
|
|
|
$this->View()->assign('invalidShippingAddress', !$this->isValidAddress($activeShippingAddressId)); |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
/** |
289
|
|
|
* Called from confirmAction View |
290
|
|
|
* Customers requests to finish current order |
291
|
|
|
* Check if all conditions match and save order |
292
|
|
|
*/ |
293
|
|
|
public function finishAction() |
294
|
|
|
{ |
295
|
|
|
if ($this->Request()->getParam('sUniqueID') && !empty($this->session['sOrderVariables'])) { |
296
|
|
|
$sql = ' |
297
|
|
|
SELECT transactionID as sTransactionumber, ordernumber as sOrderNumber |
298
|
|
|
FROM s_order |
299
|
|
|
WHERE temporaryID=? AND userID=? |
300
|
|
|
'; |
301
|
|
|
|
302
|
|
|
$order = Shopware()->Db()->fetchRow($sql, [$this->Request()->getParam('sUniqueID'), Shopware()->Session()->sUserId]); |
303
|
|
|
|
304
|
|
|
if (empty($order)) { |
305
|
|
|
if ($this->Request()->isGet()) { |
306
|
|
|
return $this->forward('confirm'); |
307
|
|
|
} |
308
|
|
|
} else { |
309
|
|
|
$this->View()->assign($order); |
310
|
|
|
$orderVariables = $this->session['sOrderVariables']->getArrayCopy(); |
311
|
|
|
|
312
|
|
|
if (!empty($orderVariables['sOrderNumber'])) { |
313
|
|
|
$orderVariables['sAddresses']['billing'] = $this->getOrderAddress($orderVariables['sOrderNumber'], 'billing'); |
314
|
|
|
$orderVariables['sAddresses']['shipping'] = $this->getOrderAddress($orderVariables['sOrderNumber'], 'shipping'); |
315
|
|
|
$orderVariables['sAddresses']['equal'] = $this->areAddressesEqual($orderVariables['sAddresses']['billing'], $orderVariables['sAddresses']['shipping']); |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
$this->View()->assign($orderVariables); |
319
|
|
|
|
320
|
|
|
if ($this->View()->sBasketView) { |
321
|
|
|
$this->View()->sBasket = $this->View()->sBasketView; |
322
|
|
|
unset($this->View()->sBasketView); |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
return; |
326
|
|
|
} |
327
|
|
|
} |
328
|
|
|
|
329
|
|
|
if (empty($this->session['sOrderVariables']) || $this->getMinimumCharge() || $this->getEsdNote() || $this->getDispatchNoOrder()) { |
330
|
|
|
return $this->forward('confirm'); |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
$checkQuantities = $this->basket->sCheckBasketQuantities(); |
334
|
|
|
if (!empty($checkQuantities['hideBasket'])) { |
335
|
|
|
return $this->forward('confirm'); |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
$orderVariables = $this->session['sOrderVariables']->getArrayCopy(); |
339
|
|
|
|
340
|
|
|
if (!empty($orderVariables['sOrderNumber'])) { |
341
|
|
|
$orderVariables['sAddresses']['billing'] = $this->getOrderAddress($orderVariables['sOrderNumber'], 'billing'); |
342
|
|
|
$orderVariables['sAddresses']['shipping'] = $this->getOrderAddress($orderVariables['sOrderNumber'], 'shipping'); |
343
|
|
|
$orderVariables['sAddresses']['equal'] = $this->areAddressesEqual($orderVariables['sAddresses']['billing'], $orderVariables['sAddresses']['shipping']); |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
$this->View()->assign($orderVariables); |
347
|
|
|
if ($this->View()->sBasketView) { |
348
|
|
|
$this->View()->sBasket = $this->View()->sBasketView; |
349
|
|
|
unset($this->View()->sBasketView); |
350
|
|
|
} |
351
|
|
|
|
352
|
|
|
if ($this->basket->sCountBasket() <= 0) { |
353
|
|
|
return; |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
if (!empty($this->View()->sUserData['additional']['payment']['embediframe'])) { |
357
|
|
|
return; |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
if ($this->Request()->getParam('sNewsletter') !== null) { |
361
|
|
|
$this->session['sNewsletter'] = $this->Request()->getParam('sNewsletter') ? true : false; |
362
|
|
|
} |
363
|
|
|
if ($this->Request()->getParam('sComment') !== null) { |
364
|
|
|
$this->session['sComment'] = trim(strip_tags($this->Request()->getParam('sComment'))); |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
$basket = $this->View()->sBasket; |
368
|
|
|
$agreements = $this->getInvalidAgreements($basket, $this->Request()); |
369
|
|
|
|
370
|
|
|
if (!empty($agreements)) { |
371
|
|
|
$this->View()->sAGBError = array_key_exists('agbError', $agreements); |
372
|
|
|
|
373
|
|
|
return $this->forward( |
374
|
|
|
'confirm', |
375
|
|
|
null, |
376
|
|
|
null, |
377
|
|
|
['agreementErrors' => $agreements] |
378
|
|
|
); |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
if (!$this->basket->validateVoucher($this->session['sessionId'], $this->session['sUserId'])) { |
382
|
|
|
$namespace = $this->container->get('snippets')->getNamespace('frontend/basket/internalMessages'); |
383
|
|
|
|
384
|
|
|
return $this->forward( |
385
|
|
|
'confirm', |
386
|
|
|
null, |
387
|
|
|
null, |
388
|
|
|
['voucherErrors' => [ |
389
|
|
|
$namespace->get('VoucherFailureAlreadyUsed', 'This voucher was used in an previous order'), |
390
|
|
|
]] |
391
|
|
|
); |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
if (empty($activeBillingAddressId = $this->session->offsetGet('checkoutBillingAddressId'))) { |
395
|
|
|
$activeBillingAddressId = $this->View()->sUserData['additional']['user']['default_billing_address_id']; |
396
|
|
|
} |
397
|
|
|
|
398
|
|
|
if (empty($activeShippingAddressId = $this->session->offsetGet('checkoutShippingAddressId'))) { |
399
|
|
|
$activeShippingAddressId = $this->View()->sUserData['additional']['user']['default_shipping_address_id']; |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
if (!$this->isValidAddress($activeBillingAddressId) || !$this->isValidAddress($activeShippingAddressId)) { |
403
|
|
|
$this->forward('confirm'); |
404
|
|
|
|
405
|
|
|
return; |
406
|
|
|
} |
407
|
|
|
|
408
|
|
|
if (!empty($this->session['sNewsletter'])) { |
409
|
|
|
$this->admin->sUpdateNewsletter(true, $this->admin->sGetUserMailById(), true); |
410
|
|
|
} |
411
|
|
|
|
412
|
|
|
if ($this->Request()->isGet()) { |
413
|
|
|
return $this->forward('confirm'); |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
$this->updateCurrencyDependencies($basket['sCurrencyId']); |
417
|
|
|
|
418
|
|
|
$this->saveOrder(); |
419
|
|
|
$this->saveDefaultAddresses(); |
420
|
|
|
$this->resetTemporaryAddresses(); |
421
|
|
|
|
422
|
|
|
$this->session->offsetUnset('sComment'); |
423
|
|
|
|
424
|
|
|
$orderVariables = $this->session['sOrderVariables']->getArrayCopy(); |
425
|
|
|
|
426
|
|
|
$orderVariables['sAddresses']['billing'] = $this->getOrderAddress($orderVariables['sOrderNumber'], 'billing'); |
427
|
|
|
$orderVariables['sAddresses']['shipping'] = $this->getOrderAddress($orderVariables['sOrderNumber'], 'shipping'); |
428
|
|
|
$orderVariables['sAddresses']['equal'] = $this->areAddressesEqual($orderVariables['sAddresses']['billing'], $orderVariables['sAddresses']['shipping']); |
429
|
|
|
|
430
|
|
|
$this->View()->assign($orderVariables); |
431
|
|
|
|
432
|
|
|
if ($this->View()->sBasketView) { |
433
|
|
|
$this->View()->sBasket = $this->View()->sBasketView; |
434
|
|
|
unset($this->View()->sBasketView); |
435
|
|
|
} |
436
|
|
|
} |
437
|
|
|
|
438
|
|
|
/** |
439
|
|
|
* Used during the checkout process |
440
|
|
|
* Returns the user to the shop homepage |
441
|
|
|
* If the user has a noAccount account, it is automatically logged out |
442
|
|
|
*/ |
443
|
|
|
public function returnAction() |
444
|
|
|
{ |
445
|
|
|
if ($this->View()->sUserData['additional']['user']['accountmode'] == 1) { |
446
|
|
|
Shopware()->Session()->unsetAll(); |
447
|
|
|
Shopware()->Modules()->Basket()->sRefreshBasket(); |
448
|
|
|
} |
449
|
|
|
|
450
|
|
|
return $this->redirect(['controller' => 'index']); |
451
|
|
|
} |
452
|
|
|
|
453
|
|
|
/** |
454
|
|
|
* If any external payment mean chooses by customer |
455
|
|
|
* Forward to payment page after order submitting |
456
|
|
|
*/ |
457
|
|
|
public function paymentAction() |
458
|
|
|
{ |
459
|
|
|
if (empty($this->session['sOrderVariables']) |
460
|
|
|
|| $this->getMinimumCharge() |
461
|
|
|
|| $this->getEsdNote() |
462
|
|
|
|| $this->getDispatchNoOrder()) { |
463
|
|
|
return $this->forward('confirm'); |
464
|
|
|
} |
465
|
|
|
|
466
|
|
|
if ($this->Request()->getParam('sNewsletter') !== null) { |
467
|
|
|
$this->session['sNewsletter'] = $this->Request()->getParam('sNewsletter') ? true : false; |
468
|
|
|
} |
469
|
|
|
if ($this->Request()->getParam('sComment') !== null) { |
470
|
|
|
$this->session['sComment'] = trim(strip_tags($this->Request()->getParam('sComment'))); |
471
|
|
|
} |
472
|
|
|
|
473
|
|
|
if (!Shopware()->Config()->get('IgnoreAGB') && !$this->Request()->getParam('sAGB')) { |
474
|
|
|
$this->View()->sAGBError = true; |
475
|
|
|
|
476
|
|
|
return $this->forward('confirm'); |
477
|
|
|
} |
478
|
|
|
|
479
|
|
|
$this->View()->assign($this->session['sOrderVariables']->getArrayCopy()); |
480
|
|
|
$this->View()->sAGBError = false; |
481
|
|
|
|
482
|
|
|
if (empty($this->View()->sPayment['embediframe']) |
483
|
|
|
&& empty($this->View()->sPayment['action'])) { |
484
|
|
|
return $this->forward('confirm'); |
485
|
|
|
} |
486
|
|
|
|
487
|
|
|
if (!empty($this->session['sNewsletter'])) { |
488
|
|
|
$this->admin->sUpdateNewsletter(true, $this->admin->sGetUserMailById(), true); |
489
|
|
|
} |
490
|
|
|
|
491
|
|
|
if (!empty($this->View()->sPayment['embediframe'])) { |
492
|
|
|
$embedded = $this->View()->sPayment['embediframe']; |
493
|
|
|
$embedded = preg_replace('#^[./]+#', '', $embedded); |
494
|
|
|
$embedded .= '?sCoreId=' . Shopware()->Session()->get('sessionId'); |
495
|
|
|
$embedded .= '&sAGB=1'; |
496
|
|
|
$embedded .= '&__basket_signature=' . $this->persistBasket(); |
497
|
|
|
$this->View()->sEmbedded = $embedded; |
498
|
|
|
} else { |
499
|
|
|
$action = explode('/', $this->View()->sPayment['action']); |
500
|
|
|
$this->redirect([ |
501
|
|
|
'controller' => $action[0], |
502
|
|
|
'action' => empty($action[1]) ? 'index' : $action[1], |
503
|
|
|
]); |
504
|
|
|
} |
505
|
|
|
} |
506
|
|
|
|
507
|
|
|
/** |
508
|
|
|
* Add an article to cart directly from cart / confirm view |
509
|
|
|
* |
510
|
|
|
* @param sAdd = ordernumber |
511
|
|
|
* @param sQuantity = quantity |
512
|
|
|
* |
513
|
|
|
* @throws LogicException |
514
|
|
|
*/ |
515
|
|
|
public function addArticleAction() |
516
|
|
|
{ |
517
|
|
|
if (strtolower($this->Request()->getMethod()) !== 'post') { |
518
|
|
|
throw new \LogicException('This action only admits post requests'); |
519
|
|
|
} |
520
|
|
|
|
521
|
|
|
$ordernumber = trim($this->Request()->getParam('sAdd')); |
522
|
|
|
$quantity = $this->Request()->getParam('sQuantity'); |
523
|
|
|
$articleID = Shopware()->Modules()->Articles()->sGetArticleIdByOrderNumber($ordernumber); |
524
|
|
|
|
525
|
|
|
$this->View()->sBasketInfo = $this->getInstockInfo($ordernumber, $quantity); |
526
|
|
|
|
527
|
|
|
if (!empty($articleID)) { |
528
|
|
|
$insertID = $this->basket->sAddArticle($ordernumber, $quantity); |
529
|
|
|
$this->View()->sArticleName = Shopware()->Modules()->Articles()->sGetArticleNameByOrderNumber($ordernumber); |
530
|
|
|
if (!empty($insertID)) { |
531
|
|
|
$basket = $this->getBasket(); |
532
|
|
|
foreach ($basket['content'] as $item) { |
533
|
|
|
if ($item['id'] == $insertID) { |
534
|
|
|
$this->View()->sArticle = $item; |
535
|
|
|
break; |
536
|
|
|
} |
537
|
|
|
} |
538
|
|
|
} |
539
|
|
|
|
540
|
|
|
if (Shopware()->Config()->get('similarViewedShow', true)) { |
541
|
|
|
$this->View()->sCrossSimilarShown = $this->getSimilarShown($articleID); |
542
|
|
|
} |
543
|
|
|
|
544
|
|
|
if (Shopware()->Config()->get('alsoBoughtShow', true)) { |
545
|
|
|
$this->View()->sCrossBoughtToo = $this->getBoughtToo($articleID); |
546
|
|
|
} |
547
|
|
|
} |
548
|
|
|
|
549
|
|
|
if ($this->Request()->getParam('isXHR') || !empty($this->Request()->callback)) { |
550
|
|
|
$this->Request()->setParam('sTargetAction', 'ajax_add_article'); |
551
|
|
|
} |
552
|
|
|
|
553
|
|
|
if ($this->Request()->getParam('sAddAccessories')) { |
554
|
|
|
$this->forward('addAccessories'); |
555
|
|
|
} else { |
556
|
|
|
$this->forward($this->Request()->getParam('sTargetAction', 'cart')); |
557
|
|
|
} |
558
|
|
|
} |
559
|
|
|
|
560
|
|
|
/** |
561
|
|
|
* Add more then one article directly from cart / confirm view |
562
|
|
|
* |
563
|
|
|
* @param sAddAccessories = List of article order numbers separated by ; |
564
|
|
|
* @param sAddAccessoriesQuantity = List of article quantities separated by ; |
565
|
|
|
*/ |
566
|
|
|
public function addAccessoriesAction() |
567
|
|
|
{ |
568
|
|
|
$this->addAccessories( |
569
|
|
|
$this->Request()->getParam('sAddAccessories'), |
570
|
|
|
$this->Request()->getParam('sAddAccessoriesQuantity') |
571
|
|
|
); |
572
|
|
|
|
573
|
|
|
$this->forward($this->Request()->getParam('sTargetAction', 'cart')); |
574
|
|
|
} |
575
|
|
|
|
576
|
|
|
/** |
577
|
|
|
* Delete an article from cart - |
578
|
|
|
* |
579
|
|
|
* @param sDelete = id from s_basket identifying the product to delete |
580
|
|
|
* Forward to cart / confirmation page after success |
581
|
|
|
*/ |
582
|
|
|
public function deleteArticleAction() |
583
|
|
|
{ |
584
|
|
|
if ($this->Request()->getParam('sDelete')) { |
585
|
|
|
$this->basket->sDeleteArticle($this->Request()->getParam('sDelete')); |
586
|
|
|
} |
587
|
|
|
$this->forward($this->Request()->getParam('sTargetAction', 'index')); |
588
|
|
|
} |
589
|
|
|
|
590
|
|
|
/** |
591
|
|
|
* Change quantity of a certain product |
592
|
|
|
* |
593
|
|
|
* @param sArticle = The article to update |
594
|
|
|
* @param sQuantity = new quantity |
595
|
|
|
* Forward to cart / confirm view after success |
596
|
|
|
*/ |
597
|
|
|
public function changeQuantityAction() |
598
|
|
|
{ |
599
|
|
|
if ($this->Request()->getParam('sArticle') && $this->Request()->getParam('sQuantity')) { |
600
|
|
|
$this->View()->sBasketInfo = $this->basket->sUpdateArticle($this->Request()->getParam('sArticle'), $this->Request()->getParam('sQuantity')); |
601
|
|
|
} |
602
|
|
|
$this->redirect(['action' => $this->Request()->getParam('sTargetAction', 'index')]); |
603
|
|
|
} |
604
|
|
|
|
605
|
|
|
/** |
606
|
|
|
* Add voucher to cart |
607
|
|
|
* |
608
|
|
|
* At failure view variable sVoucherError will give further information |
609
|
|
|
* At success return to cart / confirm view |
610
|
|
|
*/ |
611
|
|
|
public function addVoucherAction() |
612
|
|
|
{ |
613
|
|
|
if ($this->Request()->isPost()) { |
614
|
|
|
$voucher = $this->basket->sAddVoucher($this->Request()->getParam('sVoucher')); |
615
|
|
|
if (!empty($voucher['sErrorMessages'])) { |
616
|
|
|
$this->View()->sVoucherError = $voucher['sErrorMessages']; |
617
|
|
|
} |
618
|
|
|
} |
619
|
|
|
$this->forward($this->Request()->getParam('sTargetAction', 'index')); |
620
|
|
|
} |
621
|
|
|
|
622
|
|
|
/** |
623
|
|
|
* Add premium / bonus article to cart |
624
|
|
|
* |
625
|
|
|
* @param sAddPremium - ordernumber of bonus article (defined in s_articles_premiums) |
626
|
|
|
* Return to cart / confirm page on success |
627
|
|
|
*/ |
628
|
|
|
public function addPremiumAction() |
629
|
|
|
{ |
630
|
|
|
if ($this->Request()->isPost()) { |
631
|
|
|
if (!$this->Request()->getParam('sAddPremium')) { |
632
|
|
|
$this->View()->sBasketInfo = Shopware()->Snippets()->getNamespace()->get( |
633
|
|
|
'CheckoutSelectPremiumVariant', |
634
|
|
|
'Please select an option to place the required premium to the cart', |
635
|
|
|
true |
636
|
|
|
); |
637
|
|
|
} else { |
638
|
|
|
$this->basket->sSYSTEM->_GET['sAddPremium'] = $this->Request()->getParam('sAddPremium'); |
|
|
|
|
639
|
|
|
$this->basket->sInsertPremium(); |
640
|
|
|
} |
641
|
|
|
} |
642
|
|
|
$this->forward($this->Request()->getParam('sTargetAction', 'index')); |
643
|
|
|
} |
644
|
|
|
|
645
|
|
|
/** |
646
|
|
|
* On any change on country, payment or dispatch recalculate shipping costs |
647
|
|
|
* and forward to cart / confirm view |
648
|
|
|
*/ |
649
|
|
|
public function calculateShippingCostsAction() |
650
|
|
|
{ |
651
|
|
|
if ($this->Request()->getPost('sCountry')) { |
652
|
|
|
$this->session['sCountry'] = (int) $this->Request()->getPost('sCountry'); |
653
|
|
|
$this->session['sState'] = 0; |
654
|
|
|
$this->session['sArea'] = Shopware()->Db()->fetchOne(' |
655
|
|
|
SELECT areaID FROM s_core_countries WHERE id = ? |
656
|
|
|
', [$this->session['sCountry']]); |
657
|
|
|
} |
658
|
|
|
|
659
|
|
|
if ($this->Request()->getPost('sPayment')) { |
660
|
|
|
$this->session['sPaymentID'] = (int) $this->Request()->getPost('sPayment'); |
661
|
|
|
} |
662
|
|
|
|
663
|
|
|
if ($this->Request()->getPost('sDispatch')) { |
664
|
|
|
$this->session['sDispatch'] = (int) $this->Request()->getPost('sDispatch'); |
665
|
|
|
} |
666
|
|
|
|
667
|
|
|
if ($this->Request()->getPost('sState')) { |
668
|
|
|
$this->session['sState'] = (int) $this->Request()->getPost('sState'); |
669
|
|
|
} |
670
|
|
|
|
671
|
|
|
// We might change the shop context here so we need to initialize it again |
672
|
|
|
$this->get('shopware_storefront.context_service')->initializeShopContext(); |
673
|
|
|
|
674
|
|
|
// We need an indicator in the view to expand the shipping costs pre-calculation on page load |
675
|
|
|
$this->View()->assign('calculateShippingCosts', true); |
676
|
|
|
|
677
|
|
|
$this->forward($this->Request()->getParam('sTargetAction', 'index')); |
678
|
|
|
} |
679
|
|
|
|
680
|
|
|
/** |
681
|
|
|
* Action to handle selection of shipping and payment methods |
682
|
|
|
*/ |
683
|
|
|
public function shippingPaymentAction() |
684
|
|
|
{ |
685
|
|
|
if (empty($this->View()->sUserLoggedIn)) { |
686
|
|
|
return $this->forward( |
687
|
|
|
'login', |
688
|
|
|
'account', |
689
|
|
|
null, |
690
|
|
|
['sTarget' => 'checkout', 'sTargetAction' => 'shippingPayment', 'showNoAccount' => true] |
691
|
|
|
); |
692
|
|
|
} |
693
|
|
|
|
694
|
|
|
// Load payment options, select option and details |
695
|
|
|
$this->View()->sPayments = $this->getPayments(); |
696
|
|
|
$this->View()->sFormData = ['payment' => $this->View()->sUserData['additional']['user']['paymentID']]; |
697
|
|
|
$getPaymentDetails = $this->admin->sGetPaymentMeanById($this->View()->sFormData['payment']); |
698
|
|
|
|
699
|
|
|
$paymentClass = $this->admin->sInitiatePaymentClass($getPaymentDetails); |
700
|
|
|
if ($paymentClass instanceof \ShopwarePlugin\PaymentMethods\Components\BasePaymentMethod) { |
701
|
|
|
$data = $paymentClass->getCurrentPaymentDataAsArray(Shopware()->Session()->sUserId); |
702
|
|
|
if (!empty($data)) { |
703
|
|
|
$this->View()->sFormData += $data; |
704
|
|
|
} |
705
|
|
|
} |
706
|
|
|
if ($this->Request()->isPost()) { |
707
|
|
|
$values = $this->Request()->getPost(); |
708
|
|
|
$values['payment'] = $this->Request()->getPost('payment'); |
709
|
|
|
$values['isPost'] = true; |
710
|
|
|
$this->View()->sFormData = $values; |
711
|
|
|
} |
712
|
|
|
|
713
|
|
|
// Load current and all shipping methods |
714
|
|
|
$this->View()->sDispatch = $this->getSelectedDispatch(); |
715
|
|
|
$this->View()->sDispatches = $this->getDispatches($this->View()->sFormData['payment']); |
716
|
|
|
|
717
|
|
|
// We might change the shop context here so we need to initialize it again |
718
|
|
|
$this->get('shopware_storefront.context_service')->initializeShopContext(); |
719
|
|
|
|
720
|
|
|
$this->View()->sBasket = $this->getBasket(); |
721
|
|
|
|
722
|
|
|
$this->View()->sLaststock = $this->basket->sCheckBasketQuantities(); |
723
|
|
|
$this->View()->sShippingcosts = $this->View()->sBasket['sShippingcosts']; |
724
|
|
|
$this->View()->sShippingcostsDifference = $this->View()->sBasket['sShippingcostsDifference']; |
725
|
|
|
$this->View()->sAmount = $this->View()->sBasket['sAmount']; |
726
|
|
|
$this->View()->sAmountWithTax = $this->View()->sBasket['sAmountWithTax']; |
727
|
|
|
$this->View()->sAmountTax = $this->View()->sBasket['sAmountTax']; |
728
|
|
|
$this->View()->sAmountNet = $this->View()->sBasket['AmountNetNumeric']; |
729
|
|
|
$this->View()->sRegisterFinished = !empty($this->session['sRegisterFinished']); |
730
|
|
|
$this->View()->sTargetAction = 'shippingPayment'; |
731
|
|
|
|
732
|
|
|
if ($this->Request()->getParam('isXHR')) { |
733
|
|
|
return $this->View()->loadTemplate('frontend/checkout/shipping_payment_core.tpl'); |
734
|
|
|
} |
735
|
|
|
} |
736
|
|
|
|
737
|
|
|
/** |
738
|
|
|
* Action to simultaneously save shipping and payment details |
739
|
|
|
*/ |
740
|
|
|
public function saveShippingPaymentAction() |
741
|
|
|
{ |
742
|
|
|
if (!$this->Request()->isPost()) { |
743
|
|
|
return $this->forward('shippingPayment'); |
744
|
|
|
} |
745
|
|
|
|
746
|
|
|
// Load data from request |
747
|
|
|
$dispatch = $this->Request()->getPost('sDispatch'); |
748
|
|
|
$payment = $this->Request()->getPost('payment'); |
749
|
|
|
|
750
|
|
|
// If request is ajax, we skip the validation, because the user is still editing |
751
|
|
|
if ($this->Request()->getParam('isXHR')) { |
752
|
|
|
// Save payment and shipping method data. |
753
|
|
|
$this->admin->sUpdatePayment($payment); |
754
|
|
|
$this->setDispatch($dispatch, $payment); |
755
|
|
|
|
756
|
|
|
return $this->forward('shippingPayment'); |
757
|
|
|
} |
758
|
|
|
|
759
|
|
|
$sErrorFlag = []; |
760
|
|
|
$sErrorMessages = []; |
761
|
|
|
|
762
|
|
|
if (is_null($dispatch) && Shopware()->Config()->get('premiumshippingnoorder') === true && !$this->getDispatches($payment)) { |
763
|
|
|
$sErrorFlag['sDispatch'] = true; |
764
|
|
|
$sErrorMessages[] = Shopware()->Snippets()->getNamespace('frontend/checkout/error_messages') |
765
|
|
|
->get('ShippingPaymentSelectShipping', 'Please select a shipping method'); |
766
|
|
|
} |
767
|
|
|
if (is_null($payment)) { |
768
|
|
|
$sErrorFlag['payment'] = true; |
769
|
|
|
$sErrorMessages[] = Shopware()->Snippets()->getNamespace('frontend/checkout/error_messages') |
770
|
|
|
->get('ShippingPaymentSelectPayment', 'Please select a payment method'); |
771
|
|
|
} |
772
|
|
|
|
773
|
|
|
// If any basic info is missing, return error messages |
774
|
|
|
if (!empty($sErrorFlag) || !empty($sErrorMessages)) { |
775
|
|
|
$this->View()->assign('sErrorFlag', $sErrorFlag); |
776
|
|
|
$this->View()->assign('sErrorMessages', $sErrorMessages); |
777
|
|
|
|
778
|
|
|
return $this->forward('shippingPayment'); |
779
|
|
|
} |
780
|
|
|
|
781
|
|
|
// Validate the payment details |
782
|
|
|
Shopware()->Modules()->Admin()->sSYSTEM->_POST['sPayment'] = $payment; |
|
|
|
|
783
|
|
|
$checkData = $this->admin->sValidateStep3(); |
784
|
|
|
|
785
|
|
|
// Problem with the payment details, return error |
786
|
|
|
if (!empty($checkData['checkPayment']['sErrorMessages']) || empty($checkData['sProcessed'])) { |
787
|
|
|
$this->View()->assign('sErrorFlag', $checkData['checkPayment']['sErrorFlag']); |
788
|
|
|
$this->View()->assign('sErrorMessages', $checkData['checkPayment']['sErrorMessages']); |
789
|
|
|
|
790
|
|
|
return $this->forward('shippingPayment'); |
791
|
|
|
} |
792
|
|
|
|
793
|
|
|
// Save payment method details db |
794
|
|
|
if ($checkData['sPaymentObject'] instanceof \ShopwarePlugin\PaymentMethods\Components\BasePaymentMethod) { |
795
|
|
|
$checkData['sPaymentObject']->savePaymentData(Shopware()->Session()->sUserId, $this->Request()); |
796
|
|
|
} |
797
|
|
|
|
798
|
|
|
// Save the payment info |
799
|
|
|
$previousPayment = Shopware()->Modules()->Admin()->sGetUserData(); |
800
|
|
|
$previousPayment = $previousPayment['additional']['user']['paymentID']; |
801
|
|
|
|
802
|
|
|
$previousPayment = $this->admin->sGetPaymentMeanById($previousPayment); |
803
|
|
|
if ($previousPayment['paymentTable']) { |
804
|
|
|
Shopware()->Db()->delete( |
805
|
|
|
$previousPayment['paymentTable'], |
806
|
|
|
['userID = ?' => Shopware()->Session()->sUserId] |
807
|
|
|
); |
808
|
|
|
} |
809
|
|
|
|
810
|
|
|
// Save payment and shipping method data. |
811
|
|
|
$this->admin->sUpdatePayment($payment); |
812
|
|
|
$this->setDispatch($dispatch, $payment); |
813
|
|
|
|
814
|
|
|
$this->redirect([ |
815
|
|
|
'controller' => $this->Request()->getParam('sTarget', 'checkout'), |
816
|
|
|
'action' => $this->Request()->getParam('sTargetAction', 'confirm'), |
817
|
|
|
]); |
818
|
|
|
} |
819
|
|
|
|
820
|
|
|
/** |
821
|
|
|
* Get complete user-data as an array to use in view |
822
|
|
|
* |
823
|
|
|
* @return array |
824
|
|
|
*/ |
825
|
|
|
public function getUserData() |
826
|
|
|
{ |
827
|
|
|
$system = Shopware()->System(); |
|
|
|
|
828
|
|
|
$userData = $this->admin->sGetUserData(); |
829
|
|
|
if (!empty($userData['additional']['countryShipping'])) { |
830
|
|
|
$system->sUSERGROUPDATA = Shopware()->Db()->fetchRow(' |
831
|
|
|
SELECT * FROM s_core_customergroups |
832
|
|
|
WHERE groupkey = ? |
833
|
|
|
', [$system->sUSERGROUP]); |
834
|
|
|
|
835
|
|
|
$taxFree = $this->isTaxFreeDelivery($userData); |
836
|
|
|
$this->session->offsetSet('taxFree', $taxFree); |
837
|
|
|
|
838
|
|
|
if ($taxFree) { |
839
|
|
|
$system->sUSERGROUPDATA['tax'] = 0; |
840
|
|
|
$system->sCONFIG['sARTICLESOUTPUTNETTO'] = 1; //Old template |
|
|
|
|
841
|
|
|
Shopware()->Session()->sUserGroupData = $system->sUSERGROUPDATA; |
842
|
|
|
$userData['additional']['charge_vat'] = false; |
843
|
|
|
$userData['additional']['show_net'] = false; |
844
|
|
|
Shopware()->Session()->sOutputNet = true; |
845
|
|
|
} else { |
846
|
|
|
$userData['additional']['charge_vat'] = true; |
847
|
|
|
$userData['additional']['show_net'] = !empty($system->sUSERGROUPDATA['tax']); |
848
|
|
|
Shopware()->Session()->sOutputNet = empty($system->sUSERGROUPDATA['tax']); |
849
|
|
|
} |
850
|
|
|
} |
851
|
|
|
|
852
|
|
|
return $userData; |
853
|
|
|
} |
854
|
|
|
|
855
|
|
|
/** |
856
|
|
|
* Create temporary order in s_order_basket on confirm page |
857
|
|
|
* Used to track failed / aborted orders |
858
|
|
|
*/ |
859
|
|
|
public function saveTemporaryOrder() |
860
|
|
|
{ |
861
|
|
|
$order = Shopware()->Modules()->Order(); |
862
|
|
|
|
863
|
|
|
$orgBasketData = $this->View()->sBasket; |
864
|
|
|
$this->View()->sBasket = $this->getBasket(false); |
865
|
|
|
|
866
|
|
|
$order->sUserData = $this->View()->sUserData; |
867
|
|
|
$order->sComment = isset($this->session['sComment']) ? $this->session['sComment'] : ''; |
868
|
|
|
$order->sBasketData = $this->View()->sBasket; |
869
|
|
|
$order->sAmount = $this->View()->sBasket['sAmount']; |
870
|
|
|
$order->sAmountWithTax = !empty($this->View()->sBasket['AmountWithTaxNumeric']) ? $this->View()->sBasket['AmountWithTaxNumeric'] : $this->View()->sBasket['AmountNumeric']; |
871
|
|
|
$order->sAmountNet = $this->View()->sBasket['AmountNetNumeric']; |
872
|
|
|
$order->sShippingcosts = $this->View()->sBasket['sShippingcosts']; |
873
|
|
|
$order->sShippingcostsNumeric = $this->View()->sBasket['sShippingcostsWithTax']; |
874
|
|
|
$order->sShippingcostsNumericNet = $this->View()->sBasket['sShippingcostsNet']; |
875
|
|
|
$order->dispatchId = $this->session['sDispatch']; |
876
|
|
|
$order->sNet = !$this->View()->sUserData['additional']['charge_vat']; |
877
|
|
|
$order->deviceType = $this->Request()->getDeviceType(); |
878
|
|
|
|
879
|
|
|
$this->View()->sBasket = $orgBasketData; |
880
|
|
|
|
881
|
|
|
$order->sDeleteTemporaryOrder(); // Delete previous temporary orders |
882
|
|
|
$order->sCreateTemporaryOrder(); // Create new temporary order |
883
|
|
|
} |
884
|
|
|
|
885
|
|
|
/** |
886
|
|
|
* Finish order - set some object properties to do this |
887
|
|
|
*/ |
888
|
|
|
public function saveOrder() |
889
|
|
|
{ |
890
|
|
|
$order = Shopware()->Modules()->Order(); |
891
|
|
|
|
892
|
|
|
$orgBasketData = $this->View()->sBasket; |
893
|
|
|
$this->View()->sBasket = $this->getBasket(false); |
894
|
|
|
|
895
|
|
|
$order->sUserData = $this->View()->sUserData; |
896
|
|
|
$order->sComment = isset($this->session['sComment']) ? $this->session['sComment'] : ''; |
897
|
|
|
$order->sBasketData = $this->View()->sBasket; |
898
|
|
|
$order->sAmount = $this->View()->sBasket['sAmount']; |
899
|
|
|
$order->sAmountWithTax = !empty($this->View()->sBasket['AmountWithTaxNumeric']) ? $this->View()->sBasket['AmountWithTaxNumeric'] : $this->View()->sBasket['AmountNumeric']; |
900
|
|
|
$order->sAmountNet = $this->View()->sBasket['AmountNetNumeric']; |
901
|
|
|
$order->sShippingcosts = $this->View()->sBasket['sShippingcosts']; |
902
|
|
|
$order->sShippingcostsNumeric = $this->View()->sBasket['sShippingcostsWithTax']; |
903
|
|
|
$order->sShippingcostsNumericNet = $this->View()->sBasket['sShippingcostsNet']; |
904
|
|
|
$order->dispatchId = $this->session['sDispatch']; |
905
|
|
|
$order->sNet = !$this->View()->sUserData['additional']['charge_vat']; |
906
|
|
|
$order->deviceType = $this->Request()->getDeviceType(); |
907
|
|
|
|
908
|
|
|
$this->View()->sBasket = $orgBasketData; |
909
|
|
|
|
910
|
|
|
return $order->sSaveOrder(); |
911
|
|
|
} |
912
|
|
|
|
913
|
|
|
/** |
914
|
|
|
* Used in ajax add cart action |
915
|
|
|
* Check availability of product and return info / error - messages |
916
|
|
|
* |
917
|
|
|
* @param string $orderNumber article order number |
918
|
|
|
* @param int $quantity quantity |
919
|
|
|
* |
920
|
|
|
* @return string|null |
921
|
|
|
*/ |
922
|
|
|
public function getInstockInfo($orderNumber, $quantity) |
923
|
|
|
{ |
924
|
|
|
if (empty($orderNumber)) { |
925
|
|
|
return Shopware()->Snippets()->getNamespace('frontend')->get('CheckoutSelectVariant', |
926
|
|
|
'Please select an option to place the required product in the cart', true); |
927
|
|
|
} |
928
|
|
|
|
929
|
|
|
$quantity = max(1, (int) $quantity); |
930
|
|
|
$inStock = $this->getAvailableStock($orderNumber); |
931
|
|
|
$inStock['quantity'] += $quantity; |
932
|
|
|
|
933
|
|
|
if (empty($inStock['articleID'])) { |
934
|
|
|
return Shopware()->Snippets()->getNamespace('frontend')->get('CheckoutArticleNotFound', |
935
|
|
|
'Product could not be found.', true); |
936
|
|
|
} |
937
|
|
|
if (!empty($inStock['laststock']) || !empty(Shopware()->Config()->InstockInfo)) { |
|
|
|
|
938
|
|
|
if ($inStock['instock'] <= 0 && !empty($inStock['laststock'])) { |
939
|
|
|
return Shopware()->Snippets()->getNamespace('frontend')->get('CheckoutArticleNoStock', |
940
|
|
|
'Unfortunately we can not deliver the desired product in sufficient quantity', true); |
941
|
|
|
} elseif ($inStock['instock'] < $inStock['quantity']) { |
942
|
|
|
$result = 'Unfortunately we can not deliver the desired product in sufficient quantity. (#0 of #1 in stock).'; |
943
|
|
|
$result = Shopware()->Snippets()->getNamespace('frontend')->get('CheckoutArticleLessStock', $result, |
944
|
|
|
true); |
945
|
|
|
|
946
|
|
|
return str_replace(['#0', '#1'], [$inStock['instock'], $inStock['quantity']], $result); |
947
|
|
|
} |
948
|
|
|
} |
949
|
|
|
|
950
|
|
|
return null; |
951
|
|
|
} |
952
|
|
|
|
953
|
|
|
/** |
954
|
|
|
* Get current stock from a certain product defined by $ordernumber |
955
|
|
|
* Support for multidimensional variants |
956
|
|
|
* |
957
|
|
|
* @param unknown_type $ordernumber |
958
|
|
|
* |
959
|
|
|
* @return array with article id / current basket quantity / instock / laststock |
960
|
|
|
*/ |
961
|
|
|
public function getAvailableStock($ordernumber) |
962
|
|
|
{ |
963
|
|
|
$sql = ' |
964
|
|
|
SELECT |
965
|
|
|
a.id as articleID, |
966
|
|
|
ob.quantity, |
967
|
|
|
IF(ad.instock < 0, 0, ad.instock) as instock, |
968
|
|
|
a.laststock, |
969
|
|
|
ad.ordernumber as ordernumber |
970
|
|
|
FROM s_articles a |
971
|
|
|
LEFT JOIN s_articles_details ad |
972
|
|
|
ON ad.ordernumber=? |
973
|
|
|
LEFT JOIN s_order_basket ob |
974
|
|
|
ON ob.sessionID=? |
975
|
|
|
AND ob.ordernumber=ad.ordernumber |
976
|
|
|
AND ob.modus=0 |
977
|
|
|
WHERE a.id=ad.articleID |
978
|
|
|
'; |
979
|
|
|
$row = Shopware()->Db()->fetchRow($sql, [ |
980
|
|
|
$ordernumber, |
981
|
|
|
Shopware()->Session()->get('sessionId'), |
982
|
|
|
]); |
983
|
|
|
|
984
|
|
|
return $row; |
985
|
|
|
} |
986
|
|
|
|
987
|
|
|
/** |
988
|
|
|
* Get shipping costs as an array (brutto / netto) depending on selected country / payment |
989
|
|
|
* |
990
|
|
|
* @return array |
991
|
|
|
*/ |
992
|
|
|
public function getShippingCosts() |
993
|
|
|
{ |
994
|
|
|
$country = $this->getSelectedCountry(); |
995
|
|
|
$payment = $this->getSelectedPayment(); |
996
|
|
|
if (empty($country) || empty($payment)) { |
997
|
|
|
return ['brutto' => 0, 'netto' => 0]; |
998
|
|
|
} |
999
|
|
|
$shippingcosts = $this->admin->sGetPremiumShippingcosts($country); |
1000
|
|
|
|
1001
|
|
|
return empty($shippingcosts) ? ['brutto' => 0, 'netto' => 0] : $shippingcosts; |
1002
|
|
|
} |
1003
|
|
|
|
1004
|
|
|
/** |
1005
|
|
|
* Return complete basket data to view |
1006
|
|
|
* Basket items / Shippingcosts / Amounts / Tax-Rates |
1007
|
|
|
* |
1008
|
|
|
* @param bool $mergeProportional |
1009
|
|
|
* |
1010
|
|
|
* @return array |
1011
|
|
|
*/ |
1012
|
|
|
public function getBasket($mergeProportional = true) |
1013
|
|
|
{ |
1014
|
|
|
$shippingcosts = $this->getShippingCosts(); |
1015
|
|
|
|
1016
|
|
|
$basket = $this->basket->sGetBasket(); |
1017
|
|
|
|
1018
|
|
|
/** @var \Shopware\Models\Shop\Currency $currency */ |
1019
|
|
|
$currency = $this->get('shop')->getCurrency(); |
1020
|
|
|
|
1021
|
|
|
$positions = $this->container->get('shopware.cart.basket_helper')->getPositionPrices(); |
1022
|
|
|
$taxCalculator = $this->container->get('shopware.cart.proportional_tax_calculator'); |
1023
|
|
|
$hasDifferentTaxes = $taxCalculator->hasDifferentTaxes($positions); |
1024
|
|
|
|
1025
|
|
|
$basket['sCurrencyId'] = $currency->getId(); |
1026
|
|
|
$basket['sCurrencyName'] = $currency->getCurrency(); |
1027
|
|
|
$basket['sCurrencyFactor'] = $currency->getFactor(); |
1028
|
|
|
|
1029
|
|
|
if ($hasDifferentTaxes && empty($shippingcosts['taxMode']) && $this->get('config')->get('proportionalTaxCalculation') && !$this->session->get('taxFree')) { |
1030
|
|
|
$taxProportional = $taxCalculator->calculate($shippingcosts['brutto'], $positions, !Shopware()->System()->sUSERGROUPDATA['tax'] && Shopware()->System()->sUSERGROUPDATA['id']); |
|
|
|
|
1031
|
|
|
|
1032
|
|
|
$basket['sShippingcostsTaxProportional'] = $taxProportional; |
1033
|
|
|
|
1034
|
|
|
$shippingNet = 0; |
1035
|
|
|
|
1036
|
|
|
foreach ($taxProportional as $shippingProportional) { |
1037
|
|
|
$shippingNet += $shippingProportional->getNetPrice(); |
1038
|
|
|
} |
1039
|
|
|
|
1040
|
|
|
$basket['sShippingcostsWithTax'] = $shippingcosts['brutto']; |
1041
|
|
|
$basket['sShippingcostsNet'] = $shippingNet; |
1042
|
|
|
$basket['sShippingcostsTax'] = $shippingcosts['tax']; |
1043
|
|
|
|
1044
|
|
|
$shippingcosts['netto'] = $shippingNet; |
1045
|
|
|
} else { |
1046
|
|
|
$basket['sShippingcostsWithTax'] = $shippingcosts['brutto']; |
1047
|
|
|
$basket['sShippingcostsNet'] = $shippingcosts['netto']; |
1048
|
|
|
$basket['sShippingcostsTax'] = $shippingcosts['tax']; |
1049
|
|
|
} |
1050
|
|
|
|
1051
|
|
|
if (!empty($shippingcosts['brutto'])) { |
1052
|
|
|
$basket['AmountNetNumeric'] += $shippingcosts['netto']; |
1053
|
|
|
$basket['AmountNumeric'] += $shippingcosts['brutto']; |
1054
|
|
|
$basket['sShippingcostsDifference'] = $shippingcosts['difference']['float']; |
1055
|
|
|
} |
1056
|
|
|
if (!empty($basket['AmountWithTaxNumeric'])) { |
1057
|
|
|
$basket['AmountWithTaxNumeric'] += $shippingcosts['brutto']; |
1058
|
|
|
} |
1059
|
|
|
if (!Shopware()->System()->sUSERGROUPDATA['tax'] && Shopware()->System()->sUSERGROUPDATA['id']) { |
|
|
|
|
1060
|
|
|
$basket['sTaxRates'] = $this->getTaxRates($basket); |
1061
|
|
|
|
1062
|
|
|
$basket['sShippingcosts'] = $shippingcosts['netto']; |
1063
|
|
|
$basket['sAmount'] = round($basket['AmountNetNumeric'], 2); |
1064
|
|
|
$basket['sAmountTax'] = round($basket['AmountWithTaxNumeric'] - $basket['AmountNetNumeric'], 2); |
1065
|
|
|
$basket['sAmountWithTax'] = round($basket['AmountWithTaxNumeric'], 2); |
1066
|
|
|
} else { |
1067
|
|
|
$basket['sTaxRates'] = $this->getTaxRates($basket); |
1068
|
|
|
|
1069
|
|
|
$basket['sShippingcosts'] = $shippingcosts['brutto']; |
1070
|
|
|
$basket['sAmount'] = $basket['AmountNumeric']; |
1071
|
|
|
|
1072
|
|
|
$basket['sAmountTax'] = round($basket['AmountNumeric'] - $basket['AmountNetNumeric'], 2); |
1073
|
|
|
} |
1074
|
|
|
|
1075
|
|
|
$this->View()->sBasketProportional = $basket; |
1076
|
|
|
if ($mergeProportional && $hasDifferentTaxes && $this->get('config')->get('proportionalTaxCalculation')) { |
1077
|
|
|
$basket['content'] = $this->mergeProportionalItems($basket['content']); |
1078
|
|
|
} |
1079
|
|
|
|
1080
|
|
|
return $basket; |
1081
|
|
|
} |
1082
|
|
|
|
1083
|
|
|
/** |
1084
|
|
|
* Merges proportional cart items into one |
1085
|
|
|
* @param array $content |
1086
|
|
|
* @return array |
1087
|
|
|
*/ |
1088
|
|
|
private function mergeProportionalItems(array $content) |
1089
|
|
|
{ |
1090
|
|
|
$newCart = []; |
1091
|
|
|
|
1092
|
|
|
foreach ($content as $cartItem) { |
1093
|
|
|
if (!isset($newCart[$cartItem['ordernumber']])) { |
1094
|
|
|
$newCart[$cartItem['ordernumber']] = $cartItem; |
1095
|
|
|
continue; |
1096
|
|
|
} |
1097
|
|
|
|
1098
|
|
|
// There are some plugins, which allows to have same product multiple times in cart |
1099
|
|
|
if (empty($newCart[$cartItem['ordernumber']]['modus'])) { |
1100
|
|
|
$newCart[] = $cartItem; |
1101
|
|
|
continue; |
1102
|
|
|
} |
1103
|
|
|
|
1104
|
|
|
if (!isset($newCart[$cartItem['ordernumber']]['fixedName'])) { |
1105
|
|
|
$newCart[$cartItem['ordernumber']]['articlename'] = substr($newCart[$cartItem['ordernumber']]['articlename'], 0, strrpos($newCart[$cartItem['ordernumber']]['articlename'], ' ')); |
1106
|
|
|
} |
1107
|
|
|
|
1108
|
|
|
$newCart[$cartItem['ordernumber']]['price'] = $this->mergeAmount($newCart[$cartItem['ordernumber']], $cartItem, 'price'); |
1109
|
|
|
$newCart[$cartItem['ordernumber']]['netprice'] = $this->mergeAmount($newCart[$cartItem['ordernumber']], $cartItem, 'netprice'); |
1110
|
|
|
$newCart[$cartItem['ordernumber']]['amountWithTax'] = $this->mergeAmount($newCart[$cartItem['ordernumber']], $cartItem, 'amountWithTax'); |
1111
|
|
|
$newCart[$cartItem['ordernumber']]['amount'] = $this->mergeAmount($newCart[$cartItem['ordernumber']], $cartItem, 'amount'); |
1112
|
|
|
$newCart[$cartItem['ordernumber']]['amountnet'] = $this->mergeAmount($newCart[$cartItem['ordernumber']], $cartItem, 'amountnet'); |
1113
|
|
|
$newCart[$cartItem['ordernumber']]['priceNumeric'] = $this->mergeAmount($newCart[$cartItem['ordernumber']], $cartItem, 'priceNumeric'); |
1114
|
|
|
$newCart[$cartItem['ordernumber']]['tax'] = $this->mergeAmount($newCart[$cartItem['ordernumber']], $cartItem, 'tax'); |
1115
|
|
|
} |
1116
|
|
|
|
1117
|
|
|
return array_values($newCart); |
1118
|
|
|
} |
1119
|
|
|
|
1120
|
|
|
/** |
1121
|
|
|
* @param array $item1 |
1122
|
|
|
* @param array $item2 |
1123
|
|
|
* @param string $property |
1124
|
|
|
* @return string |
1125
|
|
|
*/ |
1126
|
|
|
private function mergeAmount(array $item1, array $item2, $property) |
1127
|
|
|
{ |
1128
|
|
|
$hasComma = strpos($item1[$property], ',') !== false; |
1129
|
|
|
$amount = str_replace(',', '.', $item1[$property]) + str_replace(',', '.', $item2[$property]); |
1130
|
|
|
|
1131
|
|
|
if ($hasComma) { |
1132
|
|
|
$amount = Shopware()->Modules()->Articles()->sFormatPrice($amount); |
1133
|
|
|
} |
1134
|
|
|
|
1135
|
|
|
return $amount; |
1136
|
|
|
} |
1137
|
|
|
|
1138
|
|
|
/** |
1139
|
|
|
* Returns tax rates for all basket positions |
1140
|
|
|
* |
1141
|
|
|
* @param array $basket array returned from this->getBasket |
1142
|
|
|
* |
1143
|
|
|
* @return array |
1144
|
|
|
*/ |
1145
|
|
|
public function getTaxRates($basket) |
1146
|
|
|
{ |
1147
|
|
|
$result = []; |
1148
|
|
|
|
1149
|
|
|
if (!empty($basket['sShippingcostsTax'])) { |
1150
|
|
|
if (!empty($basket['sShippingcostsTaxProportional'])) { |
1151
|
|
|
/** @var \Shopware\Components\Cart\Struct\Price $shippingTax */ |
1152
|
|
|
foreach ($basket['sShippingcostsTaxProportional'] as $shippingTax) { |
1153
|
|
|
$result[number_format($shippingTax->getTaxRate(), 2)] += $shippingTax->getTax(); |
1154
|
|
|
} |
1155
|
|
|
} else { |
1156
|
|
|
$basket['sShippingcostsTax'] = number_format((float) $basket['sShippingcostsTax'], 2); |
1157
|
|
|
|
1158
|
|
|
$result[$basket['sShippingcostsTax']] = $basket['sShippingcostsWithTax'] - $basket['sShippingcostsNet']; |
1159
|
|
|
if (empty($result[$basket['sShippingcostsTax']])) { |
1160
|
|
|
unset($result[$basket['sShippingcostsTax']]); |
1161
|
|
|
} |
1162
|
|
|
} |
1163
|
|
|
} |
1164
|
|
|
|
1165
|
|
|
if (empty($basket['content'])) { |
1166
|
|
|
ksort($result, SORT_NUMERIC); |
1167
|
|
|
|
1168
|
|
|
return $result; |
1169
|
|
|
} |
1170
|
|
|
|
1171
|
|
|
foreach ($basket['content'] as $item) { |
1172
|
|
|
if (!empty($item['tax_rate'])) { |
|
|
|
|
1173
|
|
|
} elseif (!empty($item['taxPercent'])) { |
1174
|
|
|
$item['tax_rate'] = $item['taxPercent']; |
1175
|
|
|
} elseif ($item['modus'] == 2) { |
1176
|
|
|
// Ticket 4842 - dynamic tax-rates |
1177
|
|
|
$resultVoucherTaxMode = Shopware()->Db()->fetchOne( |
1178
|
|
|
'SELECT taxconfig FROM s_emarketing_vouchers WHERE ordercode=? |
1179
|
|
|
', [$item['ordernumber']]); |
1180
|
|
|
// Old behaviour |
1181
|
|
|
if (empty($resultVoucherTaxMode) || $resultVoucherTaxMode === 'default') { |
1182
|
|
|
$tax = Shopware()->Config()->get('sVOUCHERTAX'); |
1183
|
|
|
} elseif ($resultVoucherTaxMode === 'auto') { |
1184
|
|
|
// Automatically determinate tax |
1185
|
|
|
$tax = $this->basket->getMaxTax(); |
1186
|
|
|
} elseif ($resultVoucherTaxMode === 'none') { |
1187
|
|
|
// No tax |
1188
|
|
|
$tax = '0'; |
1189
|
|
|
} elseif ((int) $resultVoucherTaxMode) { |
1190
|
|
|
// Fix defined tax |
1191
|
|
|
$tax = Shopware()->Db()->fetchOne(' |
1192
|
|
|
SELECT tax FROM s_core_tax WHERE id = ? |
1193
|
|
|
', [$resultVoucherTaxMode]); |
1194
|
|
|
} |
1195
|
|
|
$item['tax_rate'] = $tax; |
1196
|
|
|
} else { |
1197
|
|
|
// Ticket 4842 - dynamic tax-rates |
1198
|
|
|
$taxAutoMode = Shopware()->Config()->get('sTAXAUTOMODE'); |
1199
|
|
|
if (!empty($taxAutoMode)) { |
1200
|
|
|
$tax = $this->basket->getMaxTax(); |
1201
|
|
|
} else { |
1202
|
|
|
$tax = Shopware()->Config()->get('sDISCOUNTTAX'); |
1203
|
|
|
} |
1204
|
|
|
$item['tax_rate'] = $tax; |
1205
|
|
|
} |
1206
|
|
|
|
1207
|
|
|
if (empty($item['tax_rate']) || empty($item['tax'])) { |
1208
|
|
|
continue; |
1209
|
|
|
} // Ignore 0 % tax |
1210
|
|
|
|
1211
|
|
|
$taxKey = number_format((float) $item['tax_rate'], 2); |
1212
|
|
|
|
1213
|
|
|
$result[$taxKey] += str_replace(',', '.', $item['tax']); |
1214
|
|
|
} |
1215
|
|
|
|
1216
|
|
|
ksort($result, SORT_NUMERIC); |
1217
|
|
|
|
1218
|
|
|
return $result; |
1219
|
|
|
} |
1220
|
|
|
|
1221
|
|
|
/** |
1222
|
|
|
* Get similar shown products to display in ajax add dialog |
1223
|
|
|
* |
1224
|
|
|
* @param int $articleID |
1225
|
|
|
* |
1226
|
|
|
* @return array |
1227
|
|
|
*/ |
1228
|
|
|
public function getSimilarShown($articleID) |
1229
|
|
|
{ |
1230
|
|
|
Shopware()->Modules()->Marketing()->sBlacklist = $this->basket->sGetBasketIds(); |
|
|
|
|
1231
|
|
|
|
1232
|
|
|
$similarId = Shopware()->Modules()->Marketing()->sGetSimilaryShownArticles($articleID); |
1233
|
|
|
|
1234
|
|
|
$similars = []; |
1235
|
|
|
if (!empty($similarId)) { |
1236
|
|
|
foreach ($similarId as $similarID) { |
1237
|
|
|
$temp = Shopware()->Modules()->Articles()->sGetPromotionById('fix', 0, (int) $similarID['id']); |
1238
|
|
|
if (!empty($temp)) { |
1239
|
|
|
$similars[] = $temp; |
1240
|
|
|
} |
1241
|
|
|
} |
1242
|
|
|
} |
1243
|
|
|
|
1244
|
|
|
return $similars; |
1245
|
|
|
} |
1246
|
|
|
|
1247
|
|
|
/** |
1248
|
|
|
* Get articles that bought in combination with last added product to |
1249
|
|
|
* display on cart page |
1250
|
|
|
* |
1251
|
|
|
* @param int $articleID |
1252
|
|
|
* |
1253
|
|
|
* @return array |
1254
|
|
|
*/ |
1255
|
|
|
public function getBoughtToo($articleID) |
1256
|
|
|
{ |
1257
|
|
|
Shopware()->Modules()->Marketing()->sBlacklist = $this->basket->sGetBasketIds(); |
|
|
|
|
1258
|
|
|
|
1259
|
|
|
$alsoBoughtId = Shopware()->Modules()->Marketing()->sGetAlsoBoughtArticles($articleID); |
1260
|
|
|
$alsoBoughts = []; |
1261
|
|
|
if (!empty($alsoBoughtId)) { |
1262
|
|
|
foreach ($alsoBoughtId as $alsoBoughtItem) { |
1263
|
|
|
$temp = Shopware()->Modules()->Articles()->sGetPromotionById('fix', 0, (int) $alsoBoughtItem['id']); |
1264
|
|
|
if (!empty($temp)) { |
1265
|
|
|
$alsoBoughts[] = $temp; |
1266
|
|
|
} |
1267
|
|
|
} |
1268
|
|
|
} |
1269
|
|
|
|
1270
|
|
|
return $alsoBoughts; |
1271
|
|
|
} |
1272
|
|
|
|
1273
|
|
|
/** |
1274
|
|
|
* Get configured minimum charge to check in order processing |
1275
|
|
|
* |
1276
|
|
|
* @return bool |
1277
|
|
|
*/ |
1278
|
|
|
public function getMinimumCharge() |
1279
|
|
|
{ |
1280
|
|
|
return $this->basket->sCheckMinimumCharge(); |
1281
|
|
|
} |
1282
|
|
|
|
1283
|
|
|
/** |
1284
|
|
|
* Check if order is possible under current conditions (dispatch) |
1285
|
|
|
* |
1286
|
|
|
* @return bool |
1287
|
|
|
*/ |
1288
|
|
|
public function getDispatchNoOrder() |
1289
|
|
|
{ |
1290
|
|
|
return !empty(Shopware()->Config()->PremiumShippingNoOrder) && (empty($this->session['sDispatch']) || empty($this->session['sCountry'])); |
|
|
|
|
1291
|
|
|
} |
1292
|
|
|
|
1293
|
|
|
/** |
1294
|
|
|
* Get all premium products that are configured and available for this order |
1295
|
|
|
* |
1296
|
|
|
* @return array |
1297
|
|
|
*/ |
1298
|
|
|
public function getPremiums() |
1299
|
|
|
{ |
1300
|
|
|
$sql = 'SELECT `id` FROM `s_order_basket` WHERE `sessionID`=? AND `modus`=1'; |
1301
|
|
|
$result = Shopware()->Db()->fetchOne($sql, [Shopware()->Session()->get('sessionId')]); |
1302
|
|
|
if (!empty($result)) { |
1303
|
|
|
return []; |
1304
|
|
|
} |
1305
|
|
|
|
1306
|
|
|
return Shopware()->Modules()->Marketing()->sGetPremiums(); |
1307
|
|
|
} |
1308
|
|
|
|
1309
|
|
|
/** |
1310
|
|
|
* Check if any electronically distribution product is in basket |
1311
|
|
|
* |
1312
|
|
|
* @return bool |
1313
|
|
|
*/ |
1314
|
|
|
public function getEsdNote() |
1315
|
|
|
{ |
1316
|
|
|
$payment = empty($this->View()->sUserData['additional']['payment']) ? $this->session['sOrderVariables']['sUserData']['additional']['payment'] : $this->View()->sUserData['additional']['payment']; |
1317
|
|
|
|
1318
|
|
|
return $this->basket->sCheckForESD() && !$payment['esdactive']; |
1319
|
|
|
} |
1320
|
|
|
|
1321
|
|
|
/** |
1322
|
|
|
* Check if a custom inquiry possibility should displayed on cart page |
1323
|
|
|
* Compare configured inquirevalue with current amount |
1324
|
|
|
* |
1325
|
|
|
* @return bool |
1326
|
|
|
*/ |
1327
|
|
|
public function getInquiry() |
1328
|
|
|
{ |
1329
|
|
|
if (Shopware()->Config()->get('sINQUIRYVALUE')) { |
1330
|
|
|
$factor = Shopware()->System()->sCurrency['factor'] ? 1 : Shopware()->System()->sCurrency['factor']; |
|
|
|
|
1331
|
|
|
$value = Shopware()->Config()->get('sINQUIRYVALUE') * $factor; |
1332
|
|
|
if ((!Shopware()->System()->sUSERGROUPDATA['tax'] && Shopware()->System()->sUSERGROUPDATA['id'])) { |
|
|
|
|
1333
|
|
|
$amount = $this->View()->sBasket['AmountWithTaxNumeric']; |
1334
|
|
|
} else { |
1335
|
|
|
$amount = $this->View()->sBasket['AmountNumeric']; |
1336
|
|
|
} |
1337
|
|
|
if (!empty($amount) && $amount >= $value) { |
1338
|
|
|
return true; |
1339
|
|
|
} |
1340
|
|
|
} |
1341
|
|
|
|
1342
|
|
|
return false; |
1343
|
|
|
} |
1344
|
|
|
|
1345
|
|
|
/** |
1346
|
|
|
* Get link to inquiry form if getInquiry returend true |
1347
|
|
|
* |
1348
|
|
|
* @return string |
1349
|
|
|
*/ |
1350
|
|
|
public function getInquiryLink() |
1351
|
|
|
{ |
1352
|
|
|
return Shopware()->Config()->get('sBASEFILE') . '?sViewport=support&sFid=' . Shopware()->Config()->get('sINQUIRYID') . '&sInquiry=basket'; |
1353
|
|
|
} |
1354
|
|
|
|
1355
|
|
|
/** |
1356
|
|
|
* Get all countries from database via sAdmin object |
1357
|
|
|
* |
1358
|
|
|
* @return array list of countries |
1359
|
|
|
*/ |
1360
|
|
|
public function getCountryList() |
1361
|
|
|
{ |
1362
|
|
|
return $this->admin->sGetCountryList(); |
1363
|
|
|
} |
1364
|
|
|
|
1365
|
|
|
/** |
1366
|
|
|
* Get all dispatches available in selected country from sAdmin object |
1367
|
|
|
* |
1368
|
|
|
* @param null $paymentId |
1369
|
|
|
* |
1370
|
|
|
* @return array list of dispatches |
1371
|
|
|
*/ |
1372
|
|
|
public function getDispatches($paymentId = null) |
1373
|
|
|
{ |
1374
|
|
|
$country = $this->getSelectedCountry(); |
1375
|
|
|
$state = $this->getSelectedState(); |
1376
|
|
|
if (empty($country)) { |
1377
|
|
|
return false; |
1378
|
|
|
} |
1379
|
|
|
$stateId = !empty($state['id']) ? $state['id'] : null; |
1380
|
|
|
|
1381
|
|
|
return $this->admin->sGetPremiumDispatches($country['id'], $paymentId, $stateId); |
1382
|
|
|
} |
1383
|
|
|
|
1384
|
|
|
/** |
1385
|
|
|
* Returns all available payment methods from sAdmin object |
1386
|
|
|
* |
1387
|
|
|
* @return array list of payment methods |
1388
|
|
|
*/ |
1389
|
|
|
public function getPayments() |
1390
|
|
|
{ |
1391
|
|
|
return $this->admin->sGetPaymentMeans(); |
1392
|
|
|
} |
1393
|
|
|
|
1394
|
|
|
/** |
1395
|
|
|
* Get current selected country - if no country is selected, choose first one from list |
1396
|
|
|
* of available countries |
1397
|
|
|
* |
1398
|
|
|
* @return array with country information |
1399
|
|
|
*/ |
1400
|
|
|
public function getSelectedCountry() |
1401
|
|
|
{ |
1402
|
|
|
if (!empty($this->View()->sUserData['additional']['countryShipping'])) { |
1403
|
|
|
$this->session['sCountry'] = (int) $this->View()->sUserData['additional']['countryShipping']['id']; |
1404
|
|
|
$this->session['sArea'] = (int) $this->View()->sUserData['additional']['countryShipping']['areaID']; |
1405
|
|
|
|
1406
|
|
|
return $this->View()->sUserData['additional']['countryShipping']; |
1407
|
|
|
} |
1408
|
|
|
$countries = $this->getCountryList(); |
1409
|
|
|
if (empty($countries)) { |
1410
|
|
|
unset($this->session['sCountry']); |
1411
|
|
|
|
1412
|
|
|
return false; |
|
|
|
|
1413
|
|
|
} |
1414
|
|
|
$country = reset($countries); |
1415
|
|
|
$this->session['sCountry'] = (int) $country['id']; |
1416
|
|
|
$this->session['sArea'] = (int) $country['areaID']; |
1417
|
|
|
$this->View()->sUserData['additional']['countryShipping'] = $country; |
1418
|
|
|
|
1419
|
|
|
return $country; |
1420
|
|
|
} |
1421
|
|
|
|
1422
|
|
|
/** |
1423
|
|
|
* Get current selected country - if no country is selected, choose first one from list |
1424
|
|
|
* of available countries |
1425
|
|
|
* |
1426
|
|
|
* @return array with country information |
1427
|
|
|
*/ |
1428
|
|
|
public function getSelectedState() |
1429
|
|
|
{ |
1430
|
|
|
if (!empty($this->View()->sUserData['additional']['stateShipping'])) { |
1431
|
|
|
$this->session['sState'] = (int) $this->View()->sUserData['additional']['stateShipping']['id']; |
1432
|
|
|
|
1433
|
|
|
return $this->View()->sUserData['additional']['stateShipping']; |
1434
|
|
|
} |
1435
|
|
|
|
1436
|
|
|
return ['id' => $this->session['sState']]; |
1437
|
|
|
} |
1438
|
|
|
|
1439
|
|
|
/** |
1440
|
|
|
* Get selected payment or do payment mean selection automatically |
1441
|
|
|
* |
1442
|
|
|
* @return array |
1443
|
|
|
*/ |
1444
|
|
|
public function getSelectedPayment() |
1445
|
|
|
{ |
1446
|
|
|
$paymentMethods = $this->getPayments(); |
1447
|
|
|
|
1448
|
|
|
if (!empty($this->View()->sUserData['additional']['payment'])) { |
1449
|
|
|
$payment = $this->View()->sUserData['additional']['payment']; |
1450
|
|
|
} elseif (!empty($this->session['sPaymentID'])) { |
1451
|
|
|
$payment = $this->admin->sGetPaymentMeanById($this->session['sPaymentID'], $this->View()->sUserData); |
1452
|
|
|
} |
1453
|
|
|
|
1454
|
|
|
if ($payment && !$this->checkPaymentAvailability($payment, $paymentMethods)) { |
1455
|
|
|
$payment = null; |
1456
|
|
|
} |
1457
|
|
|
|
1458
|
|
|
$paymentClass = $this->admin->sInitiatePaymentClass($payment); |
1459
|
|
|
if ($payment && $paymentClass instanceof \ShopwarePlugin\PaymentMethods\Components\BasePaymentMethod) { |
1460
|
|
|
$data = $paymentClass->getCurrentPaymentDataAsArray(Shopware()->Session()->sUserId); |
1461
|
|
|
$payment['validation'] = $paymentClass->validate($data); |
|
|
|
|
1462
|
|
|
if (!empty($data)) { |
1463
|
|
|
$payment['data'] = $data; |
1464
|
|
|
} |
1465
|
|
|
} |
1466
|
|
|
|
1467
|
|
|
if (!empty($payment)) { |
1468
|
|
|
return $payment; |
1469
|
|
|
} |
1470
|
|
|
|
1471
|
|
|
if (empty($paymentMethods)) { |
1472
|
|
|
unset($this->session['sPaymentID']); |
1473
|
|
|
|
1474
|
|
|
return false; |
|
|
|
|
1475
|
|
|
} |
1476
|
|
|
|
1477
|
|
|
$payment = $this->getDefaultPaymentMethod($paymentMethods); |
1478
|
|
|
|
1479
|
|
|
$this->session['sPaymentID'] = (int) $payment['id']; |
1480
|
|
|
$this->front->Request()->setPost('sPayment', (int) $payment['id']); |
1481
|
|
|
$this->admin->sUpdatePayment(); |
1482
|
|
|
|
1483
|
|
|
//if customer logged in and payment switched to fallback, display cart notice. Otherwise anonymous customers will see the message too |
1484
|
|
|
if (Shopware()->Session()->sUserId) { |
1485
|
|
|
$this->flagPaymentBlocked(); |
1486
|
|
|
} |
1487
|
|
|
|
1488
|
|
|
return $payment; |
1489
|
|
|
} |
1490
|
|
|
|
1491
|
|
|
/** |
1492
|
|
|
* Get selected dispatch or select a default dispatch |
1493
|
|
|
* |
1494
|
|
|
* @return bool|array |
1495
|
|
|
*/ |
1496
|
|
|
public function getSelectedDispatch() |
1497
|
|
|
{ |
1498
|
|
|
if (empty($this->session['sCountry'])) { |
1499
|
|
|
return false; |
1500
|
|
|
} |
1501
|
|
|
|
1502
|
|
|
$dispatches = $this->admin->sGetPremiumDispatches($this->session['sCountry'], null, $this->session['sState']); |
1503
|
|
|
if (empty($dispatches)) { |
1504
|
|
|
unset($this->session['sDispatch']); |
1505
|
|
|
|
1506
|
|
|
return false; |
1507
|
|
|
} |
1508
|
|
|
|
1509
|
|
|
foreach ($dispatches as $dispatch) { |
1510
|
|
|
if ($dispatch['id'] == $this->session['sDispatch']) { |
1511
|
|
|
return $dispatch; |
1512
|
|
|
} |
1513
|
|
|
} |
1514
|
|
|
$dispatch = reset($dispatches); |
1515
|
|
|
$this->session['sDispatch'] = (int) $dispatch['id']; |
1516
|
|
|
|
1517
|
|
|
return $dispatch; |
1518
|
|
|
} |
1519
|
|
|
|
1520
|
|
|
/** |
1521
|
|
|
* Set the provided dispatch method |
1522
|
|
|
* |
1523
|
|
|
* @param $dispatchId $dispatchId ID of the dispatch method to set |
|
|
|
|
1524
|
|
|
* @param int|null $paymentId Payment id to validate |
1525
|
|
|
* |
1526
|
|
|
* @return int set dispatch method id |
1527
|
|
|
*/ |
1528
|
|
|
public function setDispatch($dispatchId, $paymentId = null) |
1529
|
|
|
{ |
1530
|
|
|
$supportedDispatches = $this->getDispatches($paymentId); |
1531
|
|
|
|
1532
|
|
|
// Iterate over supported dispatches, look for the provided one |
1533
|
|
|
foreach ($supportedDispatches as $dispatch) { |
|
|
|
|
1534
|
|
|
if ($dispatch['id'] == $dispatchId) { |
1535
|
|
|
$this->session['sDispatch'] = $dispatchId; |
1536
|
|
|
|
1537
|
|
|
return $dispatchId; |
1538
|
|
|
} |
1539
|
|
|
} |
1540
|
|
|
|
1541
|
|
|
// If it was not found, we fallback to the default (head of supported) |
1542
|
|
|
$defaultDispatch = array_shift($supportedDispatches); |
1543
|
|
|
$this->session['sDispatch'] = $defaultDispatch['id']; |
1544
|
|
|
|
1545
|
|
|
return $this->session['sDispatch']; |
1546
|
|
|
} |
1547
|
|
|
|
1548
|
|
|
/** |
1549
|
|
|
* Ajax add article action |
1550
|
|
|
* |
1551
|
|
|
* This action will get redirected from the default addArticleAction |
1552
|
|
|
* when the request was an AJAX request. |
1553
|
|
|
*/ |
1554
|
|
|
public function ajaxAddArticleAction() |
1555
|
|
|
{ |
1556
|
|
|
// Empty but can't be removed for legacy reasons |
1557
|
|
|
} |
1558
|
|
|
|
1559
|
|
|
/** |
1560
|
|
|
* Ajax add article cart action |
1561
|
|
|
* |
1562
|
|
|
* This action is a lightweight way to add an article by the passed |
1563
|
|
|
* article order number and quantity. |
1564
|
|
|
* |
1565
|
|
|
* The order number is expected to get passed by the 'sAdd' parameter |
1566
|
|
|
* This quantity is expected to get passed by the 'sQuantity' parameter. |
1567
|
|
|
* |
1568
|
|
|
* After the article was added to the basket, the whole cart content will be returned. |
1569
|
|
|
* |
1570
|
|
|
* @throws \LogicException |
1571
|
|
|
*/ |
1572
|
|
|
public function ajaxAddArticleCartAction() |
1573
|
|
|
{ |
1574
|
|
|
if (strtolower($this->Request()->getMethod()) !== 'post') { |
1575
|
|
|
throw new \LogicException('This action only admits post requests'); |
1576
|
|
|
} |
1577
|
|
|
|
1578
|
|
|
$orderNumber = $this->Request()->getParam('sAdd'); |
1579
|
|
|
$quantity = $this->Request()->getParam('sQuantity'); |
1580
|
|
|
|
1581
|
|
|
$this->View()->assign( |
1582
|
|
|
'basketInfoMessage', |
1583
|
|
|
$this->getInstockInfo($orderNumber, $quantity) |
1584
|
|
|
); |
1585
|
|
|
|
1586
|
|
|
if ($this->Request()->get('sAddAccessories')) { |
1587
|
|
|
$this->addAccessories( |
1588
|
|
|
$this->Request()->getParam('sAddAccessories'), |
1589
|
|
|
$this->Request()->getParam('sAddAccessoriesQuantity') |
1590
|
|
|
); |
1591
|
|
|
} |
1592
|
|
|
|
1593
|
|
|
$this->basket->sAddArticle($orderNumber, $quantity); |
1594
|
|
|
|
1595
|
|
|
$this->forward('ajaxCart'); |
1596
|
|
|
} |
1597
|
|
|
|
1598
|
|
|
/** |
1599
|
|
|
* Ajax delete article action |
1600
|
|
|
* |
1601
|
|
|
* This action is a lightweight way to delete an article by the passed |
1602
|
|
|
* basket item id. |
1603
|
|
|
* |
1604
|
|
|
* This id is expected to get passed by the 'sDelete' parameter. |
1605
|
|
|
* |
1606
|
|
|
* After the article was removed from the basket, the whole cart content will be returned. |
1607
|
|
|
*/ |
1608
|
|
|
public function ajaxDeleteArticleCartAction() |
1609
|
|
|
{ |
1610
|
|
|
if (strtolower($this->Request()->getMethod()) !== 'post') { |
1611
|
|
|
throw new \LogicException('This action only admits post requests'); |
1612
|
|
|
} |
1613
|
|
|
|
1614
|
|
|
$itemId = $this->Request()->getParam('sDelete'); |
1615
|
|
|
|
1616
|
|
|
if ($itemId) { |
1617
|
|
|
$this->basket->sDeleteArticle($itemId); |
1618
|
|
|
} |
1619
|
|
|
|
1620
|
|
|
$this->forward('ajaxCart'); |
1621
|
|
|
} |
1622
|
|
|
|
1623
|
|
|
/** |
1624
|
|
|
* Ajax cart action |
1625
|
|
|
* |
1626
|
|
|
* This action loads the cart content and returns it. |
1627
|
|
|
* Its purpose is to return all necessary information in a minimal template |
1628
|
|
|
* for a good performance so e.g. ajax requests are finished more quickly. |
1629
|
|
|
*/ |
1630
|
|
|
public function ajaxCartAction() |
1631
|
|
|
{ |
1632
|
|
|
$view = $this->View(); |
1633
|
|
|
$basket = $this->getBasket(); |
1634
|
|
|
|
1635
|
|
|
$view->sBasket = $basket; |
1636
|
|
|
|
1637
|
|
|
$view->sShippingcosts = $basket['sShippingcosts']; |
1638
|
|
|
$view->sShippingcostsDifference = $basket['sShippingcostsDifference']; |
1639
|
|
|
$view->sAmount = $basket['sAmount']; |
1640
|
|
|
$view->sAmountWithTax = $basket['sAmountWithTax']; |
1641
|
|
|
$view->sAmountTax = $basket['sAmountTax']; |
1642
|
|
|
$view->sAmountNet = $basket['AmountNetNumeric']; |
1643
|
|
|
$view->sDispatches = $this->getDispatches(); |
1644
|
|
|
$view->sDispatchNoOrder = $this->getDispatchNoOrder(); |
1645
|
|
|
} |
1646
|
|
|
|
1647
|
|
|
/** |
1648
|
|
|
* Get current amount from cart via ajax to display in realtime |
1649
|
|
|
*/ |
1650
|
|
|
public function ajaxAmountAction() |
1651
|
|
|
{ |
1652
|
|
|
$this->Response()->setHeader('Content-Type', 'application/json'); |
1653
|
|
|
|
1654
|
|
|
$amount = $this->basket->sGetAmount(); |
1655
|
|
|
$quantity = $this->basket->sCountBasket(); |
1656
|
|
|
|
1657
|
|
|
$this->View()->sBasketQuantity = $quantity; |
1658
|
|
|
$this->View()->sBasketAmount = empty($amount) ? 0 : array_shift($amount); |
1659
|
|
|
|
1660
|
|
|
$this->Front()->Plugins()->ViewRenderer()->setNoRender(); |
1661
|
|
|
|
1662
|
|
|
$this->Response()->setBody( |
1663
|
|
|
json_encode([ |
1664
|
|
|
'amount' => Shopware()->Template()->fetch('frontend/checkout/ajax_amount.tpl'), |
1665
|
|
|
'quantity' => $quantity, |
1666
|
|
|
]) |
1667
|
|
|
); |
1668
|
|
|
} |
1669
|
|
|
|
1670
|
|
|
/** |
1671
|
|
|
* Sets a temporary session variable which holds an address for the current order |
1672
|
|
|
*/ |
1673
|
|
|
public function setAddressAction() |
1674
|
|
|
{ |
1675
|
|
|
$this->Front()->Plugins()->ViewRenderer()->setNoRender(true); |
1676
|
|
|
$target = $this->Request()->getParam('target', 'shipping'); |
1677
|
|
|
$sessionKey = $target === 'shipping' ? 'checkoutShippingAddressId' : 'checkoutBillingAddressId'; |
1678
|
|
|
|
1679
|
|
|
$this->session->offsetSet($sessionKey, $this->Request()->getParam('addressId')); |
1680
|
|
|
|
1681
|
|
|
if ($target === 'both') { |
1682
|
|
|
$this->session->offsetSet('checkoutShippingAddressId', $this->Request()->getParam('addressId')); |
1683
|
|
|
$this->session->offsetSet('checkoutBillingAddressId', $this->Request()->getParam('addressId')); |
1684
|
|
|
} |
1685
|
|
|
} |
1686
|
|
|
|
1687
|
|
|
/** |
1688
|
|
|
* Validates if the provided customer should get a tax free delivery |
1689
|
|
|
* |
1690
|
|
|
* @param array $userData |
1691
|
|
|
* |
1692
|
|
|
* @return bool |
1693
|
|
|
*/ |
1694
|
|
|
protected function isTaxFreeDelivery($userData) |
1695
|
|
|
{ |
1696
|
|
|
if (!empty($userData['additional']['countryShipping']['taxfree'])) { |
1697
|
|
|
return true; |
1698
|
|
|
} |
1699
|
|
|
|
1700
|
|
|
if (empty($userData['additional']['countryShipping']['taxfree_ustid'])) { |
1701
|
|
|
return false; |
1702
|
|
|
} |
1703
|
|
|
|
1704
|
|
|
if (empty($userData['shippingaddress']['ustid']) && |
1705
|
|
|
!empty($userData['billingaddress']['ustid']) && |
1706
|
|
|
!empty($userData['additional']['country']['taxfree_ustid'])) { |
1707
|
|
|
return true; |
1708
|
|
|
} |
1709
|
|
|
|
1710
|
|
|
return !empty($userData['shippingaddress']['ustid']); |
1711
|
|
|
} |
1712
|
|
|
|
1713
|
|
|
/** |
1714
|
|
|
* @param $basket |
1715
|
|
|
* @param Request $request |
1716
|
|
|
* |
1717
|
|
|
* @throws Exception |
1718
|
|
|
* |
1719
|
|
|
* @return array |
1720
|
|
|
*/ |
1721
|
|
|
private function getInvalidAgreements($basket, Request $request) |
1722
|
|
|
{ |
1723
|
|
|
$errors = []; |
1724
|
|
|
|
1725
|
|
|
if (!$this->container->get('config')->get('IgnoreAGB') && !$this->Request()->getParam('sAGB')) { |
1726
|
|
|
$errors['agbError'] = true; |
1727
|
|
|
} |
1728
|
|
|
|
1729
|
|
|
$esdAgreement = $request->getParam('esdAgreementChecked'); |
1730
|
|
|
if ($this->container->get('config')->get('showEsdWarning') |
1731
|
|
|
&& $this->basketHasEsdArticles($basket) |
1732
|
|
|
&& empty($esdAgreement) |
1733
|
|
|
) { |
1734
|
|
|
$errors['esdError'] = true; |
1735
|
|
|
} |
1736
|
|
|
|
1737
|
|
|
$serviceChecked = $request->getParam('serviceAgreementChecked'); |
1738
|
|
|
if ($this->basketHasServiceArticles($basket) && empty($serviceChecked)) { |
1739
|
|
|
$errors['serviceError'] = true; |
1740
|
|
|
} |
1741
|
|
|
|
1742
|
|
|
return $errors; |
1743
|
|
|
} |
1744
|
|
|
|
1745
|
|
|
/** |
1746
|
|
|
* checks if the current user selected an available payment method |
1747
|
|
|
* |
1748
|
|
|
* @param array $currentPayment |
1749
|
|
|
* @param array $payments |
1750
|
|
|
* |
1751
|
|
|
* @return bool |
1752
|
|
|
*/ |
1753
|
|
|
private function checkPaymentAvailability($currentPayment, $payments) |
1754
|
|
|
{ |
1755
|
|
|
foreach ($payments as $availablePayment) { |
1756
|
|
|
if ($availablePayment['id'] === $currentPayment['id']) { |
1757
|
|
|
return true; |
1758
|
|
|
} |
1759
|
|
|
} |
1760
|
|
|
|
1761
|
|
|
return false; |
1762
|
|
|
} |
1763
|
|
|
|
1764
|
|
|
/** |
1765
|
|
|
* @param string|array $accessories |
1766
|
|
|
* @param array $quantities |
1767
|
|
|
*/ |
1768
|
|
|
private function addAccessories($accessories, $quantities) |
1769
|
|
|
{ |
1770
|
|
|
if (is_string($accessories)) { |
1771
|
|
|
$accessories = explode(';', $accessories); |
1772
|
|
|
} |
1773
|
|
|
|
1774
|
|
|
if (empty($accessories) || !is_array($accessories)) { |
1775
|
|
|
return; |
1776
|
|
|
} |
1777
|
|
|
|
1778
|
|
|
foreach ($accessories as $key => $accessory) { |
1779
|
|
|
try { |
1780
|
|
|
$quantity = 1; |
1781
|
|
|
if (!empty($quantities[$key])) { |
1782
|
|
|
$quantity = (int) $quantities[$key]; |
1783
|
|
|
} |
1784
|
|
|
|
1785
|
|
|
$this->basket->sAddArticle($accessory, $quantity); |
1786
|
|
|
} catch (Exception $e) { |
|
|
|
|
1787
|
|
|
} |
1788
|
|
|
} |
1789
|
|
|
} |
1790
|
|
|
|
1791
|
|
|
/** |
1792
|
|
|
* Helper function that checks whether or not the given basket has an esd article in it. |
1793
|
|
|
* |
1794
|
|
|
* @param array $basket |
1795
|
|
|
* |
1796
|
|
|
* @return bool |
1797
|
|
|
*/ |
1798
|
|
|
private function basketHasEsdArticles($basket) |
1799
|
|
|
{ |
1800
|
|
|
if (!isset($basket['content'])) { |
1801
|
|
|
return false; |
1802
|
|
|
} |
1803
|
|
|
|
1804
|
|
|
foreach ($basket['content'] as $article) { |
1805
|
|
|
if ($article['esd']) { |
1806
|
|
|
return true; |
1807
|
|
|
} |
1808
|
|
|
} |
1809
|
|
|
|
1810
|
|
|
return false; |
1811
|
|
|
} |
1812
|
|
|
|
1813
|
|
|
/** |
1814
|
|
|
* Helper function that iterates through the basket articles. |
1815
|
|
|
* It checks if an article is a service article by comparing its attributes |
1816
|
|
|
* with the plugin config serviceAttrField value. |
1817
|
|
|
* |
1818
|
|
|
* @param array $basket |
1819
|
|
|
* |
1820
|
|
|
* @return bool |
1821
|
|
|
*/ |
1822
|
|
|
private function basketHasServiceArticles($basket) |
1823
|
|
|
{ |
1824
|
|
|
$config = Shopware()->Config(); |
1825
|
|
|
|
1826
|
|
|
if (!$config->offsetExists('serviceAttrField')) { |
1827
|
|
|
return false; |
1828
|
|
|
} |
1829
|
|
|
|
1830
|
|
|
$attrName = $config->serviceAttrField; |
|
|
|
|
1831
|
|
|
if (empty($attrName) || !isset($basket['content'])) { |
1832
|
|
|
return false; |
1833
|
|
|
} |
1834
|
|
|
|
1835
|
|
|
foreach ($basket['content'] as $article) { |
1836
|
|
|
$serviceAttr = $article['additional_details'][$attrName]; |
1837
|
|
|
|
1838
|
|
|
if ($serviceAttr && $serviceAttr != 'false') { |
1839
|
|
|
return true; |
1840
|
|
|
} |
1841
|
|
|
} |
1842
|
|
|
|
1843
|
|
|
return false; |
1844
|
|
|
} |
1845
|
|
|
|
1846
|
|
|
/** |
1847
|
|
|
* Helper function that iterates through the basket articles. |
1848
|
|
|
* If checks if the basket has a normal article e.g. not an esd article |
1849
|
|
|
* and not a article with the service attribute is set to true. |
1850
|
|
|
* |
1851
|
|
|
* @param array $basket |
1852
|
|
|
* |
1853
|
|
|
* @return bool |
1854
|
|
|
*/ |
1855
|
|
|
private function basketHasMixedArticles($basket) |
1856
|
|
|
{ |
1857
|
|
|
$config = Shopware()->Config(); |
1858
|
|
|
$attrName = $config->serviceAttrField; |
|
|
|
|
1859
|
|
|
|
1860
|
|
|
if (!isset($basket['content'])) { |
1861
|
|
|
return false; |
1862
|
|
|
} |
1863
|
|
|
|
1864
|
|
|
foreach ($basket['content'] as $article) { |
1865
|
|
|
if ($article['modus'] == 4 || $article['esd']) { |
1866
|
|
|
continue; |
1867
|
|
|
} |
1868
|
|
|
|
1869
|
|
|
$serviceAttr = $article['additional_details'][$attrName]; |
1870
|
|
|
if (empty($attrName) || ($serviceAttr && $serviceAttr != 'false')) { |
1871
|
|
|
continue; |
1872
|
|
|
} |
1873
|
|
|
|
1874
|
|
|
return true; |
1875
|
|
|
} |
1876
|
|
|
|
1877
|
|
|
return false; |
1878
|
|
|
} |
1879
|
|
|
|
1880
|
|
|
/** |
1881
|
|
|
* Handles payment method validation fail on checkout |
1882
|
|
|
* Redirects the user to the payment edit page |
1883
|
|
|
*/ |
1884
|
|
|
private function onPaymentMethodValidationFail() |
1885
|
|
|
{ |
1886
|
|
|
$target = ['controller' => 'checkout', 'action' => 'shippingPayment']; |
1887
|
|
|
$this->redirect($target); |
1888
|
|
|
} |
1889
|
|
|
|
1890
|
|
|
/** |
1891
|
|
|
* Selects the default payment method defined in the backend. If no payment method is defined, |
1892
|
|
|
* the first payment method of the provided list will be returned. |
1893
|
|
|
* |
1894
|
|
|
* @param array $paymentMethods |
1895
|
|
|
* |
1896
|
|
|
* @return array |
1897
|
|
|
*/ |
1898
|
|
|
private function getDefaultPaymentMethod(array $paymentMethods) |
1899
|
|
|
{ |
1900
|
|
|
$payment = null; |
1901
|
|
|
|
1902
|
|
|
foreach ($paymentMethods as $paymentMethod) { |
1903
|
|
|
if ($paymentMethod['id'] == Shopware()->Config()->offsetGet('defaultpayment')) { |
1904
|
|
|
$payment = $paymentMethod; |
1905
|
|
|
break; |
1906
|
|
|
} |
1907
|
|
|
} |
1908
|
|
|
|
1909
|
|
|
if (!$payment) { |
1910
|
|
|
$payment = reset($paymentMethods); |
1911
|
|
|
} |
1912
|
|
|
|
1913
|
|
|
return $payment; |
1914
|
|
|
} |
1915
|
|
|
|
1916
|
|
|
/** |
1917
|
|
|
* Resets the temporary session address ids back to default |
1918
|
|
|
*/ |
1919
|
|
|
private function resetTemporaryAddresses() |
1920
|
|
|
{ |
1921
|
|
|
$this->session->offsetUnset('checkoutBillingAddressId'); |
1922
|
|
|
$this->session->offsetUnset('checkoutShippingAddressId'); |
1923
|
|
|
} |
1924
|
|
|
|
1925
|
|
|
/** |
1926
|
|
|
* Sets the default addresses for the user if he decided to use the temporary addresses as new default |
1927
|
|
|
*/ |
1928
|
|
|
private function saveDefaultAddresses() |
1929
|
|
|
{ |
1930
|
|
|
$billingId = $this->session->offsetGet('checkoutBillingAddressId', false); |
1931
|
|
|
$shippingId = $this->session->offsetGet('checkoutShippingAddressId', false); |
1932
|
|
|
$setBoth = $this->Request()->getPost('setAsDefaultAddress', false); |
1933
|
|
|
|
1934
|
|
|
if (!$this->Request()->getPost('setAsDefaultBillingAddress') && !$setBoth) { |
1935
|
|
|
$billingId = false; |
1936
|
|
|
} |
1937
|
|
|
|
1938
|
|
|
if (!$this->Request()->getPost('setAsDefaultShippingAddress') && !$setBoth) { |
1939
|
|
|
$shippingId = false; |
1940
|
|
|
} |
1941
|
|
|
|
1942
|
|
|
if ($billingId && $billingId != $this->View()->sUserData['additional']['user']['default_billing_address_id']) { |
1943
|
|
|
$address = $this->get('models') |
1944
|
|
|
->getRepository(Address::class) |
1945
|
|
|
->getOneByUser( |
1946
|
|
|
$billingId, |
1947
|
|
|
$this->View()->sUserData['additional']['user']['id'] |
1948
|
|
|
); |
1949
|
|
|
|
1950
|
|
|
$this->get('shopware_account.address_service')->setDefaultBillingAddress($address); |
1951
|
|
|
} |
1952
|
|
|
|
1953
|
|
|
if ($shippingId && $shippingId != $this->View()->sUserData['additional']['user']['default_shipping_address_id']) { |
1954
|
|
|
$address = $this->get('models') |
1955
|
|
|
->getRepository(Address::class) |
1956
|
|
|
->getOneByUser( |
1957
|
|
|
$shippingId, |
1958
|
|
|
$this->View()->sUserData['additional']['user']['id'] |
1959
|
|
|
); |
1960
|
|
|
|
1961
|
|
|
$this->get('shopware_account.address_service')->setDefaultShippingAddress($address); |
1962
|
|
|
} |
1963
|
|
|
} |
1964
|
|
|
|
1965
|
|
|
/** |
1966
|
|
|
* Validates the given address id with current shop configuration |
1967
|
|
|
* |
1968
|
|
|
* @param int $addressId |
1969
|
|
|
* |
1970
|
|
|
* @return bool |
1971
|
|
|
*/ |
1972
|
|
|
private function isValidAddress($addressId) |
1973
|
|
|
{ |
1974
|
|
|
$address = $this->get('models')->find(Address::class, $addressId); |
1975
|
|
|
|
1976
|
|
|
return $this->get('shopware_account.address_validator')->isValid($address); |
1977
|
|
|
} |
1978
|
|
|
|
1979
|
|
|
/** |
1980
|
|
|
* @param int $orderNumber |
1981
|
|
|
* @param string $source |
1982
|
|
|
* |
1983
|
|
|
* @return array |
1984
|
|
|
*/ |
1985
|
|
|
private function getOrderAddress($orderNumber, $source) |
1986
|
|
|
{ |
1987
|
|
|
/** @var \Doctrine\DBAL\Query\QueryBuilder $builder */ |
1988
|
|
|
$builder = $this->get('dbal_connection')->createQueryBuilder(); |
1989
|
|
|
$context = $this->get('shopware_storefront.context_service')->getShopContext(); |
1990
|
|
|
|
1991
|
|
|
$sourceTable = $source === 'billing' ? 's_order_billingaddress' : 's_order_shippingaddress'; |
1992
|
|
|
|
1993
|
|
|
$address = $builder->select(['address.*']) |
1994
|
|
|
->from($sourceTable, 'address') |
1995
|
|
|
->join('address', 's_order', '', 'address.orderID = s_order.id AND s_order.ordernumber = :orderNumber') |
1996
|
|
|
->setParameter('orderNumber', $orderNumber) |
1997
|
|
|
->execute() |
1998
|
|
|
->fetch(); |
1999
|
|
|
|
2000
|
|
|
$countryStruct = $this->get('shopware_storefront.country_gateway')->getCountry($address['countryID'], $context); |
2001
|
|
|
$stateStruct = $this->get('shopware_storefront.country_gateway')->getState($address['stateID'], $context); |
2002
|
|
|
|
2003
|
|
|
$address['country'] = json_decode(json_encode($countryStruct), true); |
2004
|
|
|
$address['state'] = json_decode(json_encode($stateStruct), true); |
2005
|
|
|
$address['attribute'] = $this->get('shopware_attribute.data_loader')->load($sourceTable . '_attributes', $address['id']); |
2006
|
|
|
|
2007
|
|
|
return $address; |
2008
|
|
|
} |
2009
|
|
|
|
2010
|
|
|
/** |
2011
|
|
|
* @param array $addressA |
2012
|
|
|
* @param array $addressB |
2013
|
|
|
* |
2014
|
|
|
* @return bool |
2015
|
|
|
*/ |
2016
|
|
|
private function areAddressesEqual(array $addressA, array $addressB) |
2017
|
|
|
{ |
2018
|
|
|
$unset = ['id', 'customernumber', 'phone', 'ustid']; |
2019
|
|
|
foreach ($unset as $key) { |
2020
|
|
|
unset($addressA[$key], $addressB[$key]); |
2021
|
|
|
} |
2022
|
|
|
|
2023
|
|
|
return count(array_diff($addressA, $addressB)) === 0; |
2024
|
|
|
} |
2025
|
|
|
|
2026
|
|
|
/** |
2027
|
|
|
* @return string |
2028
|
|
|
*/ |
2029
|
|
|
private function persistBasket() |
2030
|
|
|
{ |
2031
|
|
|
/** @var BasketSignatureGeneratorInterface $generator */ |
2032
|
|
|
$generator = $this->get('basket_signature_generator'); |
2033
|
|
|
$basket = $this->session->offsetGet('sOrderVariables')->getArrayCopy(); |
2034
|
|
|
$signature = $generator->generateSignature($basket['sBasket'], $this->session->get('sUserId')); |
2035
|
|
|
|
2036
|
|
|
/** @var BasketPersister $persister */ |
2037
|
|
|
$persister = $this->get('basket_persister'); |
2038
|
|
|
$persister->persist($signature, $basket); |
2039
|
|
|
|
2040
|
|
|
return $signature; |
2041
|
|
|
} |
2042
|
|
|
|
2043
|
|
|
/** |
2044
|
|
|
* Updates all currency dependies (e.g. in the shop model or in the shop context). |
2045
|
|
|
* |
2046
|
|
|
* @param int $currencyId |
2047
|
|
|
*/ |
2048
|
|
|
private function updateCurrencyDependencies($currencyId) |
2049
|
|
|
{ |
2050
|
|
|
/** @var \Shopware\Models\Shop\Currency $currencyModel */ |
2051
|
|
|
$currencyModel = $this->get('models')->find(\Shopware\Models\Shop\Currency::class, $currencyId); |
2052
|
|
|
|
2053
|
|
|
/** @var Shopware\Models\Shop\Shop $shopModel */ |
2054
|
|
|
$shopModel = $this->get('shop'); |
2055
|
|
|
$shopModel->setCurrency($currencyModel); |
2056
|
|
|
|
2057
|
|
|
/** @var $currency \Zend_Currency */ |
2058
|
|
|
$currency = $this->get('Currency'); |
2059
|
|
|
$currency->setFormat($currencyModel->toArray()); |
2060
|
|
|
|
2061
|
|
|
$this->get('shopware_storefront.context_service')->initializeShopContext(); |
2062
|
|
|
} |
2063
|
|
|
} |
2064
|
|
|
|
Since your code implements the magic getter
_get
, this function will be called for any read access on an undefined variable. You can add the@property
annotation to your class or interface to document the existence of this variable.If the property has read access only, you can use the @property-read annotation instead.
Of course, you may also just have mistyped another name, in which case you should fix the error.
See also the PhpDoc documentation for @property.