|
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\Components; |
|
9
|
|
|
|
|
10
|
|
|
use Enlight_Event_EventManager; |
|
11
|
|
|
use Shopware\Connect\Gateway; |
|
12
|
|
|
use Shopware\Connect\ProductFromShop as ProductFromShopBase; |
|
13
|
|
|
use Shopware\Connect\Struct\Order; |
|
14
|
|
|
use Shopware\Connect\Struct\Product; |
|
15
|
|
|
use Shopware\Connect\Struct\Address; |
|
16
|
|
|
use Shopware\Models\Order as OrderModel; |
|
17
|
|
|
use Shopware\Models\Attribute\OrderDetail as OrderDetailAttributeModel; |
|
18
|
|
|
use Shopware\Models\Customer as CustomerModel; |
|
19
|
|
|
use Shopware\Components\Model\ModelManager; |
|
20
|
|
|
use Shopware\Components\Random; |
|
21
|
|
|
use Shopware\Connect\Struct\Change\FromShop\Availability; |
|
22
|
|
|
use Shopware\Connect\Struct\Change\FromShop\Insert; |
|
23
|
|
|
use Shopware\Connect\Struct\Change\FromShop\Update; |
|
24
|
|
|
use Shopware\Connect\Struct\PaymentStatus; |
|
25
|
|
|
use Shopware\Connect\Struct\Shipping; |
|
26
|
|
|
use Shopware\CustomModels\Connect\Attribute; |
|
27
|
|
|
use ShopwarePlugins\Connect\Components\ProductStream\ProductStreamService; |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* The interface for products exported *to* connect *from* the local shop |
|
31
|
|
|
* |
|
32
|
|
|
* @category Shopware |
|
33
|
|
|
* @package Shopware\Plugins\SwagConnect |
|
34
|
|
|
*/ |
|
35
|
|
|
class ProductFromShop implements ProductFromShopBase |
|
36
|
|
|
{ |
|
37
|
|
|
/** |
|
38
|
|
|
* @var Helper |
|
39
|
|
|
*/ |
|
40
|
|
|
private $helper; |
|
41
|
|
|
|
|
42
|
|
|
/** |
|
43
|
|
|
* @var ModelManager |
|
44
|
|
|
*/ |
|
45
|
|
|
private $manager; |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* @var \Shopware\Connect\Gateway |
|
49
|
|
|
*/ |
|
50
|
|
|
private $gateway; |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* @var Logger |
|
54
|
|
|
*/ |
|
55
|
|
|
private $logger; |
|
56
|
|
|
|
|
57
|
|
|
/** |
|
58
|
|
|
* @var Enlight_Event_EventManager |
|
59
|
|
|
*/ |
|
60
|
|
|
private $eventManager; |
|
61
|
|
|
|
|
62
|
|
|
/** |
|
63
|
|
|
* @param Helper $helper |
|
64
|
|
|
* @param ModelManager $manager |
|
65
|
|
|
* @param Gateway $gateway |
|
66
|
|
|
* @param Logger $logger |
|
67
|
|
|
* @param Enlight_Event_EventManager $eventManager |
|
68
|
|
|
*/ |
|
69
|
|
|
public function __construct( |
|
70
|
|
|
Helper $helper, |
|
71
|
|
|
ModelManager $manager, |
|
72
|
|
|
Gateway $gateway, |
|
73
|
|
|
Logger $logger, |
|
74
|
|
|
Enlight_Event_EventManager $eventManager |
|
75
|
|
|
) { |
|
76
|
|
|
$this->helper = $helper; |
|
77
|
|
|
$this->manager = $manager; |
|
78
|
|
|
$this->gateway = $gateway; |
|
79
|
|
|
$this->logger = $logger; |
|
80
|
|
|
$this->eventManager = $eventManager; |
|
81
|
|
|
} |
|
82
|
|
|
|
|
83
|
|
|
/** |
|
84
|
|
|
* Get product data |
|
85
|
|
|
* |
|
86
|
|
|
* Get product data for all the source IDs specified in the given string |
|
87
|
|
|
* array. |
|
88
|
|
|
* |
|
89
|
|
|
* @param string[] $sourceIds |
|
90
|
|
|
* @return Product[] |
|
91
|
|
|
*/ |
|
92
|
|
|
public function getProducts(array $sourceIds) |
|
93
|
|
|
{ |
|
94
|
|
|
return $this->helper->getLocalProduct($sourceIds); |
|
95
|
|
|
} |
|
96
|
|
|
|
|
97
|
|
|
/** |
|
98
|
|
|
* Get all IDs of all exported products |
|
99
|
|
|
* |
|
100
|
|
|
* @throws \BadMethodCallException |
|
101
|
|
|
* @return string[] |
|
102
|
|
|
*/ |
|
103
|
|
|
public function getExportedProductIDs() |
|
104
|
|
|
{ |
|
105
|
|
|
throw new \BadMethodCallException('Not implemented'); |
|
106
|
|
|
} |
|
107
|
|
|
|
|
108
|
|
|
/** |
|
109
|
|
|
* Reserve a product in shop for purchase |
|
110
|
|
|
* |
|
111
|
|
|
* @param Order $order |
|
112
|
|
|
* @throws \Exception Abort reservation by throwing an exception here. |
|
113
|
|
|
* @return void |
|
114
|
|
|
*/ |
|
115
|
|
|
public function reserve(Order $order) |
|
116
|
|
|
{ |
|
117
|
|
|
$this->eventManager->notify( |
|
118
|
|
|
'Connect_Supplier_Reservation_Before', |
|
119
|
|
|
[ |
|
120
|
|
|
'subject' => $this, |
|
121
|
|
|
'order' => $order |
|
122
|
|
|
] |
|
123
|
|
|
); |
|
124
|
|
|
} |
|
125
|
|
|
|
|
126
|
|
|
/** |
|
127
|
|
|
* Create order in shopware |
|
128
|
|
|
* Wraps the actual order process into a transaction |
|
129
|
|
|
* |
|
130
|
|
|
* |
|
131
|
|
|
* @param Order $order |
|
132
|
|
|
* @throws \Exception Abort buy by throwing an exception, |
|
133
|
|
|
* but only in very important cases. |
|
134
|
|
|
* Do validation in {@see reserve} instead. |
|
135
|
|
|
* @return string |
|
136
|
|
|
*/ |
|
137
|
|
|
public function buy(Order $order) |
|
138
|
|
|
{ |
|
139
|
|
|
$this->manager->beginTransaction(); |
|
140
|
|
|
try { |
|
141
|
|
|
$order = $this->eventManager->filter('Connect_Components_ProductFromShop_Buy_OrderFilter', $order); |
|
142
|
|
|
|
|
143
|
|
|
$this->validateBilling($order->billingAddress); |
|
144
|
|
|
$orderNumber = $this->doBuy($order); |
|
145
|
|
|
|
|
146
|
|
|
$this->manager->commit(); |
|
147
|
|
|
} catch (\Exception $e) { |
|
148
|
|
|
$this->manager->rollback(); |
|
149
|
|
|
throw $e; |
|
150
|
|
|
} |
|
151
|
|
|
|
|
152
|
|
|
return $orderNumber; |
|
153
|
|
|
} |
|
154
|
|
|
|
|
155
|
|
|
/** |
|
156
|
|
|
* Actually creates the remote order in shopware. |
|
157
|
|
|
* |
|
158
|
|
|
* @param Order $order |
|
159
|
|
|
* @return string |
|
160
|
|
|
*/ |
|
161
|
|
|
public function doBuy(Order $order) |
|
162
|
|
|
{ |
|
163
|
|
|
$this->manager->clear(); |
|
164
|
|
|
|
|
165
|
|
|
$detailStatus = $this->manager->find('Shopware\Models\Order\DetailStatus', 0); |
|
166
|
|
|
$status = $this->manager->find('Shopware\Models\Order\Status', 0); |
|
167
|
|
|
$shop = $this->manager->find('Shopware\Models\Shop\Shop', 1); |
|
168
|
|
|
$number = 'SC-' . $order->orderShop . '-' . $order->localOrderId; |
|
169
|
|
|
|
|
170
|
|
|
$repository = $this->manager->getRepository('Shopware\Models\Payment\Payment'); |
|
171
|
|
|
$payment = $repository->findOneBy([ |
|
172
|
|
|
'name' => 'invoice', |
|
173
|
|
|
]); |
|
174
|
|
|
|
|
175
|
|
|
// todo: Create the OrderModel without previous plain SQL |
|
176
|
|
|
//$model = new OrderModel\Order(); |
|
|
|
|
|
|
177
|
|
|
$sql = 'INSERT INTO `s_order` (`ordernumber`, `cleared`) VALUES (?, 17);'; |
|
178
|
|
|
Shopware()->Db()->query($sql, [$number]); |
|
179
|
|
|
$modelId = Shopware()->Db()->lastInsertId(); |
|
180
|
|
|
/** @var $model \Shopware\Models\Order\Order */ |
|
181
|
|
|
$model = $this->manager->find('Shopware\Models\Order\Order', $modelId); |
|
182
|
|
|
|
|
183
|
|
|
$attribute = new \Shopware\Models\Attribute\Order; |
|
184
|
|
|
$attribute->setConnectOrderId($order->localOrderId); |
|
185
|
|
|
$attribute->setConnectShopId($order->orderShop); |
|
186
|
|
|
$model->setAttribute($attribute); |
|
187
|
|
|
|
|
188
|
|
|
$model->fromArray([ |
|
189
|
|
|
'number' => $number, |
|
190
|
|
|
'invoiceShipping' => $order->grossShippingCosts, |
|
|
|
|
|
|
191
|
|
|
'invoiceShippingNet' => $order->shippingCosts, |
|
|
|
|
|
|
192
|
|
|
'currencyFactor' => 1, |
|
193
|
|
|
'orderStatus' => $status, |
|
194
|
|
|
'shop' => $shop, |
|
195
|
|
|
'languageSubShop' => $shop, |
|
196
|
|
|
'payment' => $payment, |
|
197
|
|
|
'currency' => 'EUR', |
|
198
|
|
|
'orderTime' => 'now' |
|
199
|
|
|
]); |
|
200
|
|
|
$items = []; |
|
201
|
|
|
$connectAttributeRepository = $this->manager->getRepository('Shopware\CustomModels\Connect\Attribute'); |
|
202
|
|
|
|
|
203
|
|
|
/** @var \Shopware\Connect\Struct\OrderItem $orderItem */ |
|
204
|
|
|
foreach ($order->products as $orderItem) { |
|
205
|
|
|
$product = $orderItem->product; |
|
206
|
|
|
/** @var \Shopware\CustomModels\Connect\Attribute $connectAttribute */ |
|
207
|
|
|
$connectAttribute = $connectAttributeRepository->findOneBy([ |
|
208
|
|
|
'sourceId' => $product->sourceId, |
|
209
|
|
|
'shopId' => null, |
|
210
|
|
|
]); |
|
211
|
|
|
if (!$connectAttribute) { |
|
212
|
|
|
$this->logger->write( |
|
213
|
|
|
true, |
|
214
|
|
|
sprintf('Detail with sourceId: %s does not exist', $product->sourceId), |
|
215
|
|
|
null, |
|
216
|
|
|
true |
|
217
|
|
|
); |
|
218
|
|
|
continue; |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
/** @var $detail \Shopware\Models\Article\Detail */ |
|
222
|
|
|
$detail = $connectAttribute->getArticleDetail(); |
|
223
|
|
|
/** @var $productModel \Shopware\Models\Article\Article */ |
|
224
|
|
|
$productModel = $detail->getArticle(); |
|
225
|
|
|
$item = new OrderModel\Detail(); |
|
226
|
|
|
$item->fromArray([ |
|
227
|
|
|
'articleId' => $productModel->getId(), |
|
228
|
|
|
'quantity' => $orderItem->count, |
|
229
|
|
|
'orderId' => $model->getId(), |
|
230
|
|
|
'number' => $model->getNumber(), |
|
231
|
|
|
'articleNumber' => $detail->getNumber(), |
|
232
|
|
|
'articleName' => $product->title, |
|
233
|
|
|
'price' => $this->calculatePrice($product), |
|
234
|
|
|
'taxRate' => $product->vat * 100, |
|
235
|
|
|
'status' => $detailStatus, |
|
236
|
|
|
'attribute' => new OrderDetailAttributeModel() |
|
237
|
|
|
]); |
|
238
|
|
|
$items[] = $item; |
|
239
|
|
|
} |
|
240
|
|
|
$model->setDetails($items); |
|
241
|
|
|
|
|
242
|
|
|
$email = $order->billingAddress->email; |
|
243
|
|
|
|
|
244
|
|
|
$password = Random::getAlphanumericString(30); |
|
245
|
|
|
|
|
246
|
|
|
$repository = $this->manager->getRepository('Shopware\Models\Customer\Customer'); |
|
247
|
|
|
$customer = $repository->findOneBy([ |
|
248
|
|
|
'email' => $email |
|
249
|
|
|
]); |
|
250
|
|
|
if ($customer === null) { |
|
251
|
|
|
$customer = new CustomerModel\Customer(); |
|
252
|
|
|
$customer->fromArray([ |
|
253
|
|
|
'active' => true, |
|
254
|
|
|
'email' => $email, |
|
255
|
|
|
'password' => $password, |
|
256
|
|
|
'accountMode' => 1, |
|
257
|
|
|
'shop' => $shop, |
|
258
|
|
|
'paymentId' => $payment->getId(), |
|
259
|
|
|
]); |
|
260
|
|
|
} |
|
261
|
|
|
if ($customer->getBilling() === null) { |
|
262
|
|
|
$billing = new CustomerModel\Billing(); |
|
263
|
|
|
$customer->setBilling($billing); |
|
264
|
|
|
} else { |
|
265
|
|
|
$billing = $customer->getBilling(); |
|
266
|
|
|
} |
|
267
|
|
|
|
|
268
|
|
|
$billing->fromArray($this->getAddressData( |
|
269
|
|
|
$order->billingAddress |
|
270
|
|
|
)); |
|
271
|
|
|
$this->manager->persist($customer); |
|
272
|
|
|
|
|
273
|
|
|
$model->setCustomer($customer); |
|
274
|
|
|
|
|
275
|
|
|
$billing = new OrderModel\Billing(); |
|
276
|
|
|
$billing->setCustomer($customer); |
|
277
|
|
|
$billing->fromArray($this->getAddressData( |
|
278
|
|
|
$order->billingAddress |
|
279
|
|
|
)); |
|
280
|
|
|
$model->setBilling($billing); |
|
281
|
|
|
|
|
282
|
|
|
$shipping = new OrderModel\Shipping(); |
|
283
|
|
|
$shipping->setCustomer($customer); |
|
284
|
|
|
$shipping->fromArray($this->getAddressData( |
|
285
|
|
|
$order->deliveryAddress |
|
286
|
|
|
)); |
|
287
|
|
|
$model->setShipping($shipping); |
|
288
|
|
|
|
|
289
|
|
|
$model->calculateInvoiceAmount(); |
|
290
|
|
|
|
|
291
|
|
|
$dispatchRepository = $this->manager->getRepository('Shopware\Models\Dispatch\Dispatch'); |
|
292
|
|
|
$dispatch = $dispatchRepository->findOneBy([ |
|
293
|
|
|
'name' => $order->shipping->service |
|
294
|
|
|
]); |
|
295
|
|
|
if ($dispatch) { |
|
296
|
|
|
$model->setDispatch($dispatch); |
|
297
|
|
|
} |
|
298
|
|
|
|
|
299
|
|
|
$this->eventManager->notify( |
|
300
|
|
|
'Connect_Supplier_Buy_Before', |
|
301
|
|
|
[ |
|
302
|
|
|
'subject' => $this, |
|
303
|
|
|
'order' => $order |
|
304
|
|
|
] |
|
305
|
|
|
); |
|
306
|
|
|
|
|
307
|
|
|
$this->manager->flush(); |
|
308
|
|
|
|
|
309
|
|
|
return $model->getNumber(); |
|
310
|
|
|
} |
|
311
|
|
|
|
|
312
|
|
|
/** |
|
313
|
|
|
* Calculate the price (including VAT) that the from shop needs to pay. |
|
314
|
|
|
* |
|
315
|
|
|
* This is most likely NOT the price the customer itself has to pay. |
|
316
|
|
|
* |
|
317
|
|
|
* @return float |
|
318
|
|
|
*/ |
|
319
|
|
|
private function calculatePrice($product) |
|
320
|
|
|
{ |
|
321
|
|
|
return $product->purchasePrice * ($product->vat + 1); |
|
322
|
|
|
} |
|
323
|
|
|
|
|
324
|
|
|
/** |
|
325
|
|
|
* @param Address $address |
|
326
|
|
|
* @return array |
|
327
|
|
|
*/ |
|
328
|
|
|
private function getAddressData(Address $address) |
|
329
|
|
|
{ |
|
330
|
|
|
$repository = 'Shopware\Models\Country\Country'; |
|
331
|
|
|
$repository = $this->manager->getRepository($repository); |
|
332
|
|
|
/** @var $country \Shopware\Models\Country\Country */ |
|
333
|
|
|
$country = $repository->findOneBy([ |
|
334
|
|
|
'iso3' => $address->country |
|
335
|
|
|
]); |
|
336
|
|
|
|
|
337
|
|
|
return [ |
|
338
|
|
|
'company' => $address->company ?: '', |
|
339
|
|
|
'department' => $address->department ?: '', |
|
340
|
|
|
'additionalAddressLine1' => $address->additionalAddressLine1 ?: '', |
|
|
|
|
|
|
341
|
|
|
'additionalAddressLine2' => $address->additionalAddressLine2 ?: '', |
|
|
|
|
|
|
342
|
|
|
'salutation' => 'mr', |
|
343
|
|
|
'lastName' => $address->surName, |
|
344
|
|
|
'firstName' => $address->firstName, |
|
345
|
|
|
'city' => $address->city, |
|
346
|
|
|
'zipCode' => $address->zip, |
|
347
|
|
|
'street' => $address->street, |
|
348
|
|
|
'streetNumber' => $address->streetNumber, |
|
349
|
|
|
'phone' => $address->phone, |
|
350
|
|
|
'country' => $country |
|
351
|
|
|
]; |
|
352
|
|
|
} |
|
353
|
|
|
|
|
354
|
|
|
public function updatePaymentStatus(PaymentStatus $status) |
|
355
|
|
|
{ |
|
356
|
|
|
// $paymentStatus->localOrderId is actually ordernumber for this shop |
|
357
|
|
|
// e.g. BP-35-20002 |
|
358
|
|
|
$repository = $this->manager->getRepository('Shopware\Models\Order\Order'); |
|
359
|
|
|
$order = $repository->findOneBy(['number' => $status->localOrderId]); |
|
360
|
|
|
|
|
361
|
|
|
if ($order) { |
|
362
|
|
|
$paymentStatusRepository = $this->manager->getRepository('Shopware\Models\Order\Status'); |
|
363
|
|
|
/** @var \Shopware\Models\Order\Status $orderPaymentStatus */ |
|
364
|
|
|
$orderPaymentStatus = $paymentStatusRepository->findOneBy( |
|
365
|
|
|
['name' => 'sc_' . $status->paymentStatus] |
|
366
|
|
|
); |
|
367
|
|
|
|
|
368
|
|
|
if ($orderPaymentStatus) { |
|
369
|
|
|
$order->setPaymentStatus($orderPaymentStatus); |
|
370
|
|
|
|
|
371
|
|
|
$this->eventManager->notify( |
|
372
|
|
|
'Connect_Supplier_Update_PaymentStatus_Before', |
|
373
|
|
|
[ |
|
374
|
|
|
'subject' => $this, |
|
375
|
|
|
'paymentStatus' => $status, |
|
376
|
|
|
'order' => $order |
|
377
|
|
|
] |
|
378
|
|
|
); |
|
379
|
|
|
|
|
380
|
|
|
$this->manager->persist($order); |
|
381
|
|
|
$this->manager->flush(); |
|
382
|
|
|
} else { |
|
383
|
|
|
$this->logger->write( |
|
384
|
|
|
true, |
|
385
|
|
|
sprintf( |
|
386
|
|
|
'Payment status "%s" not found', |
|
387
|
|
|
$status->paymentStatus |
|
388
|
|
|
), |
|
389
|
|
|
sprintf( |
|
390
|
|
|
'Order with id "%s"', |
|
391
|
|
|
$status->localOrderId |
|
392
|
|
|
) |
|
393
|
|
|
); |
|
394
|
|
|
} |
|
395
|
|
|
} else { |
|
396
|
|
|
$this->logger->write( |
|
397
|
|
|
true, |
|
398
|
|
|
sprintf( |
|
399
|
|
|
'Order with id "%s" not found', |
|
400
|
|
|
$status->localOrderId |
|
401
|
|
|
), |
|
402
|
|
|
serialize($status) |
|
403
|
|
|
); |
|
404
|
|
|
} |
|
405
|
|
|
} |
|
406
|
|
|
|
|
407
|
|
|
public function calculateShippingCosts(Order $order) |
|
408
|
|
|
{ |
|
409
|
|
|
if (!$order->deliveryAddress) { |
|
410
|
|
|
return new Shipping(['isShippable' => false]); |
|
411
|
|
|
} |
|
412
|
|
|
|
|
413
|
|
|
$countryIso3 = $order->deliveryAddress->country; |
|
414
|
|
|
$country = $this->manager->getRepository('Shopware\Models\Country\Country')->findOneBy(['iso3' => $countryIso3]); |
|
415
|
|
|
|
|
416
|
|
|
if (!$country) { |
|
417
|
|
|
return new Shipping(['isShippable' => false]); |
|
418
|
|
|
} |
|
419
|
|
|
|
|
420
|
|
|
if (count($order->orderItems) == 0) { |
|
421
|
|
|
throw new \InvalidArgumentException( |
|
422
|
|
|
'ProductList is not allowed to be empty' |
|
423
|
|
|
); |
|
424
|
|
|
} |
|
425
|
|
|
|
|
426
|
|
|
/* @var \Shopware\Models\Shop\Shop $shop */ |
|
427
|
|
|
$shop = $this->manager->getRepository('Shopware\Models\Shop\Shop')->getActiveDefault(); |
|
428
|
|
|
if (!$shop) { |
|
429
|
|
|
return new Shipping(['isShippable' => false]); |
|
430
|
|
|
} |
|
431
|
|
|
$shop->registerResources(Shopware()->Container()->get('bootstrap')); |
|
432
|
|
|
|
|
433
|
|
|
/** @var /Enlight_Components_Session_Namespace $session */ |
|
|
|
|
|
|
434
|
|
|
$session = Shopware()->Session(); |
|
435
|
|
|
$sessionId = uniqid('connect_remote'); |
|
436
|
|
|
$session->offsetSet('sSESSION_ID', $sessionId); |
|
437
|
|
|
|
|
438
|
|
|
/** @var \Shopware\Models\Dispatch\Dispatch $shipping */ |
|
439
|
|
|
$shipping = $this->manager->getRepository('Shopware\Models\Dispatch\Dispatch')->findOneBy([ |
|
440
|
|
|
'type' => 0 // standard shipping |
|
441
|
|
|
]); |
|
442
|
|
|
|
|
443
|
|
|
// todo: if products are not shippable with default shipping |
|
444
|
|
|
// todo: do we need to check with other shipping methods |
|
445
|
|
|
if (!$shipping) { |
|
446
|
|
|
return new Shipping(['isShippable' => false]); |
|
447
|
|
|
} |
|
448
|
|
|
|
|
449
|
|
|
$session->offsetSet('sDispatch', $shipping->getId()); |
|
450
|
|
|
|
|
451
|
|
|
$repository = $this->manager->getRepository('Shopware\CustomModels\Connect\Attribute'); |
|
452
|
|
|
$products = []; |
|
453
|
|
|
/** @var \Shopware\Connect\Struct\OrderItem $orderItem */ |
|
454
|
|
|
foreach ($order->orderItems as $orderItem) { |
|
455
|
|
|
$attributes = $repository->findBy(['sourceId' => [$orderItem->product->sourceId], 'shopId' => null]); |
|
456
|
|
|
if (count($attributes) === 0) { |
|
457
|
|
|
continue; |
|
458
|
|
|
} |
|
459
|
|
|
|
|
460
|
|
|
$products[] = [ |
|
461
|
|
|
'ordernumber' => $attributes[0]->getArticleDetail()->getNumber(), |
|
462
|
|
|
'quantity' => $orderItem->count, |
|
463
|
|
|
]; |
|
464
|
|
|
} |
|
465
|
|
|
|
|
466
|
|
|
/** @var \Shopware\CustomModels\Connect\Attribute $attribute */ |
|
467
|
|
|
foreach ($products as $product) { |
|
468
|
|
|
Shopware()->Modules()->Basket()->sAddArticle($product['ordernumber'], $product['quantity']); |
|
469
|
|
|
} |
|
470
|
|
|
|
|
471
|
|
|
$result = Shopware()->Modules()->Admin()->sGetPremiumShippingcosts(['id' => $country->getId()]); |
|
472
|
|
|
if (!is_array($result)) { |
|
473
|
|
|
return new Shipping(['isShippable' => false]); |
|
474
|
|
|
} |
|
475
|
|
|
|
|
476
|
|
|
$sql = 'DELETE FROM s_order_basket WHERE sessionID=?'; |
|
477
|
|
|
Shopware()->Db()->executeQuery($sql, [ |
|
478
|
|
|
$sessionId, |
|
479
|
|
|
]); |
|
480
|
|
|
|
|
481
|
|
|
$shippingReturn = new Shipping([ |
|
482
|
|
|
'shopId' => $this->gateway->getShopId(), |
|
483
|
|
|
'service' => $shipping->getName(), |
|
484
|
|
|
'shippingCosts' => floatval($result['netto']), |
|
485
|
|
|
'grossShippingCosts' => floatval($result['brutto']), |
|
486
|
|
|
]); |
|
487
|
|
|
|
|
488
|
|
|
$this->eventManager->notify( |
|
489
|
|
|
'Connect_Supplier_Get_Shipping_After', |
|
490
|
|
|
[ |
|
491
|
|
|
'subject' => $this, |
|
492
|
|
|
'shipping' => $shippingReturn, |
|
493
|
|
|
'order' => $order |
|
494
|
|
|
] |
|
495
|
|
|
); |
|
496
|
|
|
|
|
497
|
|
|
return $shippingReturn; |
|
498
|
|
|
} |
|
499
|
|
|
|
|
500
|
|
|
/** |
|
501
|
|
|
* Perform sync changes to fromShop |
|
502
|
|
|
* |
|
503
|
|
|
* @param string $since |
|
504
|
|
|
* @param \Shopware\Connect\Struct\Change[] $changes |
|
505
|
|
|
* @return void |
|
506
|
|
|
*/ |
|
507
|
|
|
public function onPerformSync($since, array $changes) |
|
508
|
|
|
{ |
|
509
|
|
|
$this->manager->getConnection()->beginTransaction(); |
|
510
|
|
|
|
|
511
|
|
|
$statusSynced = Attribute::STATUS_SYNCED; |
|
512
|
|
|
$statusInsert = Attribute::STATUS_INSERT; |
|
513
|
|
|
$statusUpdate = Attribute::STATUS_UPDATE; |
|
514
|
|
|
$statusDelete = Attribute::STATUS_DELETE; |
|
515
|
|
|
try { |
|
516
|
|
|
$this->manager->getConnection()->executeQuery( |
|
517
|
|
|
"UPDATE s_plugin_connect_items |
|
518
|
|
|
SET export_status = '$statusSynced' |
|
519
|
|
|
WHERE revision <= ? |
|
520
|
|
|
AND ( export_status = '$statusInsert' OR export_status = '$statusUpdate' )", |
|
521
|
|
|
[$since] |
|
522
|
|
|
); |
|
523
|
|
|
|
|
524
|
|
|
$this->manager->getConnection()->executeQuery( |
|
525
|
|
|
"UPDATE s_plugin_connect_items |
|
526
|
|
|
SET export_status = ? |
|
527
|
|
|
WHERE revision <= ? |
|
528
|
|
|
AND export_status = '$statusDelete'", |
|
529
|
|
|
[null, $since] |
|
530
|
|
|
); |
|
531
|
|
|
|
|
532
|
|
|
/** @var \Shopware\Connect\Struct\Change $change */ |
|
533
|
|
|
foreach ($changes as $change) { |
|
534
|
|
|
if (!$change instanceof Insert && !$change instanceof Update && !$change instanceof Availability) { |
|
535
|
|
|
continue; |
|
536
|
|
|
} |
|
537
|
|
|
|
|
538
|
|
|
$this->manager->getConnection()->executeQuery( |
|
539
|
|
|
'UPDATE s_plugin_connect_items |
|
540
|
|
|
SET revision = ? |
|
541
|
|
|
WHERE source_id = ? AND shop_id IS NULL', |
|
542
|
|
|
[$change->revision, $change->sourceId] |
|
543
|
|
|
); |
|
544
|
|
|
} |
|
545
|
|
|
|
|
546
|
|
|
$this->manager->getConnection()->commit(); |
|
547
|
|
|
} catch (\Exception $e) { |
|
548
|
|
|
$this->manager->getConnection()->rollBack(); |
|
549
|
|
|
} |
|
550
|
|
|
|
|
551
|
|
|
try { |
|
552
|
|
|
$this->markStreamsAsSynced(); |
|
553
|
|
|
$this->markStreamsAsNotExported(); |
|
554
|
|
|
} catch (\Exception $e) { |
|
555
|
|
|
$this->logger->write( |
|
556
|
|
|
true, |
|
557
|
|
|
sprintf('Failed to mark streams as synced! Message: "%s". Trace: "%s"', $e->getMessage(), $e->getTraceAsString()), |
|
558
|
|
|
null |
|
559
|
|
|
); |
|
560
|
|
|
} |
|
561
|
|
|
} |
|
562
|
|
|
|
|
563
|
|
View Code Duplication |
private function markStreamsAsNotExported() |
|
|
|
|
|
|
564
|
|
|
{ |
|
565
|
|
|
$streamIds = $this->manager->getConnection()->executeQuery( |
|
566
|
|
|
'SELECT pcs.stream_id as streamId |
|
567
|
|
|
FROM s_plugin_connect_streams as pcs |
|
568
|
|
|
WHERE export_status = ?', |
|
569
|
|
|
[ProductStreamService::STATUS_DELETE] |
|
570
|
|
|
)->fetchAll(); |
|
571
|
|
|
|
|
572
|
|
|
foreach ($streamIds as $stream) { |
|
573
|
|
|
$streamId = $stream['streamId']; |
|
574
|
|
|
|
|
575
|
|
|
$notDeleted = $this->manager->getConnection()->executeQuery( |
|
576
|
|
|
'SELECT pss.id |
|
577
|
|
|
FROM s_product_streams_selection as pss |
|
578
|
|
|
JOIN s_plugin_connect_items as pci |
|
579
|
|
|
ON pss.article_id = pci.article_id |
|
580
|
|
|
WHERE pss.stream_id = ? |
|
581
|
|
|
AND pci.export_status != ?', |
|
582
|
|
|
[$streamId, null] |
|
583
|
|
|
)->fetchAll(); |
|
584
|
|
|
|
|
585
|
|
|
if (count($notDeleted) === 0) { |
|
586
|
|
|
$this->manager->getConnection()->executeQuery( |
|
587
|
|
|
'UPDATE s_plugin_connect_streams |
|
588
|
|
|
SET export_status = ? |
|
589
|
|
|
WHERE stream_id = ?', |
|
590
|
|
|
[null, $streamId] |
|
591
|
|
|
); |
|
592
|
|
|
} |
|
593
|
|
|
} |
|
594
|
|
|
} |
|
595
|
|
|
|
|
596
|
|
View Code Duplication |
private function markStreamsAsSynced() |
|
|
|
|
|
|
597
|
|
|
{ |
|
598
|
|
|
$streamIds = $this->manager->getConnection()->executeQuery( |
|
599
|
|
|
'SELECT pcs.stream_id as streamId |
|
600
|
|
|
FROM s_plugin_connect_streams as pcs |
|
601
|
|
|
WHERE export_status = ?', |
|
602
|
|
|
[ProductStreamService::STATUS_EXPORT] |
|
603
|
|
|
)->fetchAll(); |
|
604
|
|
|
|
|
605
|
|
|
foreach ($streamIds as $stream) { |
|
606
|
|
|
$streamId = $stream['streamId']; |
|
607
|
|
|
|
|
608
|
|
|
$notExported = $this->manager->getConnection()->executeQuery( |
|
609
|
|
|
'SELECT pss.id |
|
610
|
|
|
FROM s_product_streams_selection as pss |
|
611
|
|
|
JOIN s_plugin_connect_items as pci |
|
612
|
|
|
ON pss.article_id = pci.article_id |
|
613
|
|
|
WHERE pss.stream_id = ? |
|
614
|
|
|
AND pci.export_status != ?', |
|
615
|
|
|
[$streamId, Attribute::STATUS_SYNCED] |
|
616
|
|
|
)->fetchAll(); |
|
617
|
|
|
|
|
618
|
|
|
if (count($notExported) === 0) { |
|
619
|
|
|
$this->manager->getConnection()->executeQuery( |
|
620
|
|
|
'UPDATE s_plugin_connect_streams |
|
621
|
|
|
SET export_status = ? |
|
622
|
|
|
WHERE stream_id = ?', |
|
623
|
|
|
[ProductStreamService::STATUS_SYNCED, $streamId] |
|
624
|
|
|
); |
|
625
|
|
|
} |
|
626
|
|
|
} |
|
627
|
|
|
} |
|
628
|
|
|
|
|
629
|
|
|
/** |
|
630
|
|
|
* @param Address $address |
|
631
|
|
|
*/ |
|
632
|
|
|
private function validateBilling(Address $address) |
|
633
|
|
|
{ |
|
634
|
|
|
if (!$address->email) { |
|
635
|
|
|
throw new \RuntimeException('Billing address should contain email'); |
|
636
|
|
|
} |
|
637
|
|
|
|
|
638
|
|
|
if (!$address->firstName) { |
|
639
|
|
|
throw new \RuntimeException('Billing address should contain first name'); |
|
640
|
|
|
} |
|
641
|
|
|
|
|
642
|
|
|
if (!$address->surName) { |
|
643
|
|
|
throw new \RuntimeException('Billing address should contain last name'); |
|
644
|
|
|
} |
|
645
|
|
|
|
|
646
|
|
|
if (!$address->zip) { |
|
647
|
|
|
throw new \RuntimeException('Billing address should contain zip'); |
|
648
|
|
|
} |
|
649
|
|
|
|
|
650
|
|
|
if (!$address->city) { |
|
651
|
|
|
throw new \RuntimeException('Billing address should contain city'); |
|
652
|
|
|
} |
|
653
|
|
|
|
|
654
|
|
|
if (!$address->phone) { |
|
655
|
|
|
throw new \RuntimeException('Billing address should contain phone'); |
|
656
|
|
|
} |
|
657
|
|
|
} |
|
658
|
|
|
} |
|
659
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.