ShoppingService::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.ec-cube.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
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 General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
23
24
namespace Eccube\Service;
25
26
use Doctrine\DBAL\LockMode;
27
use Eccube\Application;
28
use Eccube\Common\Constant;
29
use Eccube\Entity\Customer;
30
use Eccube\Entity\Delivery;
31
use Eccube\Entity\MailHistory;
32
use Eccube\Entity\Master\DeviceType;
33
use Eccube\Entity\Order;
34
use Eccube\Entity\OrderDetail;
35
use Eccube\Entity\Product;
36
use Eccube\Entity\ProductClass;
37
use Eccube\Entity\ShipmentItem;
38
use Eccube\Entity\Shipping;
39
use Eccube\Event\EccubeEvents;
40
use Eccube\Event\EventArgs;
41
use Eccube\Exception\CartException;
42
use Eccube\Exception\ShoppingException;
43
use Eccube\Util\Str;
44
45
46
class ShoppingService
47
{
48
    /** @var \Eccube\Application */
49
    public $app;
50
51
    /** @var \Eccube\Service\CartService */
52
    protected $cartService;
53
54
    /** @var \Eccube\Service\OrderService */
55
    protected $orderService;
56
57
    /** @var \Eccube\Entity\BaseInfo */
58
    protected $BaseInfo;
59
60
    /** @var  \Doctrine\ORM\EntityManager */
61
    protected $em;
62
63
    public function __construct(Application $app, $cartService, $orderService)
64
    {
65
        $this->app = $app;
66
        $this->cartService = $cartService;
67
        $this->orderService = $orderService;
68
        $this->BaseInfo = $app['eccube.repository.base_info']->get();
69
    }
70
71
    /**
72
     * セッションにセットされた受注情報を取得
73
     *
74
     * @param null $status
75
     * @return null|object
76
     */
77
    public function getOrder($status = null)
78
    {
79
80
        // 受注データを取得
81
        $preOrderId = $this->cartService->getPreOrderId();
82
        if (!$preOrderId) {
83
            return null;
84
        }
85
86
        $condition = array(
87
            'pre_order_id' => $preOrderId,
88
        );
89
90
        if (!is_null($status)) {
91
            $condition += array(
92
                'OrderStatus' => $status,
93
            );
94
        }
95
96
        $Order = $this->app['eccube.repository.order']->findOneBy($condition);
97
98
        return $Order;
99
100
    }
101
102
    /**
103
     * 非会員情報を取得
104
     *
105
     * @param $sesisonKey
106
     * @return $Customer|null
0 ignored issues
show
Documentation introduced by
The doc-type $Customer|null could not be parsed: Unknown type name "$Customer" 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...
107
     */
108
    public function getNonMember($sesisonKey)
109
    {
110
111
        // 非会員でも一度会員登録されていればショッピング画面へ遷移
112
        $nonMember = $this->app['session']->get($sesisonKey);
113
        if (is_null($nonMember)) {
114
            return null;
115
        }
116
        if (!array_key_exists('customer', $nonMember) || !array_key_exists('pref', $nonMember)) {
117
            return null;
118
        }
119
120
        $Customer = $nonMember['customer'];
121
        $Customer->setPropertiesFromArray($nonMember, array('customer', 'id', 'pref', 'email', 'password', 'salt'));
122
        $Customer->setPref($this->app['eccube.repository.master.pref']->find($nonMember['pref']));
123
        return $Customer;
124
    }
125
126
    /**
127
     * 非会員情報をセッションに設定する
128
     *
129
     * @param $sesisonKey
130
     * @param Customer $Customer
131
     * @return ShoppingService
132
     */
133
    public function setNonMember($sessionKey, Customer $Customer)
134
    {
135
        $nonMember = $Customer->toArray(array('id', 'email', 'password', 'salt'));
136
        $nonMember['pref'] = $Customer->getPref()->getId();
137
        $nonMember['customer'] = $Customer; // Customer::serialize() で対象となっているプロパティのみ保存される
138
        $this->app['session']->set($sessionKey, $nonMember);
139
140
        return $this;
141
    }
142
143
    /**
144
     * 受注情報を作成
145
     *
146
     * @param $Customer
147
     * @return \Eccube\Entity\Order
148
     */
149
    public function createOrder($Customer)
150
    {
151
        // ランダムなpre_order_idを作成
152
        do {
153
            $preOrderId = sha1(Str::random(32));
154
            $Order = $this->app['eccube.repository.order']->findOneBy(array(
155
                'pre_order_id' => $preOrderId,
156
                'OrderStatus' => $this->app['config']['order_processing'],
157
            ));
158
        } while ($Order);
159
160
        // 受注情報、受注明細情報、お届け先情報、配送商品情報を作成
161
        $Order = $this->registerPreOrder(
162
            $Customer,
163
            $preOrderId);
164
165
        $this->cartService->setPreOrderId($preOrderId);
166
        $this->cartService->save();
167
168
        return $Order;
169
    }
170
171
    /**
172
     * 仮受注情報作成
173
     *
174
     * @param $Customer
175
     * @param $preOrderId
176
     * @return mixed
177
     * @throws \Doctrine\ORM\NoResultException
178
     * @throws \Doctrine\ORM\NonUniqueResultException
179
     */
180
    public function registerPreOrder(Customer $Customer, $preOrderId)
181
    {
182
183
        $this->em = $this->app['orm.em'];
184
185
        // 受注情報を作成
186
        $Order = $this->getNewOrder($Customer);
187
        $Order->setPreOrderId($preOrderId);
188
189
        // device type
190
        if ($this->app['mobile_detect']->isMobile()) {
191
            $DeviceType = $this->app['eccube.repository.master.device_type']->find(DeviceType::DEVICE_TYPE_SP);
192
        } else {
193
            $DeviceType = $this->app['eccube.repository.master.device_type']->find(DeviceType::DEVICE_TYPE_PC);
194
        }
195
        $Order->setDeviceType($DeviceType);
196
197
        $this->em->persist($Order);
198
199
        // 配送業者情報を取得
200
        $deliveries = $this->getDeliveriesCart();
201
202
        // お届け先情報を作成
203
        $Order = $this->getNewShipping($Order, $Customer, $deliveries);
204
205
        // 受注明細情報、配送商品情報を作成
206
        $Order = $this->getNewDetails($Order);
207
208
        // 小計
209
        $subTotal = $this->orderService->getSubTotal($Order);
0 ignored issues
show
Deprecated Code introduced by
The method Eccube\Service\OrderService::getSubTotal() has been deprecated with message: since 3.0.0, to be removed in 3.1

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
210
211
        // 消費税のみの小計
212
        $tax = $this->orderService->getTotalTax($Order);
0 ignored issues
show
Deprecated Code introduced by
The method Eccube\Service\OrderService::getTotalTax() has been deprecated with message: since 3.0.0, to be removed in 3.1

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
213
214
        // 配送料合計金額
215
        $Order->setDeliveryFeeTotal($this->getShippingDeliveryFeeTotal($Order->getShippings()));
216
217
        // 小計
218
        $Order->setSubTotal($subTotal);
219
220
        // 配送料無料条件(合計金額)
221
        $this->setDeliveryFreeAmount($Order);
222
223
        // 配送料無料条件(合計数量)
224
        $this->setDeliveryFreeQuantity($Order);
225
226
        // 初期選択の支払い方法をセット
227
        $payments = $this->app['eccube.repository.payment']->findAllowedPayments($deliveries);
228
        $payments = $this->getPayments($payments, $subTotal);
229
230
        if (count($payments) > 0) {
231
            $payment = $payments[0];
232
            $Order->setPayment($payment);
233
            $Order->setPaymentMethod($payment->getMethod());
234
            $Order->setCharge($payment->getCharge());
235
        } else {
236
            $Order->setCharge(0);
237
        }
238
239
        $Order->setTax($tax);
240
241
        // 合計金額の計算
242
        $this->calculatePrice($Order);
243
244
        $this->em->flush();
245
246
        return $Order;
247
248
    }
249
250
    /**
251
     * 受注情報を作成
252
     *
253
     * @param $Customer
254
     * @return \Eccube\Entity\Order
255
     */
256
    public function getNewOrder(Customer $Customer)
257
    {
258
        $Order = $this->newOrder();
259
        $this->copyToOrderFromCustomer($Order, $Customer);
260
261
        return $Order;
262
    }
263
264
265
    /**
266
     * 受注情報を作成
267
     *
268
     * @return \Eccube\Entity\Order
269
     */
270
    public function newOrder()
271
    {
272
        $OrderStatus = $this->app['eccube.repository.order_status']->find($this->app['config']['order_processing']);
273
        $Order = new \Eccube\Entity\Order($OrderStatus);
274
275
        return $Order;
276
    }
277
278
    /**
279
     * 受注情報を作成
280
     *
281
     * @param \Eccube\Entity\Order $Order
282
     * @param \Eccube\Entity\Customer|null $Customer
283
     * @return \Eccube\Entity\Order
284
     */
285
    public function copyToOrderFromCustomer(Order $Order, Customer $Customer = null)
286
    {
287
        if (is_null($Customer)) {
288
            return $Order;
289
        }
290
291
        if ($Customer->getId()) {
292
            $Order->setCustomer($Customer);
293
        }
294
        $Order
295
            ->setName01($Customer->getName01())
296
            ->setName02($Customer->getName02())
297
            ->setKana01($Customer->getKana01())
298
            ->setKana02($Customer->getKana02())
299
            ->setCompanyName($Customer->getCompanyName())
300
            ->setEmail($Customer->getEmail())
301
            ->setTel01($Customer->getTel01())
302
            ->setTel02($Customer->getTel02())
303
            ->setTel03($Customer->getTel03())
304
            ->setFax01($Customer->getFax01())
305
            ->setFax02($Customer->getFax02())
306
            ->setFax03($Customer->getFax03())
307
            ->setZip01($Customer->getZip01())
308
            ->setZip02($Customer->getZip02())
309
            ->setZipCode($Customer->getZip01().$Customer->getZip02())
310
            ->setPref($Customer->getPref())
311
            ->setAddr01($Customer->getAddr01())
312
            ->setAddr02($Customer->getAddr02())
313
            ->setSex($Customer->getSex())
314
            ->setBirth($Customer->getBirth())
315
            ->setJob($Customer->getJob());
316
317
        return $Order;
318
    }
319
320
321
    /**
322
     * 配送業者情報を取得
323
     *
324
     * @return array
325
     */
326
    public function getDeliveriesCart()
327
    {
328
329
        // カートに保持されている商品種別を取得
330
        $productTypes = $this->cartService->getProductTypes();
331
332
        return $this->getDeliveries($productTypes);
333
334
    }
335
336
    /**
337
     * 配送業者情報を取得
338
     *
339
     * @param Order $Order
340
     * @return array
341
     */
342
    public function getDeliveriesOrder(Order $Order)
343
    {
344
345
        // 受注情報から商品種別を取得
346
        $productTypes = $this->orderService->getProductTypes($Order);
0 ignored issues
show
Deprecated Code introduced by
The method Eccube\Service\OrderService::getProductTypes() has been deprecated with message: since 3.0.0, to be removed in 3.1

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
347
348
        return $this->getDeliveries($productTypes);
349
350
    }
351
352
    /**
353
     * 配送業者情報を取得
354
     *
355
     * @param $productTypes
356
     * @return array
357
     */
358
    public function getDeliveries($productTypes)
359
    {
360
361
        // 商品種別に紐づく配送業者を取得
362
        $deliveries = $this->app['eccube.repository.delivery']->getDeliveries($productTypes);
363
364
        if ($this->BaseInfo->getOptionMultipleShipping() == Constant::ENABLED) {
365
            // 複数配送対応
366
367
            // 支払方法を取得
368
            $payments = $this->app['eccube.repository.payment']->findAllowedPayments($deliveries);
369
370
            if (count($productTypes) > 1) {
371
                // 商品種別が複数ある場合、配送対象となる配送業者を取得
372
                $deliveries = $this->app['eccube.repository.delivery']->findAllowedDeliveries($productTypes, $payments);
373
            }
374
375
        }
376
377
        return $deliveries;
378
379
    }
380
381
382
    /**
383
     * お届け先情報を作成
384
     *
385
     * @param Order $Order
386
     * @param Customer $Customer
387
     * @param $deliveries
388
     * @return Order
389
     */
390
    public function getNewShipping(Order $Order, Customer $Customer, $deliveries)
391
    {
392
        $productTypes = array();
393
        foreach ($deliveries as $Delivery) {
394
            if (!in_array($Delivery->getProductType()->getId(), $productTypes)) {
395
                $Shipping = new Shipping();
396
397
                $this->copyToShippingFromCustomer($Shipping, $Customer)
398
                    ->setOrder($Order)
399
                    ->setDelFlg(Constant::DISABLED);
400
401
                // 配送料金の設定
402
                $this->setShippingDeliveryFee($Shipping, $Delivery);
403
404
                $this->em->persist($Shipping);
405
406
                $Order->addShipping($Shipping);
407
408
                $productTypes[] = $Delivery->getProductType()->getId();
409
            }
410
        }
411
412
        return $Order;
413
    }
414
415
    /**
416
     * お届け先情報を作成
417
     *
418
     * @param \Eccube\Entity\Shipping $Shipping
419
     * @param \Eccube\Entity\Customer|null $Customer
420
     * @return \Eccube\Entity\Shipping
421
     */
422
    public function copyToShippingFromCustomer(Shipping $Shipping, Customer $Customer = null)
423
    {
424
        if (is_null($Customer)) {
425
            return $Shipping;
426
        }
427
428
        $CustomerAddress = $this->app['eccube.repository.customer_address']->findOneBy(
429
            array('Customer' => $Customer),
430
            array('id' => 'ASC')
431
        );
432
433
        if (!is_null($CustomerAddress)) {
434
            $Shipping
435
                ->setName01($CustomerAddress->getName01())
436
                ->setName02($CustomerAddress->getName02())
437
                ->setKana01($CustomerAddress->getKana01())
438
                ->setKana02($CustomerAddress->getKana02())
439
                ->setCompanyName($CustomerAddress->getCompanyName())
440
                ->setTel01($CustomerAddress->getTel01())
441
                ->setTel02($CustomerAddress->getTel02())
442
                ->setTel03($CustomerAddress->getTel03())
443
                ->setFax01($CustomerAddress->getFax01())
444
                ->setFax02($CustomerAddress->getFax02())
445
                ->setFax03($CustomerAddress->getFax03())
446
                ->setZip01($CustomerAddress->getZip01())
447
                ->setZip02($CustomerAddress->getZip02())
448
                ->setZipCode($CustomerAddress->getZip01().$CustomerAddress->getZip02())
449
                ->setPref($CustomerAddress->getPref())
450
                ->setAddr01($CustomerAddress->getAddr01())
451
                ->setAddr02($CustomerAddress->getAddr02());
452
        } else {
453
            $Shipping
454
                ->setName01($Customer->getName01())
455
                ->setName02($Customer->getName02())
456
                ->setKana01($Customer->getKana01())
457
                ->setKana02($Customer->getKana02())
458
                ->setCompanyName($Customer->getCompanyName())
459
                ->setTel01($Customer->getTel01())
460
                ->setTel02($Customer->getTel02())
461
                ->setTel03($Customer->getTel03())
462
                ->setFax01($Customer->getFax01())
463
                ->setFax02($Customer->getFax02())
464
                ->setFax03($Customer->getFax03())
465
                ->setZip01($Customer->getZip01())
466
                ->setZip02($Customer->getZip02())
467
                ->setZipCode($Customer->getZip01().$Customer->getZip02())
468
                ->setPref($Customer->getPref())
469
                ->setAddr01($Customer->getAddr01())
470
                ->setAddr02($Customer->getAddr02());
471
        }
472
473
        return $Shipping;
474
    }
475
476
477
    /**
478
     * 受注明細情報、配送商品情報を作成
479
     *
480
     * @param Order $Order
481
     * @return Order
482
     */
483
    public function getNewDetails(Order $Order)
484
    {
485
486
        // 受注詳細, 配送商品
487
        foreach ($this->cartService->getCart()->getCartItems() as $item) {
488
            /* @var $ProductClass \Eccube\Entity\ProductClass */
489
            $ProductClass = $item->getObject();
490
            /* @var $Product \Eccube\Entity\Product */
491
            $Product = $ProductClass->getProduct();
492
493
            $quantity = $item->getQuantity();
494
495
            // 受注明細情報を作成
496
            $OrderDetail = $this->getNewOrderDetail($Product, $ProductClass, $quantity);
497
            $OrderDetail->setOrder($Order);
498
            $Order->addOrderDetail($OrderDetail);
499
500
            // 配送商品情報を作成
501
            $this->getNewShipmentItem($Order, $Product, $ProductClass, $quantity);
502
        }
503
504
        return $Order;
505
506
    }
507
508
    /**
509
     * 受注明細情報を作成
510
     *
511
     * @param Product $Product
512
     * @param ProductClass $ProductClass
513
     * @param $quantity
514
     * @return \Eccube\Entity\OrderDetail
515
     */
516
    public function getNewOrderDetail(Product $Product, ProductClass $ProductClass, $quantity)
517
    {
518
        $OrderDetail = new OrderDetail();
519
        $TaxRule = $this->app['eccube.repository.tax_rule']->getByRule($Product, $ProductClass);
520
        $OrderDetail->setProduct($Product)
521
            ->setProductClass($ProductClass)
522
            ->setProductName($Product->getName())
523
            ->setProductCode($ProductClass->getCode())
524
            ->setPrice($ProductClass->getPrice02())
525
            ->setQuantity($quantity)
526
            ->setTaxRule($TaxRule->getCalcRule()->getId())
527
            ->setTaxRate($TaxRule->getTaxRate());
528
529
        $ClassCategory1 = $ProductClass->getClassCategory1();
530
        if (!is_null($ClassCategory1)) {
531
            $OrderDetail->setClasscategoryName1($ClassCategory1->getName());
532
            $OrderDetail->setClassName1($ClassCategory1->getClassName()->getName());
533
        }
534
        $ClassCategory2 = $ProductClass->getClassCategory2();
535
        if (!is_null($ClassCategory2)) {
536
            $OrderDetail->setClasscategoryName2($ClassCategory2->getName());
537
            $OrderDetail->setClassName2($ClassCategory2->getClassName()->getName());
538
        }
539
540
        $this->em->persist($OrderDetail);
541
542
        return $OrderDetail;
543
    }
544
545
    /**
546
     * 配送商品情報を作成
547
     *
548
     * @param Order $Order
549
     * @param Product $Product
550
     * @param ProductClass $ProductClass
551
     * @param $quantity
552
     * @return \Eccube\Entity\ShipmentItem
553
     */
554
    public function getNewShipmentItem(Order $Order, Product $Product, ProductClass $ProductClass, $quantity)
555
    {
556
557
        $ShipmentItem = new ShipmentItem();
558
        $shippings = $Order->getShippings();
559
560
        // 選択された商品がどのお届け先情報と関連するかチェック
561
        $Shipping = null;
562
        foreach ($shippings as $s) {
563
            if ($s->getDelivery()->getProductType()->getId() == $ProductClass->getProductType()->getId()) {
564
                // 商品種別が同一のお届け先情報と関連させる
565
                $Shipping = $s;
566
                break;
567
            }
568
        }
569
570
        if (is_null($Shipping)) {
571
            // お届け先情報と関連していない場合、エラー
572
            throw new CartException('shopping.delivery.not.producttype');
573
        }
574
575
        // 商品ごとの配送料合計
576
        $productDeliveryFeeTotal = 0;
577
        if ($this->BaseInfo->getOptionProductDeliveryFee() === Constant::ENABLED) {
578
            $productDeliveryFeeTotal = $ProductClass->getDeliveryFee() * $quantity;
579
        }
580
581
        $Shipping->setShippingDeliveryFee($Shipping->getShippingDeliveryFee() + $productDeliveryFeeTotal);
582
583
        $ShipmentItem->setShipping($Shipping)
584
            ->setOrder($Order)
585
            ->setProductClass($ProductClass)
586
            ->setProduct($Product)
587
            ->setProductName($Product->getName())
588
            ->setProductCode($ProductClass->getCode())
589
            ->setPrice($ProductClass->getPrice02())
590
            ->setQuantity($quantity);
591
592
        $ClassCategory1 = $ProductClass->getClassCategory1();
593
        if (!is_null($ClassCategory1)) {
594
            $ShipmentItem->setClasscategoryName1($ClassCategory1->getName());
595
            $ShipmentItem->setClassName1($ClassCategory1->getClassName()->getName());
596
        }
597
        $ClassCategory2 = $ProductClass->getClassCategory2();
598
        if (!is_null($ClassCategory2)) {
599
            $ShipmentItem->setClasscategoryName2($ClassCategory2->getName());
600
            $ShipmentItem->setClassName2($ClassCategory2->getClassName()->getName());
601
        }
602
        $Shipping->addShipmentItem($ShipmentItem);
603
        $this->em->persist($ShipmentItem);
604
605
        return $ShipmentItem;
606
607
    }
608
609
    /**
610
     * お届け先ごとの送料合計を取得
611
     *
612
     * @param $shippings
613
     * @return int
614
     */
615
    public function getShippingDeliveryFeeTotal($shippings)
616
    {
617
        $deliveryFeeTotal = 0;
618
        foreach ($shippings as $Shipping) {
619
            $deliveryFeeTotal += $Shipping->getShippingDeliveryFee();
620
        }
621
622
        return $deliveryFeeTotal;
623
624
    }
625
626
    /**
627
     * 商品ごとの配送料を取得
628
     *
629
     * @param Shipping $Shipping
630
     * @return int
631
     */
632
    public function getProductDeliveryFee(Shipping $Shipping)
633
    {
634
        $productDeliveryFeeTotal = 0;
635
        $shipmentItems = $Shipping->getShipmentItems();
636
        foreach ($shipmentItems as $ShipmentItem) {
637
            $productDeliveryFeeTotal += $ShipmentItem->getProductClass()->getDeliveryFee() * $ShipmentItem->getQuantity();
638
        }
639
640
        return $productDeliveryFeeTotal;
641
    }
642
643
    /**
644
     * 住所などの情報が変更された時に金額の再計算を行う
645
     *
646
     * @param Order $Order
647
     * @return Order
648
     */
649 View Code Duplication
    public function getAmount(Order $Order)
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...
650
    {
651
652
        // 初期選択の配送業者をセット
653
        $shippings = $Order->getShippings();
654
655
        // 配送料合計金額
656
        $Order->setDeliveryFeeTotal($this->getShippingDeliveryFeeTotal($shippings));
657
658
        // 配送料無料条件(合計金額)
659
        $this->setDeliveryFreeAmount($Order);
660
661
        // 配送料無料条件(合計数量)
662
        $this->setDeliveryFreeQuantity($Order);
663
664
        // 合計金額の計算
665
        $this->calculatePrice($Order);
666
667
        return $Order;
668
669
    }
670
671
    /**
672
     * 配送料金の設定
673
     *
674
     * @param Shipping $Shipping
675
     * @param Delivery|null $Delivery
676
     */
677
    public function setShippingDeliveryFee(Shipping $Shipping, Delivery $Delivery = null)
678
    {
679
        // 配送料金の設定
680
        if (is_null($Delivery)) {
681
            $Delivery = $Shipping->getDelivery();
682
        }
683
        $deliveryFee = $this->app['eccube.repository.delivery_fee']->findOneBy(array('Delivery' => $Delivery, 'Pref' => $Shipping->getPref()));
684
685
        $Shipping->setDeliveryFee($deliveryFee);
686
        $Shipping->setDelivery($Delivery);
687
688
        // 商品ごとの配送料合計
689
        $productDeliveryFeeTotal = 0;
690
        if ($this->BaseInfo->getOptionProductDeliveryFee() === Constant::ENABLED) {
691
            $productDeliveryFeeTotal += $this->getProductDeliveryFee($Shipping);
692
        }
693
694
        $Shipping->setShippingDeliveryFee($deliveryFee->getFee() + $productDeliveryFeeTotal);
695
        $Shipping->setShippingDeliveryName($Delivery->getName());
696
    }
697
698
    /**
699
     * 配送料無料条件(合計金額)の条件を満たしていれば配送料金を0に設定
700
     *
701
     * @param Order $Order
702
     */
703 View Code Duplication
    public function setDeliveryFreeAmount(Order $Order)
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...
704
    {
705
        // 配送料無料条件(合計金額)
706
        $deliveryFreeAmount = $this->BaseInfo->getDeliveryFreeAmount();
707
        if (!is_null($deliveryFreeAmount)) {
708
            // 合計金額が設定金額以上であれば送料無料
709
            if ($Order->getSubTotal() >= $deliveryFreeAmount) {
710
                $Order->setDeliveryFeeTotal(0);
711
                // お届け先情報の配送料も0にセット
712
                $shippings = $Order->getShippings();
713
                foreach ($shippings as $Shipping) {
714
                    $Shipping->setShippingDeliveryFee(0);
715
                }
716
            }
717
        }
718
    }
719
720
    /**
721
     * 配送料無料条件(合計数量)の条件を満たしていれば配送料金を0に設定
722
     *
723
     * @param Order $Order
724
     */
725 View Code Duplication
    public function setDeliveryFreeQuantity(Order $Order)
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...
726
    {
727
        // 配送料無料条件(合計数量)
728
        $deliveryFreeQuantity = $this->BaseInfo->getDeliveryFreeQuantity();
729
        if (!is_null($deliveryFreeQuantity)) {
730
            // 合計数量が設定数量以上であれば送料無料
731
            if ($this->orderService->getTotalQuantity($Order) >= $deliveryFreeQuantity) {
0 ignored issues
show
Deprecated Code introduced by
The method Eccube\Service\OrderService::getTotalQuantity() has been deprecated with message: since 3.0.0, to be removed in 3.1

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
732
                $Order->setDeliveryFeeTotal(0);
733
                // お届け先情報の配送料も0にセット
734
                $shippings = $Order->getShippings();
735
                foreach ($shippings as $Shipping) {
736
                    $Shipping->setShippingDeliveryFee(0);
737
                }
738
            }
739
        }
740
    }
741
742
743
    /**
744
     * 商品公開ステータスチェック、在庫チェック、購入制限数チェックを行い、在庫情報をロックする
745
     *
746
     * @param $em トランザクション制御されているEntityManager
747
     * @param Order $Order 受注情報
748
     * @return bool true : 成功、false : 失敗
749
     */
750
    public function isOrderProduct($em, \Eccube\Entity\Order $Order)
751
    {
752
        $orderDetails = $Order->getOrderDetails();
753
754
        foreach ($orderDetails as $orderDetail) {
755
756
            // 商品削除チェック
757
            if ($orderDetail->getProductClass()->getDelFlg()) {
758
                // @deprecated 3.1以降ではexceptionをthrowする
759
                // throw new ShoppingException('cart.product.delete');
760
                return false;
761
            }
762
763
            // 商品公開ステータスチェック
764
            if ($orderDetail->getProduct()->getStatus()->getId() != \Eccube\Entity\Master\Disp::DISPLAY_SHOW) {
765
                // 商品が非公開ならエラー
766
767
                // @deprecated 3.1以降ではexceptionをthrowする
768
                // throw new ShoppingException('cart.product.not.status');
769
                return false;
770
            }
771
772
            // 購入制限数チェック
773
            if (!is_null($orderDetail->getProductClass()->getSaleLimit())) {
774
                if ($orderDetail->getQuantity() > $orderDetail->getProductClass()->getSaleLimit()) {
775
                    // @deprecated 3.1以降ではexceptionをthrowする
776
                    // throw new ShoppingException('cart.over.sale_limit');
777
                    return false;
778
                }
779
            }
780
781
            // 購入数チェック
782
            if ($orderDetail->getQuantity() < 1) {
783
                // 購入数量が1未満ならエラー
784
785
                // @deprecated 3.1以降ではexceptionをthrowする
786
                // throw new ShoppingException('???');
787
                return false;
788
            }
789
790
        }
791
792
        // 在庫チェック
793
        foreach ($orderDetails as $orderDetail) {
794
            // 在庫が無制限かチェックし、制限ありなら在庫数をチェック
795
            if ($orderDetail->getProductClass()->getStockUnlimited() == Constant::DISABLED) {
796
                // 在庫チェックあり
797
                // 在庫に対してロック(select ... for update)を実行
798
                $productStock = $em->getRepository('Eccube\Entity\ProductStock')->find(
799
                    $orderDetail->getProductClass()->getProductStock()->getId(), LockMode::PESSIMISTIC_WRITE
800
                );
801
                // 購入数量と在庫数をチェックして在庫がなければエラー
802
                if ($productStock->getStock() < 1) {
803
                    // @deprecated 3.1以降ではexceptionをthrowする
804
                    // throw new ShoppingException('cart.over.stock');
805
                    return false;
806
                } elseif ($orderDetail->getQuantity() > $productStock->getStock()) {
807
                    // @deprecated 3.1以降ではexceptionをthrowする
808
                    // throw new ShoppingException('cart.over.stock');
809
                    return false;
810
                }
811
            }
812
        }
813
814
        return true;
815
816
    }
817
818
    /**
819
     * 受注情報、お届け先情報の更新
820
     *
821
     * @param Order $Order 受注情報
822
     * @param $data フォームデータ
823
     *
824
     * @deprecated since 3.0.5, to be removed in 3.1
825
     */
826
    public function setOrderUpdate(Order $Order, $data)
827
    {
828
        // 受注情報を更新
829
        $Order->setOrderDate(new \DateTime());
830
        $Order->setOrderStatus($this->app['eccube.repository.order_status']->find($this->app['config']['order_new']));
831
        $Order->setMessage($data['message']);
832
        // お届け先情報を更新
833
        $shippings = $data['shippings'];
834
        foreach ($shippings as $Shipping) {
835
            $Delivery = $Shipping->getDelivery();
836
            $deliveryFee = $this->app['eccube.repository.delivery_fee']->findOneBy(array(
837
                'Delivery' => $Delivery,
838
                'Pref' => $Shipping->getPref()
839
            ));
840
            $deliveryTime = $Shipping->getDeliveryTime();
841
            if (!empty($deliveryTime)) {
842
                $Shipping->setShippingDeliveryTime($deliveryTime->getDeliveryTime());
843
            }
844
            $Shipping->setDeliveryFee($deliveryFee);
845
            // 商品ごとの配送料合計
846
            $productDeliveryFeeTotal = 0;
847
            if ($this->BaseInfo->getOptionProductDeliveryFee() === Constant::ENABLED) {
848
                $productDeliveryFeeTotal += $this->getProductDeliveryFee($Shipping);
849
            }
850
            $Shipping->setShippingDeliveryFee($deliveryFee->getFee() + $productDeliveryFeeTotal);
851
            $Shipping->setShippingDeliveryName($Delivery->getName());
852
        }
853
        // 配送料無料条件(合計金額)
854
        $this->setDeliveryFreeAmount($Order);
855
        // 配送料無料条件(合計数量)
856
        $this->setDeliveryFreeQuantity($Order);
857
    }
858
859
860
    /**
861
     * 受注情報の更新
862
     *
863
     * @param Order $Order 受注情報
864
     */
865
    public function setOrderUpdateData(Order $Order)
866
    {
867
        // 受注情報を更新
868
        $Order->setOrderDate(new \DateTime());
869
        $OrderStatus = $this->app['eccube.repository.order_status']->find($this->app['config']['order_new']);
870
        $this->setOrderStatus($Order, $OrderStatus);
871
872
    }
873
874
875
    /**
876
     * 在庫情報の更新
877
     *
878
     * @param $em トランザクション制御されているEntityManager
879
     * @param Order $Order 受注情報
880
     */
881
    public function setStockUpdate($em, Order $Order)
882
    {
883
884
        $orderDetails = $Order->getOrderDetails();
885
886
        // 在庫情報更新
887
        foreach ($orderDetails as $orderDetail) {
888
            // 在庫が無制限かチェックし、制限ありなら在庫数を更新
889
            if ($orderDetail->getProductClass()->getStockUnlimited() == Constant::DISABLED) {
890
891
                $productStock = $em->getRepository('Eccube\Entity\ProductStock')->find(
892
                    $orderDetail->getProductClass()->getProductStock()->getId()
893
                );
894
895
                // 在庫情報の在庫数を更新
896
                $stock = $productStock->getStock() - $orderDetail->getQuantity();
897
                $productStock->setStock($stock);
898
899
                // 商品規格情報の在庫数を更新
900
                $orderDetail->getProductClass()->setStock($stock);
901
902
            }
903
        }
904
905
    }
906
907
908
    /**
909
     * 会員情報の更新
910
     *
911
     * @param Order $Order 受注情報
912
     * @param Customer $user ログインユーザ
913
     */
914
    public function setCustomerUpdate(Order $Order, Customer $user)
915
    {
916
917
        $orderDetails = $Order->getOrderDetails();
0 ignored issues
show
Unused Code introduced by
$orderDetails is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
918
919
        // 顧客情報を更新
920
        $now = new \DateTime();
921
        $firstBuyDate = $user->getFirstBuyDate();
922
        if (empty($firstBuyDate)) {
923
            $user->setFirstBuyDate($now);
924
        }
925
        $user->setLastBuyDate($now);
926
927
        $user->setBuyTimes($user->getBuyTimes() + 1);
928
        $user->setBuyTotal($user->getBuyTotal() + $Order->getTotal());
929
930
    }
931
932
933
    /**
934
     * 支払方法選択の表示設定
935
     *
936
     * @param $payments 支払選択肢情報
937
     * @param $subTotal 小計
938
     * @return array
939
     */
940
    public function getPayments($payments, $subTotal)
941
    {
942
        $pays = array();
943
        foreach ($payments as $payment) {
944
            // 支払方法の制限値内であれば表示
945
            if (!is_null($payment)) {
946
                $pay = $this->app['eccube.repository.payment']->find($payment['id']);
947
                if (intval($pay->getRuleMin()) <= $subTotal) {
948
                    if (is_null($pay->getRuleMax()) || $pay->getRuleMax() >= $subTotal) {
949
                        $pays[] = $pay;
950
                    }
951
                }
952
            }
953
        }
954
955
        return $pays;
956
957
    }
958
959
    /**
960
     * お届け日を取得
961
     *
962
     * @param Order $Order
963
     * @return array
964
     */
965
    public function getFormDeliveryDates(Order $Order)
966
    {
967
968
        // お届け日の設定
969
        $minDate = 0;
970
        $deliveryDateFlag = false;
971
972
        // 配送時に最大となる商品日数を取得
973
        foreach ($Order->getOrderDetails() as $detail) {
974
            $deliveryDate = $detail->getProductClass()->getDeliveryDate();
975
            if (!is_null($deliveryDate)) {
976
                if ($deliveryDate->getValue() < 0) {
977
                    // 配送日数がマイナスの場合はお取り寄せなのでスキップする
978
                    $deliveryDateFlag = false;
979
                    break;
980
                }
981
982
                if ($minDate < $deliveryDate->getValue()) {
983
                    $minDate = $deliveryDate->getValue();
984
                }
985
                // 配送日数が設定されている
986
                $deliveryDateFlag = true;
987
            }
988
        }
989
990
        // 配達最大日数期間を設定
991
        $deliveryDates = array();
992
993
        // 配送日数が設定されている
994
        if ($deliveryDateFlag) {
995
            $period = new \DatePeriod (
996
                new \DateTime($minDate.' day'),
997
                new \DateInterval('P1D'),
998
                new \DateTime($minDate + $this->app['config']['deliv_date_end_max'].' day')
999
            );
1000
1001
            foreach ($period as $day) {
1002
                $deliveryDates[$day->format('Y/m/d')] = $day->format('Y/m/d');
1003
            }
1004
        }
1005
1006
        return $deliveryDates;
1007
1008
    }
1009
1010
    /**
1011
     * 支払方法を取得
1012
     *
1013
     * @param $deliveries
1014
     * @param Order $Order
1015
     * @return array
1016
     */
1017
    public function getFormPayments($deliveries, Order $Order)
1018
    {
1019
        $productTypes = $this->orderService->getProductTypes($Order);
0 ignored issues
show
Deprecated Code introduced by
The method Eccube\Service\OrderService::getProductTypes() has been deprecated with message: since 3.0.0, to be removed in 3.1

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1020
1021
        if ($this->BaseInfo->getOptionMultipleShipping() == Constant::ENABLED && count($productTypes) > 1) {
1022
            // 複数配送時の支払方法
1023
            $payments = $this->app['eccube.repository.payment']->findAllowedPayments($deliveries);
1024
        } else {
1025
            // 配送業者をセット
1026
            $shippings = $Order->getShippings();
1027
            $payments = array();
1028
            foreach ($shippings as $Shipping) {
1029
                $paymentsShip = $this->app['eccube.repository.payment']->findPayments($Shipping->getDelivery(), true);
1030
                if (!$payments) {
1031
                    $payments = $paymentsShip;
1032
                } else {
1033
                    $payments = array_intersect($payments, $paymentsShip);
1034
                }
1035
            }
1036
        }
1037
        $payments = $this->getPayments($payments, $Order->getSubTotal());
1038
1039
        return $payments;
1040
    }
1041
1042
    /**
1043
     * お届け先ごとにFormを作成
1044
     *
1045
     * @param Order $Order
1046
     * @return \Symfony\Component\Form\Form
1047
     * @deprecated since 3.0, to be removed in 3.1
1048
     */
1049 View Code Duplication
    public function getShippingForm(Order $Order)
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...
1050
    {
1051
        $message = $Order->getMessage();
1052
1053
        $deliveries = $this->getDeliveriesOrder($Order);
1054
1055
        // 配送業者の支払方法を取得
1056
        $payments = $this->getFormPayments($deliveries, $Order);
1057
1058
        $builder = $this->app['form.factory']->createBuilder('shopping', null, array(
1059
            'payments' => $payments,
1060
            'payment' => $Order->getPayment(),
1061
            'message' => $message,
1062
        ));
1063
1064
        $builder
1065
            ->add('shippings', 'collection', array(
1066
                'type' => 'shipping_item',
1067
                'data' => $Order->getShippings(),
1068
            ));
1069
1070
        $form = $builder->getForm();
1071
1072
        return $form;
1073
1074
    }
1075
1076
    /**
1077
     * お届け先ごとにFormBuilderを作成
1078
     *
1079
     * @param Order $Order
1080
     * @return \Symfony\Component\Form\FormBuilderInterface
1081
     */
1082 View Code Duplication
    public function getShippingFormBuilder(Order $Order)
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...
1083
    {
1084
        $message = $Order->getMessage();
1085
1086
        $deliveries = $this->getDeliveriesOrder($Order);
1087
1088
        // 配送業者の支払方法を取得
1089
        $payments = $this->getFormPayments($deliveries, $Order);
1090
1091
        $builder = $this->app['form.factory']->createBuilder('shopping', null, array(
1092
            'payments' => $payments,
1093
            'payment' => $Order->getPayment(),
1094
            'message' => $message,
1095
        ));
1096
1097
        $builder
1098
            ->add('shippings', 'collection', array(
1099
                'type' => 'shipping_item',
1100
                'data' => $Order->getShippings(),
1101
            ));
1102
1103
        return $builder;
1104
1105
    }
1106
1107
1108
    /**
1109
     * フォームデータを更新
1110
     *
1111
     * @param Order $Order
1112
     * @param array $data
1113
     */
1114
    public function setFormData(Order $Order, array $data)
1115
    {
1116
1117
        // お問い合わせ
1118
        $Order->setMessage($data['message']);
1119
1120
        // お届け先情報を更新
1121
        $shippings = $data['shippings'];
1122
        foreach ($shippings as $Shipping) {
1123
1124
            $deliveryTime = $Shipping->getDeliveryTime();
1125
            if (!empty($deliveryTime)) {
1126
                $Shipping->setShippingDeliveryTime($deliveryTime->getDeliveryTime());
1127
            }
1128
1129
        }
1130
1131
    }
1132
1133
    /**
1134
     * 配送料の合計金額を計算
1135
     *
1136
     * @param Order $Order
1137
     * @return Order
1138
     */
1139 View Code Duplication
    public function calculateDeliveryFee(Order $Order)
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...
1140
    {
1141
1142
        // 配送業者を取得
1143
        $shippings = $Order->getShippings();
1144
1145
        // 配送料合計金額
1146
        $Order->setDeliveryFeeTotal($this->getShippingDeliveryFeeTotal($shippings));
1147
1148
        // 配送料無料条件(合計金額)
1149
        $this->setDeliveryFreeAmount($Order);
1150
1151
        // 配送料無料条件(合計数量)
1152
        $this->setDeliveryFreeQuantity($Order);
1153
1154
        return $Order;
1155
1156
    }
1157
1158
1159
    /**
1160
     * 購入処理を行う
1161
     *
1162
     * @param Order $Order
1163
     * @throws ShoppingException
1164
     */
1165
    public function processPurchase(Order $Order)
1166
    {
1167
1168
        $em = $this->app['orm.em'];
1169
1170
        // 合計金額の再計算
1171
        $this->calculatePrice($Order);
1172
1173
        // 商品公開ステータスチェック、商品制限数チェック、在庫チェック
1174
        $check = $this->isOrderProduct($em, $Order);
1175
        if (!$check) {
1176
            throw new ShoppingException('front.shopping.stock.error');
1177
        }
1178
1179
        // 受注情報、配送情報を更新
1180
        $Order = $this->calculateDeliveryFee($Order);
1181
        $this->setOrderUpdateData($Order);
1182
        // 在庫情報を更新
1183
        $this->setStockUpdate($em, $Order);
1184
1185
        if ($this->app->isGranted('ROLE_USER')) {
1186
            // 会員の場合、購入金額を更新
1187
            $this->setCustomerUpdate($Order, $this->app->user());
1188
        }
1189
1190
    }
1191
1192
1193
    /**
1194
     * 値引き可能かチェック
1195
     *
1196
     * @param Order $Order
1197
     * @param       $discount
1198
     * @return bool
1199
     */
1200
    public function isDiscount(Order $Order, $discount)
1201
    {
1202
1203
        if ($Order->getTotal() < $discount) {
1204
            return false;
1205
        }
1206
1207
        return true;
1208
    }
1209
1210
1211
    /**
1212
     * 値引き金額をセット
1213
     *
1214
     * @param Order $Order
1215
     * @param $discount
1216
     */
1217
    public function setDiscount(Order $Order, $discount)
1218
    {
1219
1220
        $Order->setDiscount($Order->getDiscount() + $discount);
1221
1222
    }
1223
1224
1225
    /**
1226
     * 合計金額を計算
1227
     *
1228
     * @param Order $Order
1229
     * @return Order
1230
     */
1231
    public function calculatePrice(Order $Order)
1232
    {
1233
1234
        $total = $Order->getTotalPrice();
1235
1236
        if ($total < 0) {
1237
            // 合計金額がマイナスの場合、0を設定し、discountは値引きされた額のみセット
1238
            $total = 0;
1239
        }
1240
1241
        $Order->setTotal($total);
1242
        $Order->setPaymentTotal($total);
1243
1244
        return $Order;
1245
1246
    }
1247
1248
    /**
1249
     * 受注ステータスをセット
1250
     *
1251
     * @param Order $Order
1252
     * @param $status
1253
     * @return Order
1254
     */
1255
    public function setOrderStatus(Order $Order, $status)
1256
    {
1257
1258
        $Order->setOrderDate(new \DateTime());
1259
        $Order->setOrderStatus($this->app['eccube.repository.order_status']->find($status));
1260
1261
        $event = new EventArgs(
1262
            array(
1263
                'Order' => $Order,
1264
            ),
1265
            null
1266
        );
1267
        $this->app['eccube.event.dispatcher']->dispatch(EccubeEvents::SERVICE_SHOPPING_ORDER_STATUS, $event);
1268
1269
        return $Order;
1270
1271
    }
1272
1273
    /**
1274
     * 受注メール送信を行う
1275
     *
1276
     * @param Order $Order
1277
     * @return MailHistory
1278
     */
1279
    public function sendOrderMail(Order $Order)
1280
    {
1281
1282
        // メール送信
1283
        $message = $this->app['eccube.service.mail']->sendOrderMail($Order);
1284
1285
        // 送信履歴を保存.
1286
        $MailTemplate = $this->app['eccube.repository.mail_template']->find(1);
1287
1288
        $MailHistory = new MailHistory();
1289
        $MailHistory
1290
            ->setSubject($message->getSubject())
1291
            ->setMailBody($message->getBody())
1292
            ->setMailTemplate($MailTemplate)
1293
            ->setSendDate(new \DateTime())
1294
            ->setOrder($Order);
1295
1296
        $this->app['orm.em']->persist($MailHistory);
1297
        $this->app['orm.em']->flush($MailHistory);
1298
1299
        return $MailHistory;
1300
1301
    }
1302
1303
1304
    /**
1305
     * 受注処理完了通知
1306
     *
1307
     * @param Order $Order
1308
     */
1309
    public function notifyComplete(Order $Order)
1310
    {
1311
1312
        $event = new EventArgs(
1313
            array(
1314
                'Order' => $Order,
1315
            ),
1316
            null
1317
        );
1318
        $this->app['eccube.event.dispatcher']->dispatch(EccubeEvents::SERVICE_SHOPPING_NOTIFY_COMPLETE, $event);
1319
1320
    }
1321
1322
1323
}
1324