|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* (c) shopware AG <[email protected]> |
|
4
|
|
|
* For the full copyright and license information, please view the LICENSE |
|
5
|
|
|
* file that was distributed with this source code. |
|
6
|
|
|
*/ |
|
7
|
|
|
|
|
8
|
|
|
namespace ShopwarePlugins\Connect\Subscribers; |
|
9
|
|
|
|
|
10
|
|
|
use Enlight\Event\SubscriberInterface; |
|
11
|
|
|
use Enlight_Event_EventManager; |
|
12
|
|
|
use Shopware\Components\Model\ModelManager; |
|
13
|
|
|
use Shopware\Connect\SDK; |
|
14
|
|
|
use Shopware\Connect\Struct\Address; |
|
15
|
|
|
use Shopware\Connect\Struct\CheckResult; |
|
16
|
|
|
use Shopware\Connect\Struct\Message; |
|
17
|
|
|
use Shopware\Connect\Struct\OrderItem; |
|
18
|
|
|
use Shopware\Connect\Struct\Product; |
|
19
|
|
|
use Shopware\Models\Order\Status; |
|
20
|
|
|
use ShopwarePlugins\Connect\Components\BasketHelper; |
|
21
|
|
|
use ShopwarePlugins\Connect\Components\ConnectFactory; |
|
22
|
|
|
use ShopwarePlugins\Connect\Components\Exceptions\CheckoutException; |
|
23
|
|
|
use ShopwarePlugins\Connect\Components\Helper; |
|
24
|
|
|
use ShopwarePlugins\Connect\Components\Logger; |
|
25
|
|
|
use ShopwarePlugins\Connect\Components\Utils\ConnectOrderUtil; |
|
26
|
|
|
use ShopwarePlugins\Connect\Components\Utils\OrderPaymentMapper; |
|
27
|
|
|
use Shopware\Models\Order\Order; |
|
28
|
|
|
use Shopware\Models\Payment\Payment; |
|
29
|
|
|
|
|
30
|
|
|
/** |
|
31
|
|
|
* Handles the whole checkout manipulation, which is required for the connect checkout |
|
32
|
|
|
*/ |
|
33
|
|
|
class Checkout implements SubscriberInterface |
|
34
|
|
|
{ |
|
35
|
|
|
/** |
|
36
|
|
|
* @var Logger |
|
37
|
|
|
*/ |
|
38
|
|
|
protected $logger; |
|
39
|
|
|
|
|
40
|
|
|
/** |
|
41
|
|
|
* @var string |
|
42
|
|
|
*/ |
|
43
|
|
|
private $newSessionId; |
|
44
|
|
|
|
|
45
|
|
|
/** |
|
46
|
|
|
* @var ConnectFactory |
|
47
|
|
|
*/ |
|
48
|
|
|
protected $factory; |
|
49
|
|
|
|
|
50
|
|
|
/** |
|
51
|
|
|
* @var ModelManager |
|
52
|
|
|
*/ |
|
53
|
|
|
protected $manager; |
|
54
|
|
|
|
|
55
|
|
|
/** |
|
56
|
|
|
* @var Enlight_Event_EventManager |
|
57
|
|
|
*/ |
|
58
|
|
|
protected $eventManager; |
|
59
|
|
|
|
|
60
|
|
|
/** |
|
61
|
|
|
* @var SDK |
|
62
|
|
|
*/ |
|
63
|
|
|
private $sdk; |
|
64
|
|
|
|
|
65
|
|
|
/** |
|
66
|
|
|
* @var BasketHelper |
|
67
|
|
|
*/ |
|
68
|
|
|
private $basketHelper; |
|
69
|
|
|
|
|
70
|
|
|
/** |
|
71
|
|
|
* @var Helper |
|
72
|
|
|
*/ |
|
73
|
|
|
private $helper; |
|
74
|
|
|
|
|
75
|
|
|
/** |
|
76
|
|
|
* @param ModelManager $manager |
|
77
|
|
|
* @param Enlight_Event_EventManager $eventManager |
|
78
|
|
|
* @param SDK $sdk |
|
79
|
|
|
* @param BasketHelper $basketHelper |
|
80
|
|
|
* @param Helper $helper |
|
81
|
|
|
*/ |
|
82
|
|
|
public function __construct( |
|
83
|
|
|
ModelManager $manager, |
|
84
|
|
|
Enlight_Event_EventManager $eventManager, |
|
85
|
|
|
SDK $sdk, |
|
86
|
|
|
BasketHelper $basketHelper, |
|
87
|
|
|
Helper $helper |
|
88
|
|
|
) { |
|
89
|
|
|
$this->manager = $manager; |
|
90
|
|
|
$this->eventManager = $eventManager; |
|
91
|
|
|
$this->logger = new Logger(Shopware()->Db()); |
|
92
|
|
|
$this->factory = new ConnectFactory(); |
|
93
|
|
|
$this->sdk = $sdk; |
|
94
|
|
|
$this->basketHelper = $basketHelper; |
|
95
|
|
|
$this->helper = $helper; |
|
96
|
|
|
} |
|
97
|
|
|
|
|
98
|
|
|
/** |
|
99
|
|
|
* {@inheritdoc} |
|
100
|
|
|
*/ |
|
101
|
|
|
public static function getSubscribedEvents() |
|
102
|
|
|
{ |
|
103
|
|
|
return [ |
|
104
|
|
|
'Enlight_Controller_Action_PostDispatch_Frontend_Checkout' => [ 'fixBasketForConnect', '-1' ], |
|
105
|
|
|
'Enlight_Controller_Action_PreDispatch_Frontend_Checkout' => 'reserveConnectProductsOnCheckoutFinish', |
|
106
|
|
|
'Shopware_Modules_Admin_Regenerate_Session_Id' => 'updateSessionId', |
|
107
|
|
|
]; |
|
108
|
|
|
} |
|
109
|
|
|
|
|
110
|
|
|
/** |
|
111
|
|
|
* @param \Enlight_Event_EventArgs $args |
|
112
|
|
|
*/ |
|
113
|
|
|
public function updateSessionId(\Enlight_Event_EventArgs $args) |
|
114
|
|
|
{ |
|
115
|
|
|
$this->newSessionId = $args->get('newSessionId'); |
|
116
|
|
|
} |
|
117
|
|
|
|
|
118
|
|
|
/** |
|
119
|
|
|
* @return string |
|
120
|
|
|
*/ |
|
121
|
|
|
protected function getCountryCode() |
|
122
|
|
|
{ |
|
123
|
|
|
$countryCodeUtil = $this->factory->getCountryCodeResolver(); |
|
124
|
|
|
|
|
125
|
|
|
return $countryCodeUtil->getIso3CountryCode(); |
|
126
|
|
|
} |
|
127
|
|
|
|
|
128
|
|
|
/** |
|
129
|
|
|
* Event listener method for the checkout confirm- and cartAction. |
|
130
|
|
|
* |
|
131
|
|
|
* @param \Enlight_Event_EventArgs $args |
|
132
|
|
|
* @throws CheckoutException |
|
133
|
|
|
* @return void |
|
134
|
|
|
*/ |
|
135
|
|
|
public function fixBasketForConnect(\Enlight_Event_EventArgs $args) |
|
136
|
|
|
{ |
|
137
|
|
|
/** @var $action \Enlight_Controller_Action */ |
|
138
|
|
|
$action = $args->getSubject(); |
|
139
|
|
|
$view = $action->View(); |
|
140
|
|
|
$request = $action->Request(); |
|
141
|
|
|
$actionName = $request->getActionName(); |
|
142
|
|
|
$sessionId = Shopware()->SessionID(); |
|
143
|
|
|
|
|
144
|
|
|
$userId = Shopware()->Session()->sUserId; |
|
145
|
|
|
$hasConnectProduct = $this->helper->hasBasketConnectProducts($sessionId, $userId); |
|
146
|
|
|
|
|
147
|
|
|
if ($hasConnectProduct === false && $this->newSessionId) { |
|
148
|
|
|
$hasConnectProduct = $this->helper->hasBasketConnectProducts($this->newSessionId); |
|
149
|
|
|
} |
|
150
|
|
|
|
|
151
|
|
|
$view->hasConnectProduct = $hasConnectProduct; |
|
152
|
|
|
|
|
153
|
|
|
if ($actionName === 'ajax_add_article') { |
|
154
|
|
|
$view->extendsTemplate('frontend/connect/ajax_add_article.tpl'); |
|
155
|
|
|
} |
|
156
|
|
|
|
|
157
|
|
|
// send order to connect |
|
158
|
|
|
// this method must be called after external payments (Sofort, Billsafe) |
|
159
|
|
|
if ($actionName === 'finish' && !empty($view->sOrderNumber)) { |
|
160
|
|
|
try { |
|
161
|
|
|
$this->checkoutReservedProducts($view->sOrderNumber); |
|
162
|
|
|
} catch (CheckoutException $e) { |
|
163
|
|
|
$this->setOrderStatusError($view->sOrderNumber); |
|
164
|
|
|
throw $e; |
|
165
|
|
|
} |
|
166
|
|
|
} |
|
167
|
|
|
|
|
168
|
|
|
// clear connect reserved products |
|
169
|
|
|
// sometimes with external payment methods |
|
170
|
|
|
// $hasConnectProduct will be false, because order is already finished |
|
171
|
|
|
// and information about connect products is not available. |
|
172
|
|
|
if (!$hasConnectProduct) { |
|
173
|
|
|
$this->helper->clearConnectReservation(); |
|
174
|
|
|
|
|
175
|
|
|
return; |
|
176
|
|
|
} |
|
177
|
|
|
|
|
178
|
|
|
if (!in_array($actionName, ['confirm', 'shippingPayment', 'cart', 'finish'])) { |
|
179
|
|
|
return; |
|
180
|
|
|
} |
|
181
|
|
|
|
|
182
|
|
|
if (empty($view->sBasket) || !$request->isDispatched()) { |
|
183
|
|
|
return; |
|
184
|
|
|
} |
|
185
|
|
|
|
|
186
|
|
|
if (!empty($view->sOrderNumber)) { |
|
187
|
|
|
return; |
|
188
|
|
|
} |
|
189
|
|
|
|
|
190
|
|
|
if (Shopware()->Config()->get('requirePhoneField')) { |
|
191
|
|
|
$this->enforcePhoneNumber($view); |
|
192
|
|
|
} |
|
193
|
|
|
|
|
194
|
|
|
// Wrap the basket array in order to make it some more readable |
|
195
|
|
|
$this->basketHelper->setBasket($view->sBasket); |
|
196
|
|
|
|
|
197
|
|
|
// If no messages are shown, yet, check products from remote shop and build message array |
|
198
|
|
|
if (($connectMessages = Shopware()->Session()->connectMessages) === null) { |
|
199
|
|
|
$connectMessages = []; |
|
200
|
|
|
|
|
201
|
|
|
$session = Shopware()->Session(); |
|
202
|
|
|
$userData = $session['sOrderVariables']['sUserData']; |
|
203
|
|
|
// prepare an order to check products |
|
204
|
|
|
$order = new \Shopware\Connect\Struct\Order(); |
|
205
|
|
|
$order->orderItems = []; |
|
206
|
|
|
$order->billingAddress = $order->deliveryAddress = $this->getDeliveryAddress($userData); |
|
207
|
|
|
|
|
208
|
|
|
$allProducts = []; |
|
209
|
|
|
|
|
210
|
|
|
foreach ($this->basketHelper->getConnectProducts() as $shopId => $products) { |
|
211
|
|
|
$products = $this->helper->prepareConnectUnit($products); |
|
212
|
|
|
$allProducts = array_merge($allProducts, $products); |
|
213
|
|
|
// add order items in connect order |
|
214
|
|
|
$order->orderItems = array_map(function (Product $product) { |
|
215
|
|
|
return new OrderItem([ |
|
216
|
|
|
'product' => $product, |
|
217
|
|
|
'count' => $this->basketHelper->getQuantityForProduct($product), |
|
218
|
|
|
]); |
|
219
|
|
|
}, $products); |
|
220
|
|
|
} |
|
221
|
|
|
|
|
222
|
|
|
$this->eventManager->notify( |
|
223
|
|
|
'Connect_Merchant_Create_Order_Before', |
|
224
|
|
|
[ |
|
225
|
|
|
//we use clone to not be able to modify the connect order |
|
226
|
|
|
'order' => clone $order, |
|
227
|
|
|
'basket' => $view->sBasket, |
|
228
|
|
|
] |
|
229
|
|
|
); |
|
230
|
|
|
|
|
231
|
|
|
try { |
|
232
|
|
|
/** @var $checkResult \Shopware\Connect\Struct\CheckResult */ |
|
233
|
|
|
$checkResult = $this->sdk->checkProducts($order); |
|
234
|
|
|
$this->basketHelper->setCheckResult($checkResult); |
|
235
|
|
|
|
|
236
|
|
|
if ($checkResult->hasErrors()) { |
|
237
|
|
|
$connectMessages = $checkResult->errors; |
|
238
|
|
|
} |
|
239
|
|
|
} catch (\Exception $e) { |
|
240
|
|
|
$this->logger->write(true, 'Error during checkout', $e, 'checkout'); |
|
241
|
|
|
// If the checkout results in an exception because the remote shop is not available |
|
242
|
|
|
// don't show the exception to the user but tell him to remove the products from that shop |
|
243
|
|
|
$connectMessages = $this->getNotAvailableMessageForProducts($allProducts); |
|
244
|
|
|
} |
|
245
|
|
|
} |
|
246
|
|
|
|
|
247
|
|
|
if ($connectMessages) { |
|
248
|
|
|
$connectMessages = $this->translateConnectMessages($connectMessages); |
|
249
|
|
|
} |
|
250
|
|
|
|
|
251
|
|
|
Shopware()->Session()->connectMessages = null; |
|
252
|
|
|
|
|
253
|
|
|
// If no products are bought from the local shop, move the first connect shop into |
|
254
|
|
|
// the content section. Also set that shop's id in the template |
|
255
|
|
|
$shopId = $this->basketHelper->fixBasket(); |
|
256
|
|
|
if ($shopId) { |
|
257
|
|
|
$view->shopId = $shopId; |
|
258
|
|
|
} |
|
259
|
|
|
// Increase amount and shipping costs by the amount of connect shipping costs |
|
260
|
|
|
$this->basketHelper->recalculate($this->basketHelper->getCheckResult()); |
|
261
|
|
|
|
|
262
|
|
|
$connectMessages = $this->getNotShippableMessages($this->basketHelper->getCheckResult(), $connectMessages); |
|
263
|
|
|
|
|
264
|
|
|
$view->assign($this->basketHelper->getDefaultTemplateVariables()); |
|
265
|
|
|
|
|
266
|
|
|
// Set the sOrderVariables for the session based on the original content subarray of the basket array |
|
267
|
|
|
// @HL - docs? |
|
268
|
|
|
if ($actionName === 'confirm') { |
|
269
|
|
|
$session = Shopware()->Session(); |
|
270
|
|
|
/** @var $variables \ArrayObject */ |
|
271
|
|
|
$variables = $session->offsetGet('sOrderVariables'); |
|
272
|
|
|
|
|
273
|
|
|
$session->offsetSet('sOrderVariables', $this->basketHelper->getOrderVariablesForSession($variables)); |
|
274
|
|
|
} |
|
275
|
|
|
|
|
276
|
|
|
$view->assign($this->basketHelper->getConnectTemplateVariables($connectMessages)); |
|
277
|
|
|
$view->assign('showShippingCostsSeparately', $this->factory->getConfigComponent()->getConfig('showShippingCostsSeparately', false)); |
|
278
|
|
|
} |
|
279
|
|
|
|
|
280
|
|
|
/** |
|
281
|
|
|
* Helper to translate connect messages from the SDK. Will use the normalized message itself as namespace key |
|
282
|
|
|
* |
|
283
|
|
|
* @param $connectMessages |
|
284
|
|
|
* @return mixed |
|
285
|
|
|
*/ |
|
286
|
|
|
private function translateConnectMessages($connectMessages) |
|
287
|
|
|
{ |
|
288
|
|
|
$namespace = Shopware()->Snippets()->getNamespace('frontend/checkout/connect'); |
|
289
|
|
|
|
|
290
|
|
|
foreach ($connectMessages as &$connectMessage) { |
|
291
|
|
|
$message = trim($connectMessage->message); |
|
292
|
|
|
$normalized = strtolower(preg_replace('/[^a-zA-Z0-9]/', '_', $connectMessage->message)); |
|
293
|
|
|
if (empty($normalized) || empty($message)) { |
|
294
|
|
|
$normalized = 'unknown-connect-error'; |
|
295
|
|
|
$message = 'Unknown error'; |
|
296
|
|
|
} |
|
297
|
|
|
$translation = $namespace->get( |
|
298
|
|
|
$normalized, |
|
299
|
|
|
$message, |
|
300
|
|
|
true |
|
301
|
|
|
); |
|
302
|
|
|
|
|
303
|
|
|
$connectMessage->message = $translation; |
|
304
|
|
|
} |
|
305
|
|
|
|
|
306
|
|
|
return $connectMessages; |
|
307
|
|
|
} |
|
308
|
|
|
|
|
309
|
|
|
/** |
|
310
|
|
|
* Event listener method for the checkout->finishAction. Will reserve products and redirect to |
|
311
|
|
|
* the confirm page if a product cannot be reserved |
|
312
|
|
|
* |
|
313
|
|
|
* @event Enlight_Controller_Action_PreDispatch_Frontend_Checkout |
|
314
|
|
|
* @param \Enlight_Event_EventArgs $args |
|
315
|
|
|
*/ |
|
316
|
|
|
public function reserveConnectProductsOnCheckoutFinish(\Enlight_Event_EventArgs $args) |
|
317
|
|
|
{ |
|
318
|
|
|
/** @var $controller \Enlight_Controller_Action */ |
|
319
|
|
|
$controller = $args->getSubject(); |
|
320
|
|
|
$request = $controller->Request(); |
|
321
|
|
|
$view = $controller->View(); |
|
322
|
|
|
$session = Shopware()->Session(); |
|
323
|
|
|
$userData = $session['sOrderVariables']['sUserData']; |
|
324
|
|
|
$paymentName = $userData['additional']['payment']['name']; |
|
325
|
|
|
|
|
326
|
|
|
if (($request->getActionName() !== 'finish' && $request->getActionName() !== 'payment')) { |
|
327
|
|
|
if (($request->getActionName() === 'confirm' && $paymentName === 'klarna_checkout')) { |
|
|
|
|
|
|
328
|
|
|
// BEP-1010 Fix for Klarna checkout |
|
329
|
|
|
} else { |
|
330
|
|
|
return; |
|
331
|
|
|
} |
|
332
|
|
|
} |
|
333
|
|
|
|
|
334
|
|
|
if (empty($session['sOrderVariables'])) { |
|
335
|
|
|
return; |
|
336
|
|
|
} |
|
337
|
|
|
|
|
338
|
|
|
if (!$this->helper->hasBasketConnectProducts(Shopware()->SessionID())) { |
|
339
|
|
|
return; |
|
340
|
|
|
} |
|
341
|
|
|
|
|
342
|
|
|
$userData = $session['sOrderVariables']['sUserData']; |
|
343
|
|
|
$paymentId = $userData['additional']['payment']['id']; |
|
344
|
|
|
|
|
345
|
|
|
if ($this->isPaymentAllowed($paymentId) === false) { |
|
346
|
|
|
$connectMessage = new \stdClass(); |
|
347
|
|
|
$connectMessage->message = 'frontend_checkout_cart_connect_payment_not_allowed'; |
|
348
|
|
|
|
|
349
|
|
|
$connectMessages = [ |
|
350
|
|
|
0 => [ |
|
351
|
|
|
'connectmessage' => $connectMessage |
|
352
|
|
|
] |
|
353
|
|
|
]; |
|
354
|
|
|
|
|
355
|
|
|
Shopware()->Session()->connectMessages = $this->translateConnectMessages($connectMessages); |
|
356
|
|
|
$controller->forward('confirm'); |
|
357
|
|
|
} |
|
358
|
|
|
|
|
359
|
|
|
if (Shopware()->Config()->get('requirePhoneField')) { |
|
360
|
|
|
$this->enforcePhoneNumber($view); |
|
361
|
|
|
} |
|
362
|
|
|
|
|
363
|
|
|
$order = new \Shopware\Connect\Struct\Order(); |
|
364
|
|
|
$order->orderItems = []; |
|
365
|
|
|
$order->deliveryAddress = $this->getDeliveryAddress($userData); |
|
366
|
|
|
|
|
367
|
|
|
$basket = $session['sOrderVariables']['sBasket']; |
|
368
|
|
|
|
|
369
|
|
|
/** @var \ShopwarePlugins\Connect\Components\Utils\OrderPaymentMapper $orderPaymentMapper */ |
|
370
|
|
|
$orderPaymentMapper = new OrderPaymentMapper(); |
|
371
|
|
|
$orderPaymentName = $userData['additional']['payment']['name']; |
|
372
|
|
|
$order->paymentType = $orderPaymentMapper->mapShopwareOrderPaymentToConnect($orderPaymentName); |
|
373
|
|
|
|
|
374
|
|
|
foreach ($basket['content'] as $row) { |
|
375
|
|
|
if (!empty($row['mode'])) { |
|
376
|
|
|
continue; |
|
377
|
|
|
} |
|
378
|
|
|
|
|
379
|
|
|
$articleDetailId = $row['additional_details']['articleDetailsID']; |
|
380
|
|
|
if ($this->helper->isRemoteArticleDetailDBAL($articleDetailId) === false) { |
|
381
|
|
|
continue; |
|
382
|
|
|
} |
|
383
|
|
|
$shopProductId = $this->helper->getShopProductId($articleDetailId); |
|
384
|
|
|
|
|
385
|
|
|
$products = $this->helper->getRemoteProducts([$shopProductId->sourceId], $shopProductId->shopId); |
|
386
|
|
|
$products = $this->helper->prepareConnectUnit($products); |
|
387
|
|
|
|
|
388
|
|
|
if (empty($products)) { |
|
389
|
|
|
continue; |
|
390
|
|
|
} |
|
391
|
|
|
$product = $products[0]; |
|
392
|
|
|
|
|
393
|
|
|
|
|
394
|
|
|
if ($product === null || $product->shopId === null) { |
|
395
|
|
|
continue; |
|
396
|
|
|
} |
|
397
|
|
|
|
|
398
|
|
|
$orderItem = new \Shopware\Connect\Struct\OrderItem(); |
|
399
|
|
|
$orderItem->product = $product; |
|
400
|
|
|
$orderItem->count = (int) $row['quantity']; |
|
401
|
|
|
$order->orderItems[] = $orderItem; |
|
402
|
|
|
} |
|
403
|
|
|
|
|
404
|
|
|
if (empty($order->orderItems)) { |
|
405
|
|
|
return; |
|
406
|
|
|
} |
|
407
|
|
|
|
|
408
|
|
|
try { |
|
409
|
|
|
$order = $this->eventManager->filter( |
|
410
|
|
|
'Connect_Subscriber_OrderReservation_OrderFilter', |
|
411
|
|
|
$order |
|
412
|
|
|
); |
|
413
|
|
|
|
|
414
|
|
|
/** @var $reservation \Shopware\Connect\Struct\Reservation */ |
|
415
|
|
|
$reservation = $this->sdk->reserveProducts($order); |
|
416
|
|
|
|
|
417
|
|
|
if (!$reservation || !$reservation->success) { |
|
418
|
|
|
throw new \Exception('Error during reservation'); |
|
419
|
|
|
} |
|
420
|
|
|
|
|
421
|
|
|
if (!empty($reservation->messages)) { |
|
422
|
|
|
$messages = $reservation->messages; |
|
423
|
|
|
} |
|
424
|
|
|
} catch (\Exception $e) { |
|
425
|
|
|
$this->logger->write(true, 'Error during reservation', $e, 'reservation'); |
|
426
|
|
|
$messages = $this->getNotAvailableMessageForProducts(array_map( |
|
427
|
|
|
function ($orderItem) { |
|
428
|
|
|
return $orderItem->product; |
|
429
|
|
|
}, |
|
430
|
|
|
$order->orderItems |
|
431
|
|
|
)); |
|
432
|
|
|
} |
|
433
|
|
|
|
|
434
|
|
|
if (!empty($messages)) { |
|
435
|
|
|
Shopware()->Session()->connectMessages = $messages; |
|
436
|
|
|
$controller->forward('confirm'); |
|
437
|
|
|
} else { |
|
438
|
|
|
Shopware()->Session()->connectReservation = serialize($reservation); |
|
|
|
|
|
|
439
|
|
|
} |
|
440
|
|
|
} |
|
441
|
|
|
|
|
442
|
|
|
/** |
|
443
|
|
|
* Helper method to create an address struct from shopware session info |
|
444
|
|
|
* |
|
445
|
|
|
* @param $userData |
|
446
|
|
|
* @return Address |
|
447
|
|
|
*/ |
|
448
|
|
|
private function getDeliveryAddress($userData) |
|
449
|
|
|
{ |
|
450
|
|
|
if (!$userData) { |
|
451
|
|
|
return $this->createDummyAddress('DEU'); |
|
452
|
|
|
} |
|
453
|
|
|
|
|
454
|
|
|
$shippingData = $userData['shippingaddress']; |
|
455
|
|
|
$address = new Address(); |
|
456
|
|
|
$address->zip = $shippingData['zipcode']; |
|
457
|
|
|
$address->city = $shippingData['city']; |
|
458
|
|
|
$address->country = $userData['additional']['countryShipping']['iso3']; //when the user is not logged in |
|
459
|
|
|
$address->phone = $userData['billingaddress']['phone']; |
|
460
|
|
|
$address->email = $userData['additional']['user']['email']; |
|
461
|
|
|
if (!empty($userData['additional']['stateShipping']['shortcode'])) { |
|
462
|
|
|
$address->state = $userData['additional']['stateShipping']['shortcode']; |
|
463
|
|
|
} |
|
464
|
|
|
if (!empty($shippingData['department'])) { |
|
465
|
|
|
$address->department = $shippingData['department']; |
|
466
|
|
|
} |
|
467
|
|
|
if (!empty($shippingData['additionalAddressLine1'])) { |
|
468
|
|
|
$address->additionalAddressLine1 = $shippingData['additionalAddressLine1']; |
|
469
|
|
|
} |
|
470
|
|
|
if (!empty($shippingData['additionalAddressLine2'])) { |
|
471
|
|
|
$address->additionalAddressLine2 = $shippingData['additionalAddressLine2']; |
|
472
|
|
|
} |
|
473
|
|
|
$address->firstName = $shippingData['firstname']; |
|
474
|
|
|
$address->surName = $shippingData['lastname']; |
|
475
|
|
|
if (!empty($shippingData['company'])) { |
|
476
|
|
|
$address->company = $shippingData['company']; |
|
477
|
|
|
} |
|
478
|
|
|
$address->street = $shippingData['street']; |
|
479
|
|
|
$address->streetNumber = (string) $shippingData['streetnumber']; |
|
480
|
|
|
|
|
481
|
|
|
return $address; |
|
482
|
|
|
} |
|
483
|
|
|
|
|
484
|
|
|
/** |
|
485
|
|
|
* @param string $country |
|
486
|
|
|
* @return Address |
|
487
|
|
|
*/ |
|
488
|
|
|
private function createDummyAddress($country = 'DEU') |
|
489
|
|
|
{ |
|
490
|
|
|
return new Address([ |
|
491
|
|
|
'country' => $country, |
|
492
|
|
|
'firstName' => 'Shopware', |
|
493
|
|
|
'surName' => 'AG', |
|
494
|
|
|
'street' => 'Eggeroder Str. 6', |
|
495
|
|
|
'zip' => '48624', |
|
496
|
|
|
'city' => 'Schöppingen', |
|
497
|
|
|
'phone' => '+49 (0) 2555 92885-0', |
|
498
|
|
|
'email' => '[email protected]' |
|
499
|
|
|
]); |
|
500
|
|
|
} |
|
501
|
|
|
|
|
502
|
|
|
/** |
|
503
|
|
|
* Hooks the sSaveOrder frontend method and reserves the connect products |
|
504
|
|
|
* |
|
505
|
|
|
* @param $orderNumber |
|
506
|
|
|
* @throws \ShopwarePlugins\Connect\Components\Exceptions\CheckoutException |
|
507
|
|
|
*/ |
|
508
|
|
|
public function checkoutReservedProducts($orderNumber) |
|
509
|
|
|
{ |
|
510
|
|
|
if (empty($orderNumber)) { |
|
511
|
|
|
return; |
|
512
|
|
|
} |
|
513
|
|
|
|
|
514
|
|
|
$reservation = unserialize(Shopware()->Session()->connectReservation); |
|
515
|
|
|
|
|
516
|
|
|
if ($reservation !== null && $reservation !== false) { |
|
517
|
|
|
$result = $this->sdk->checkout($reservation, $orderNumber); |
|
518
|
|
|
foreach ($result as $shopId => $success) { |
|
519
|
|
|
if (!$success) { |
|
520
|
|
|
$e = new CheckoutException("Could not checkout from warehouse {$shopId}"); |
|
521
|
|
|
$this->logger->write(true, 'Error during checkout with this reservation: ' . json_encode($reservation, JSON_PRETTY_PRINT), $e, 'checkout'); |
|
522
|
|
|
throw $e; |
|
523
|
|
|
} |
|
524
|
|
|
} |
|
525
|
|
|
$this->helper->clearConnectReservation(); |
|
526
|
|
|
} |
|
527
|
|
|
} |
|
528
|
|
|
|
|
529
|
|
|
/** |
|
530
|
|
|
* Asks the user to leave is phone number if connect products are in the basket and the |
|
531
|
|
|
* phone number was not configured, yet. |
|
532
|
|
|
* |
|
533
|
|
|
* @param \Enlight_View_Default $view |
|
534
|
|
|
* @return null |
|
535
|
|
|
*/ |
|
536
|
|
|
public function enforcePhoneNumber($view) |
|
537
|
|
|
{ |
|
538
|
|
|
if (Shopware()->Session()->sUserId && $this->helper->hasBasketConnectProducts(Shopware()->SessionID())) { |
|
539
|
|
|
$id = Shopware()->Session()->sUserId; |
|
540
|
|
|
|
|
541
|
|
|
$sql = 'SELECT phone FROM s_user_billingaddress WHERE userID = :id'; |
|
542
|
|
|
$result = Shopware()->Db()->fetchOne($sql, ['id' => $id]); |
|
543
|
|
|
if (!$result) { |
|
544
|
|
|
$view->assign('phoneMissing', true); |
|
545
|
|
|
} |
|
546
|
|
|
} |
|
547
|
|
|
} |
|
548
|
|
|
|
|
549
|
|
|
/** |
|
550
|
|
|
* @param Product[] $products |
|
551
|
|
|
* @return array |
|
552
|
|
|
*/ |
|
553
|
|
|
protected function getNotAvailableMessageForProducts($products) |
|
554
|
|
|
{ |
|
555
|
|
|
$messages = []; |
|
556
|
|
|
foreach ($products as $product) { |
|
557
|
|
|
$messages[] = new Message([ |
|
558
|
|
|
'message' => 'Due to technical reasons, product %product is not available.', |
|
559
|
|
|
'values' => [ |
|
560
|
|
|
'product' => $product->title, |
|
561
|
|
|
] |
|
562
|
|
|
]); |
|
563
|
|
|
} |
|
564
|
|
|
|
|
565
|
|
|
return $messages; |
|
566
|
|
|
} |
|
567
|
|
|
|
|
568
|
|
|
/** |
|
569
|
|
|
* @param \Shopware\Connect\Struct\CheckResult $checkResult |
|
570
|
|
|
* @param $connectMessages |
|
571
|
|
|
* @return mixed |
|
572
|
|
|
*/ |
|
573
|
|
|
protected function getNotShippableMessages($checkResult, $connectMessages) |
|
574
|
|
|
{ |
|
575
|
|
|
if (!$checkResult instanceof CheckResult) { |
|
576
|
|
|
return $connectMessages; |
|
577
|
|
|
} |
|
578
|
|
|
|
|
579
|
|
|
$namespace = Shopware()->Snippets()->getNamespace('frontend/checkout/connect'); |
|
580
|
|
|
|
|
581
|
|
|
foreach ($checkResult->shippingCosts as $shipping) { |
|
582
|
|
|
if ($shipping->isShippable === false) { |
|
583
|
|
|
$connectMessages[] = new Message([ |
|
584
|
|
|
'message' => $namespace->get( |
|
585
|
|
|
'frontend_checkout_cart_connect_not_shippable', |
|
586
|
|
|
'Ihre Bestellung kann nicht geliefert werden', |
|
587
|
|
|
true |
|
588
|
|
|
) |
|
589
|
|
|
]); |
|
590
|
|
|
} |
|
591
|
|
|
} |
|
592
|
|
|
|
|
593
|
|
|
return $connectMessages; |
|
594
|
|
|
} |
|
595
|
|
|
|
|
596
|
|
|
/** |
|
597
|
|
|
* @param $orderNumber |
|
598
|
|
|
* @return void |
|
599
|
|
|
*/ |
|
600
|
|
|
private function setOrderStatusError($orderNumber) |
|
601
|
|
|
{ |
|
602
|
|
|
$repo = $this->manager->getRepository(Order::class); |
|
603
|
|
|
|
|
604
|
|
|
/** @var Order $order */ |
|
605
|
|
|
$order = $repo->findOneBy(['number' => $orderNumber]); |
|
606
|
|
|
|
|
607
|
|
|
$repoStatus = $this->manager->getRepository(Status::class); |
|
608
|
|
|
$status = $repoStatus->findOneBy(['name' => ConnectOrderUtil::ORDER_STATUS_ERROR, 'group' => Status::GROUP_STATE ]); |
|
609
|
|
|
|
|
610
|
|
|
$order->setOrderStatus($status); |
|
611
|
|
|
$this->manager->persist($order); |
|
612
|
|
|
$this->manager->flush(); |
|
613
|
|
|
} |
|
614
|
|
|
|
|
615
|
|
|
/** |
|
616
|
|
|
* Check is allowed payment method with connect products |
|
617
|
|
|
* @param int $paymentId |
|
618
|
|
|
* @return bool |
|
619
|
|
|
*/ |
|
620
|
|
|
private function isPaymentAllowed($paymentId) |
|
621
|
|
|
{ |
|
622
|
|
|
if ($paymentId < 1) { |
|
623
|
|
|
return false; |
|
624
|
|
|
} |
|
625
|
|
|
|
|
626
|
|
|
$paymentRepository = $this->manager->getRepository(Payment::class); |
|
627
|
|
|
/** @var Payment $payment */ |
|
628
|
|
|
$payment = $paymentRepository->find($paymentId); |
|
629
|
|
|
|
|
630
|
|
|
if (!$payment) { |
|
631
|
|
|
return false; |
|
632
|
|
|
} |
|
633
|
|
|
|
|
634
|
|
|
if ($payment->getAttribute()->getConnectIsAllowed() == 0) { |
|
635
|
|
|
return false; |
|
636
|
|
|
} |
|
637
|
|
|
|
|
638
|
|
|
return true; |
|
639
|
|
|
} |
|
640
|
|
|
} |
|
641
|
|
|
|
This check looks for the bodies of
ifstatements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.These
ifbodies can be removed. If you have an empty if but statements in theelsebranch, consider inverting the condition.could be turned into
This is much more concise to read.