Completed
Pull Request — master (#448)
by Stefan
04:21
created

ProductFromShop   B

Complexity

Total Complexity 52

Size/Duplication

Total Lines 681
Duplicated Lines 15.27 %

Coupling/Cohesion

Components 2
Dependencies 5

Importance

Changes 0
Metric Value
dl 104
loc 681
rs 7.0204
c 0
b 0
f 0
wmc 52
lcom 2
cbo 5

14 Methods

Rating   Name   Duplication   Size   Complexity  
A getExportedProductIDs() 0 4 1
A reserve() 0 10 1
A __construct() 0 13 1
A getProducts() 0 4 1
A buy() 0 17 2
B doBuy() 0 150 6
A calculatePrice() 0 4 1
B getAddressData() 0 25 5
A updatePaymentStatus() 0 52 3
D calculateShippingCosts() 40 130 10
C onPerformSync() 0 74 8
B markStreamsAsNotExported() 32 32 3
B markStreamsAsSynced() 32 32 3
C validateBilling() 0 26 7

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ProductFromShop often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ProductFromShop, and based on these observations, apply Extract Interface, too.

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
use Shopware\Connect\Struct\Message;
29
30
/**
31
 * The interface for products exported *to* connect *from* the local shop
32
 *
33
 * @category  Shopware
34
 * @package   Shopware\Plugins\SwagConnect
35
 */
36
class ProductFromShop implements ProductFromShopBase
37
{
38
    /**
39
     * @var Helper
40
     */
41
    private $helper;
42
43
    /**
44
     * @var ModelManager
45
     */
46
    private $manager;
47
48
    /**
49
     * @var \Shopware\Connect\Gateway
50
     */
51
    private $gateway;
52
53
    /**
54
     * @var Logger
55
     */
56
    private $logger;
57
58
    /**
59
     * @var Enlight_Event_EventManager
60
     */
61
    private $eventManager;
62
63
    /**
64
     * @param Helper $helper
65
     * @param ModelManager $manager
66
     * @param Gateway $gateway
67
     * @param Logger $logger
68
     * @param Enlight_Event_EventManager $eventManager
69
     */
70
    public function __construct(
71
        Helper $helper,
72
        ModelManager $manager,
73
        Gateway $gateway,
74
        Logger $logger,
75
        Enlight_Event_EventManager $eventManager
76
    ) {
77
        $this->helper = $helper;
78
        $this->manager = $manager;
79
        $this->gateway = $gateway;
80
        $this->logger = $logger;
81
        $this->eventManager = $eventManager;
82
    }
83
84
    /**
85
     * Get product data
86
     *
87
     * Get product data for all the source IDs specified in the given string
88
     * array.
89
     *
90
     * @param string[] $sourceIds
91
     * @return Product[]
92
     */
93
    public function getProducts(array $sourceIds)
94
    {
95
        return $this->helper->getLocalProduct($sourceIds);
96
    }
97
98
    /**
99
     * Get all IDs of all exported products
100
     *
101
     * @throws \BadMethodCallException
102
     * @return string[]
103
     */
104
    public function getExportedProductIDs()
105
    {
106
        throw new \BadMethodCallException('Not implemented');
107
    }
108
109
    /**
110
     * Reserve a product in shop for purchase
111
     *
112
     * @param Order $order
113
     * @throws \Exception Abort reservation by throwing an exception here.
114
     * @return void
115
     */
116
    public function reserve(Order $order)
117
    {
118
        $this->eventManager->notify(
119
            'Connect_Supplier_Reservation_Before',
120
            [
121
                'subject' => $this,
122
                'order' => $order
123
            ]
124
        );
125
    }
126
127
    /**
128
     * Create order in shopware
129
     * Wraps the actual order process into a transaction
130
     *
131
     *
132
     * @param Order $order
133
     * @throws \Exception Abort buy by throwing an exception,
134
     *                    but only in very important cases.
135
     *                    Do validation in {@see reserve} instead.
136
     * @return string
137
     */
138
    public function buy(Order $order)
139
    {
140
        $this->manager->beginTransaction();
141
        try {
142
            $order = $this->eventManager->filter('Connect_Components_ProductFromShop_Buy_OrderFilter', $order);
143
144
            $this->validateBilling($order->billingAddress);
145
            $orderNumber = $this->doBuy($order);
146
147
            $this->manager->commit();
148
        } catch (\Exception $e) {
149
            $this->manager->rollback();
150
            throw $e;
151
        }
152
153
        return $orderNumber;
154
    }
155
156
    /**
157
     * Actually creates the remote order in shopware.
158
     *
159
     * @param Order $order
160
     * @return string
161
     */
162
    public function doBuy(Order $order)
163
    {
164
        $this->manager->clear();
165
166
        $detailStatus = $this->manager->find('Shopware\Models\Order\DetailStatus', 0);
167
        $status = $this->manager->find('Shopware\Models\Order\Status', 0);
168
        $shop = $this->manager->find('Shopware\Models\Shop\Shop', 1);
169
        $number = 'SC-' . $order->orderShop . '-' . $order->localOrderId;
170
171
        $repository = $this->manager->getRepository('Shopware\Models\Payment\Payment');
172
        $payment = $repository->findOneBy([
173
            'name' => 'invoice',
174
        ]);
175
176
        // todo: Create the OrderModel without previous plain SQL
177
        //$model = new OrderModel\Order();
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

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.

Loading history...
178
        $sql = 'INSERT INTO `s_order` (`ordernumber`, `cleared`) VALUES (?, 17);';
179
        Shopware()->Db()->query($sql, [$number]);
180
        $modelId = Shopware()->Db()->lastInsertId();
181
        /** @var $model \Shopware\Models\Order\Order */
182
        $model = $this->manager->find('Shopware\Models\Order\Order', $modelId);
183
184
        $attribute = new \Shopware\Models\Attribute\Order;
185
        $attribute->setConnectOrderId($order->localOrderId);
186
        $attribute->setConnectShopId($order->orderShop);
187
        $model->setAttribute($attribute);
188
189
        $model->fromArray([
190
            'number' => $number,
191
            'invoiceShipping' => $order->grossShippingCosts,
0 ignored issues
show
Bug introduced by
The property grossShippingCosts does not seem to exist. Did you mean shipping?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
192
            'invoiceShippingNet' => $order->shippingCosts,
0 ignored issues
show
Bug introduced by
The property shippingCosts does not seem to exist. Did you mean shipping?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
193
            'currencyFactor' => 1,
194
            'orderStatus' => $status,
195
            'shop' => $shop,
196
            'languageSubShop' => $shop,
197
            'payment' => $payment,
198
            'currency' => 'EUR',
199
            'orderTime' => 'now'
200
        ]);
201
        $items = [];
202
        $connectAttributeRepository = $this->manager->getRepository('Shopware\CustomModels\Connect\Attribute');
203
204
        /** @var \Shopware\Connect\Struct\OrderItem $orderItem */
205
        foreach ($order->products as $orderItem) {
206
            $product = $orderItem->product;
207
            /** @var \Shopware\CustomModels\Connect\Attribute $connectAttribute */
208
            $connectAttribute = $connectAttributeRepository->findOneBy([
209
                'sourceId' => $product->sourceId,
210
                'shopId' => null,
211
            ]);
212
            if (!$connectAttribute) {
213
                $this->logger->write(
214
                    true,
215
                    sprintf('Detail with sourceId: %s does not exist', $product->sourceId),
216
                    null,
217
                    true
218
                );
219
                continue;
220
            }
221
222
            /** @var $detail \Shopware\Models\Article\Detail */
223
            $detail = $connectAttribute->getArticleDetail();
224
            /** @var $productModel \Shopware\Models\Article\Article */
225
            $productModel = $detail->getArticle();
226
            $item = new OrderModel\Detail();
227
            $item->fromArray([
228
                'articleId' => $productModel->getId(),
229
                'quantity' => $orderItem->count,
230
                'orderId' => $model->getId(),
231
                'number' => $model->getNumber(),
232
                'articleNumber' => $detail->getNumber(),
233
                'articleName' => $product->title,
234
                'price' => $this->calculatePrice($product),
235
                'taxRate' => $product->vat * 100,
236
                'status' => $detailStatus,
237
                'attribute' => new OrderDetailAttributeModel()
238
            ]);
239
            $items[] = $item;
240
        }
241
        $model->setDetails($items);
242
243
        $email = $order->billingAddress->email;
244
245
        $password = Random::getAlphanumericString(30);
246
247
        $repository = $this->manager->getRepository('Shopware\Models\Customer\Customer');
248
        $customer = $repository->findOneBy([
249
            'email' => $email
250
        ]);
251
        if ($customer === null) {
252
            $customer = new CustomerModel\Customer();
253
            $customer->fromArray([
254
                'active' => true,
255
                'email' => $email,
256
                'password' => $password,
257
                'accountMode' => 1,
258
                'shop' => $shop,
259
                'paymentId' => $payment->getId(),
260
            ]);
261
        }
262
        if ($customer->getBilling() === null) {
263
            $billing = new CustomerModel\Billing();
264
            $customer->setBilling($billing);
265
        } else {
266
            $billing = $customer->getBilling();
267
        }
268
269
        $billing->fromArray($this->getAddressData(
270
            $order->billingAddress
271
        ));
272
        $this->manager->persist($customer);
273
274
        $model->setCustomer($customer);
275
276
        $billing = new OrderModel\Billing();
277
        $billing->setCustomer($customer);
278
        $billing->fromArray($this->getAddressData(
279
                $order->billingAddress
280
        ));
281
        $model->setBilling($billing);
282
283
        $shipping = new OrderModel\Shipping();
284
        $shipping->setCustomer($customer);
285
        $shipping->fromArray($this->getAddressData(
286
            $order->deliveryAddress
287
        ));
288
        $model->setShipping($shipping);
289
290
        $model->calculateInvoiceAmount();
291
292
        $dispatchRepository = $this->manager->getRepository('Shopware\Models\Dispatch\Dispatch');
293
        $dispatch = $dispatchRepository->findOneBy([
294
            'name' => $order->shipping->service
295
        ]);
296
        if ($dispatch) {
297
            $model->setDispatch($dispatch);
298
        }
299
300
        $this->eventManager->notify(
301
            'Connect_Supplier_Buy_Before',
302
            [
303
                'subject' => $this,
304
                'order' => $order
305
            ]
306
        );
307
308
        $this->manager->flush();
309
310
        return $model->getNumber();
311
    }
312
313
    /**
314
     * Calculate the price (including VAT) that the from shop needs to pay.
315
     *
316
     * This is most likely NOT the price the customer itself has to pay.
317
     *
318
     * @return float
319
     */
320
    private function calculatePrice($product)
321
    {
322
        return $product->purchasePrice * ($product->vat + 1);
323
    }
324
325
    /**
326
     * @param Address $address
327
     * @return array
328
     */
329
    private function getAddressData(Address $address)
330
    {
331
        $repository = 'Shopware\Models\Country\Country';
332
        $repository = $this->manager->getRepository($repository);
333
        /** @var $country \Shopware\Models\Country\Country */
334
        $country = $repository->findOneBy([
335
            'iso3' => $address->country
336
        ]);
337
338
        return [
339
            'company' => $address->company ?: '',
340
            'department' => $address->department ?: '',
341
            'additionalAddressLine1' => $address->additionalAddressLine1 ?: '',
342
            'additionalAddressLine2' => $address->additionalAddressLine2 ?: '',
343
            'salutation' => 'mr',
344
            'lastName' => $address->surName,
345
            'firstName' => $address->firstName,
346
            'city' => $address->city,
347
            'zipCode' => $address->zip,
348
            'street' => $address->street,
349
            'streetNumber' => $address->streetNumber,
350
            'phone' => $address->phone,
351
            'country' => $country
352
        ];
353
    }
354
355
    public function updatePaymentStatus(PaymentStatus $status)
356
    {
357
        // $paymentStatus->localOrderId is actually ordernumber for this shop
358
        // e.g. BP-35-20002
359
        $repository = $this->manager->getRepository('Shopware\Models\Order\Order');
360
        $order = $repository->findOneBy(['number' => $status->localOrderId]);
361
362
        if ($order) {
363
            $paymentStatusRepository = $this->manager->getRepository('Shopware\Models\Order\Status');
364
            /** @var \Shopware\Models\Order\Status $orderPaymentStatus */
365
            $orderPaymentStatus = $paymentStatusRepository->findOneBy(
366
                ['name' => 'sc_' . $status->paymentStatus]
367
            );
368
369
            if ($orderPaymentStatus) {
370
                $order->setPaymentStatus($orderPaymentStatus);
371
372
                $this->eventManager->notify(
373
                    'Connect_Supplier_Update_PaymentStatus_Before',
374
                    [
375
                        'subject' => $this,
376
                        'paymentStatus' => $status,
377
                        'order' => $order
378
                    ]
379
                );
380
381
                $this->manager->persist($order);
382
                $this->manager->flush();
383
            } else {
384
                $this->logger->write(
385
                    true,
386
                    sprintf(
387
                        'Payment status "%s" not found',
388
                        $status->paymentStatus
389
                    ),
390
                    sprintf(
391
                        'Order with id "%s"',
392
                        $status->localOrderId
393
                    )
394
                );
395
            }
396
        } else {
397
            $this->logger->write(
398
                true,
399
                sprintf(
400
                    'Order with id "%s" not found',
401
                    $status->localOrderId
402
                ),
403
                serialize($status)
404
            );
405
        }
406
    }
407
408
    public function calculateShippingCosts(Order $order)
409
    {
410 View Code Duplication
        if (!$order->deliveryAddress) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
411
            return new Shipping([
412
                'isShippable' => false,
413
                'messages' => [
414
                    new Message([
415
                        'message' => 'Delivery address could not be empty'
416
                    ])
417
                ]
418
            ]);
419
        }
420
421
        $countryIso3 = $order->deliveryAddress->country;
422
        $country = $this->manager->getRepository('Shopware\Models\Country\Country')->findOneBy(['iso3' => $countryIso3]);
423
424
        if (!$country) {
425
            return new Shipping([
426
                'isShippable' => false,
427
                'messages' => [
428
                    new Message([
429
                        'message' => 'Order could not be shipped to %country',
430
                        'values' => [
431
                            'country' => $countryIso3,
432
                        ]
433
                    ])
434
                ]
435
            ]);
436
        }
437
438
        if (count($order->orderItems) == 0) {
439
            throw new \InvalidArgumentException(
440
                'ProductList is not allowed to be empty'
441
            );
442
        }
443
444
        /* @var \Shopware\Models\Shop\Shop $shop */
445
        $shop = $this->manager->getRepository('Shopware\Models\Shop\Shop')->getActiveDefault();
446 View Code Duplication
        if (!$shop) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
447
            return new Shipping([
448
                'isShippable' => false,
449
                'messages' => [
450
                    new Message([
451
                        'message' => 'Default shop could not be found'
452
                    ])
453
                ]
454
            ]);
455
        }
456
        $shop->registerResources(Shopware()->Container()->get('bootstrap'));
457
458
        /** @var /Enlight_Components_Session_Namespace $session */
0 ignored issues
show
Documentation introduced by
The doc-type /Enlight_Components_Session_Namespace could not be parsed: Unknown type name "/Enlight_Components_Session_Namespace" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
459
        $session = Shopware()->Session();
460
        $sessionId = uniqid('connect_remote');
461
        $session->offsetSet('sSESSION_ID', $sessionId);
462
463
        /** @var \Shopware\Models\Dispatch\Dispatch $shipping */
464
        $shipping = $this->manager->getRepository('Shopware\Models\Dispatch\Dispatch')->findOneBy([
465
            'type' => 0 // standard shipping
466
        ]);
467
468
        // todo: if products are not shippable with default shipping
469
        // todo: do we need to check with other shipping methods
470 View Code Duplication
        if (!$shipping) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
471
            return new Shipping([
472
                'isShippable' => false,
473
                'messages' => [
474
                    new Message([
475
                        'message' => 'Default shipping could not be found'
476
                    ])
477
                ]
478
            ]);
479
        }
480
481
        $session->offsetSet('sDispatch', $shipping->getId());
482
483
        $repository = $this->manager->getRepository('Shopware\CustomModels\Connect\Attribute');
484
        $products = [];
485
        /** @var \Shopware\Connect\Struct\OrderItem $orderItem */
486
        foreach ($order->orderItems as $orderItem) {
487
            $attributes = $repository->findBy(['sourceId' => [$orderItem->product->sourceId], 'shopId' => null]);
488
            if (count($attributes) === 0) {
489
                continue;
490
            }
491
492
            $products[] = [
493
                'ordernumber' => $attributes[0]->getArticleDetail()->getNumber(),
494
                'quantity' => $orderItem->count,
495
            ];
496
        }
497
498
        /** @var \Shopware\CustomModels\Connect\Attribute $attribute */
499
        foreach ($products as $product) {
500
            Shopware()->Modules()->Basket()->sAddArticle($product['ordernumber'], $product['quantity']);
501
        }
502
503
        $result = Shopware()->Modules()->Admin()->sGetPremiumShippingcosts(['id' => $country->getId()]);
504 View Code Duplication
        if (!is_array($result)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
505
            return new Shipping([
506
                'isShippable' => false,
507
                'messages' => [
508
                    new Message([
509
                        'message' => 'Checkout is not possible at the moment possible reasons are: inactive product, removed product, etc.'
510
                    ])
511
                ]
512
            ]);
513
        }
514
515
        $sql = 'DELETE FROM s_order_basket WHERE sessionID=?';
516
        Shopware()->Db()->executeQuery($sql, [
517
            $sessionId,
518
        ]);
519
520
        $shippingReturn = new Shipping([
521
            'shopId' => $this->gateway->getShopId(),
522
            'service' => $shipping->getName(),
523
            'shippingCosts' => floatval($result['netto']),
524
            'grossShippingCosts' => floatval($result['brutto']),
525
        ]);
526
527
        $this->eventManager->notify(
528
            'Connect_Supplier_Get_Shipping_After',
529
            [
530
                'subject' => $this,
531
                'shipping' => $shippingReturn,
532
                'order' => $order
533
            ]
534
        );
535
536
        return $shippingReturn;
537
    }
538
539
    /**
540
     * Perform sync changes to fromShop
541
     *
542
     * @param string $since
543
     * @param \Shopware\Connect\Struct\Change[] $changes
544
     * @return void
545
     */
546
    public function onPerformSync($since, array $changes)
547
    {
548
        $this->manager->getConnection()->beginTransaction();
549
550
        $statusSynced = Attribute::STATUS_SYNCED;
551
        $statusInsert = Attribute::STATUS_INSERT;
552
        $statusUpdate = Attribute::STATUS_UPDATE;
553
        $statusDelete = Attribute::STATUS_DELETE;
554
        try {
555
            if ($since) {
556
                $this->manager->getConnection()->executeQuery(
557
                    'UPDATE s_plugin_connect_items
558
                    SET export_status = ?
559
                    WHERE revision <= ?
560
                    AND ( export_status = ? OR export_status = ? )',
561
                    [$statusSynced, $since, $statusInsert, $statusUpdate]
562
                );
563
564
                $this->manager->getConnection()->executeQuery(
565
                    'UPDATE s_plugin_connect_items
566
                    SET export_status = ?
567
                    WHERE revision <= ?
568
                    AND export_status = ?',
569
                    [null, $since, $statusDelete]
570
                );
571
            } else {
572
                $this->manager->getConnection()->executeQuery(
573
                    'UPDATE s_plugin_connect_items
574
                    SET export_status = ?
575
                    WHERE revision IS NULL
576
                    AND ( export_status = ? OR export_status = ? )',
577
                    [$statusSynced, $statusInsert, $statusUpdate]
578
                );
579
580
                $this->manager->getConnection()->executeQuery(
581
                    'UPDATE s_plugin_connect_items
582
                    SET export_status = ?
583
                    WHERE revision IS NULL
584
                    AND export_status = ?',
585
                    [null, $statusDelete]
586
                );
587
            }
588
589
590
            /** @var \Shopware\Connect\Struct\Change $change */
591
            foreach ($changes as $change) {
592
                if (!$change instanceof Insert && !$change instanceof Update && !$change instanceof Availability) {
593
                    continue;
594
                }
595
596
                $this->manager->getConnection()->executeQuery(
597
                    'UPDATE s_plugin_connect_items
598
                    SET revision = ?
599
                    WHERE source_id = ? AND shop_id IS NULL',
600
                    [$change->revision, $change->sourceId]
601
                );
602
            }
603
604
            $this->manager->getConnection()->commit();
605
        } catch (\Exception $e) {
606
            $this->manager->getConnection()->rollBack();
607
        }
608
609
        try {
610
            $this->markStreamsAsSynced();
611
            $this->markStreamsAsNotExported();
612
        } catch (\Exception $e) {
613
            $this->logger->write(
614
                true,
615
                sprintf('Failed to mark streams as synced! Message: "%s". Trace: "%s"', $e->getMessage(), $e->getTraceAsString()),
616
                null
617
            );
618
        }
619
    }
620
621 View Code Duplication
    private function markStreamsAsNotExported()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
622
    {
623
        $streamIds = $this->manager->getConnection()->executeQuery(
624
            'SELECT pcs.stream_id as streamId
625
             FROM s_plugin_connect_streams as pcs
626
             WHERE export_status = ?',
627
            [ProductStreamService::STATUS_DELETE]
628
        )->fetchAll();
629
630
        foreach ($streamIds as $stream) {
631
            $streamId = $stream['streamId'];
632
633
            $notDeleted = $this->manager->getConnection()->executeQuery(
634
                'SELECT pss.id
635
                 FROM s_product_streams_selection as pss
636
                 JOIN s_plugin_connect_items as pci
637
                 ON pss.article_id = pci.article_id
638
                 WHERE pss.stream_id = ?
639
                 AND pci.export_status != ?',
640
                [$streamId, null]
641
            )->fetchAll();
642
643
            if (count($notDeleted) === 0) {
644
                $this->manager->getConnection()->executeQuery(
645
                    'UPDATE s_plugin_connect_streams
646
                     SET export_status = ?
647
                     WHERE stream_id = ?',
648
                    [null, $streamId]
649
                );
650
            }
651
        }
652
    }
653
654 View Code Duplication
    private function markStreamsAsSynced()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
655
    {
656
        $streamIds = $this->manager->getConnection()->executeQuery(
657
            'SELECT pcs.stream_id as streamId
658
             FROM s_plugin_connect_streams as pcs
659
             WHERE export_status = ?',
660
            [ProductStreamService::STATUS_EXPORT]
661
        )->fetchAll();
662
663
        foreach ($streamIds as $stream) {
664
            $streamId = $stream['streamId'];
665
666
            $notExported = $this->manager->getConnection()->executeQuery(
667
                'SELECT pss.id
668
                 FROM s_product_streams_selection as pss
669
                 JOIN s_plugin_connect_items as pci
670
                 ON pss.article_id = pci.article_id
671
                 WHERE pss.stream_id = ?
672
                 AND pci.export_status != ?',
673
                [$streamId, Attribute::STATUS_SYNCED]
674
            )->fetchAll();
675
676
            if (count($notExported) === 0) {
677
                $this->manager->getConnection()->executeQuery(
678
                    'UPDATE s_plugin_connect_streams
679
                     SET export_status = ?
680
                     WHERE stream_id = ?',
681
                    [ProductStreamService::STATUS_SYNCED, $streamId]
682
                );
683
            }
684
        }
685
    }
686
687
    /**
688
     * @param Address $address
689
     */
690
    private function validateBilling(Address $address)
691
    {
692
        if (!$address->email) {
693
            throw new \RuntimeException('Billing address should contain email');
694
        }
695
696
        if (!$address->firstName) {
697
            throw new \RuntimeException('Billing address should contain first name');
698
        }
699
700
        if (!$address->surName) {
701
            throw new \RuntimeException('Billing address should contain last name');
702
        }
703
704
        if (!$address->zip) {
705
            throw new \RuntimeException('Billing address should contain zip');
706
        }
707
708
        if (!$address->city) {
709
            throw new \RuntimeException('Billing address should contain city');
710
        }
711
712
        if (!$address->phone) {
713
            throw new \RuntimeException('Billing address should contain phone');
714
        }
715
    }
716
}
717