Issues (2366)

Branch: master

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/Eccube/Service/ShoppingService.php (6 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.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 24
57
    /** @var \Eccube\Entity\BaseInfo */
58 24
    protected $BaseInfo;
59 24
60 24
    /** @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 5
71
    /**
72
     * セッションにセットされた受注情報を取得
73
     *
74
     * @param null $status
75
     * @return null|object
76
     */
77
    public function getOrder($status = null)
78 5
    {
79
80
        // 受注データを取得
81
        $preOrderId = $this->cartService->getPreOrderId();
82
        if (!$preOrderId) {
83 2
            return null;
84
        }
85
86
        $condition = array(
87
            'pre_order_id' => $preOrderId,
88 5
        );
89
90 3
        if (!is_null($status)) {
91
            $condition += array(
92
                'OrderStatus' => $status,
93
            );
94
        }
95
96
        $Order = $this->app['eccube.repository.order']->findOneBy($condition);
97
98 1
        return $Order;
99
100
    }
101
102
    /**
103
     * 非会員情報を取得
104 1
     *
105
     * @param $sesisonKey
106
     * @return $Customer|null
107 1
     */
108
    public function getNonMember($sesisonKey)
109
    {
110 1
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 6
        $Customer = $nonMember['customer'];
121
        $Customer->setPref($this->app['eccube.repository.master.pref']->find($nonMember['pref']));
122
123
        return $Customer;
124
125
    }
126 6
127
    /**
128
     * 受注情報を作成
129
     *
130
     * @param $Customer
131
     * @return \Eccube\Entity\Order
132
     */
133 6
    public function createOrder($Customer)
134
    {
135
        // ランダムなpre_order_idを作成
136
        do {
137
            $preOrderId = sha1(Str::random(32));
138
            $Order = $this->app['eccube.repository.order']->findOneBy(array(
139
                'pre_order_id' => $preOrderId,
140
                'OrderStatus' => $this->app['config']['order_processing'],
141
            ));
142
        } while ($Order);
143
144
        // 受注情報、受注明細情報、お届け先情報、配送商品情報を作成
145 6
        $Order = $this->registerPreOrder(
146
            $Customer,
147
            $preOrderId);
148
149
        $this->cartService->setPreOrderId($preOrderId);
150
        $this->cartService->save();
151
152
        return $Order;
153
    }
154
155
    /**
156
     * 仮受注情報作成
157
     *
158
     * @param $Customer
159
     * @param $preOrderId
160
     * @return mixed
161
     * @throws \Doctrine\ORM\NoResultException
162
     * @throws \Doctrine\ORM\NonUniqueResultException
163
     */
164
    public function registerPreOrder(Customer $Customer, $preOrderId)
165
    {
166
167
        $this->em = $this->app['orm.em'];
168
169
        // 受注情報を作成
170
        $Order = $this->getNewOrder($Customer);
171
        $Order->setPreOrderId($preOrderId);
172
173
        // device type
174
        if ($this->app['mobile_detect']->isMobile()) {
175
            $DeviceType = $this->app['eccube.repository.master.device_type']->find(DeviceType::DEVICE_TYPE_SP);
176
        } else {
177
            $DeviceType = $this->app['eccube.repository.master.device_type']->find(DeviceType::DEVICE_TYPE_PC);
178
        }
179
        $Order->setDeviceType($DeviceType);
180
181
        $this->em->persist($Order);
182
183
        // 配送業者情報を取得
184
        $deliveries = $this->getDeliveriesCart();
185
186
        // お届け先情報を作成
187
        $Order = $this->getNewShipping($Order, $Customer, $deliveries);
188 6
189
        // 受注明細情報、配送商品情報を作成
190
        $Order = $this->getNewDetails($Order);
191
192
        // 小計
193
        $subTotal = $this->orderService->getSubTotal($Order);
194 6
195
        // 消費税のみの小計
196
        $tax = $this->orderService->getTotalTax($Order);
197
198
        // 配送料合計金額
199
        $Order->setDeliveryFeeTotal($this->getShippingDeliveryFeeTotal($Order->getShippings()));
200
201
        // 小計
202
        $Order->setSubTotal($subTotal);
203
204
        // 配送料無料条件(合計金額)
205 6
        $this->setDeliveryFreeAmount($Order);
206
207 6
        // 配送料無料条件(合計数量)
208
        $this->setDeliveryFreeQuantity($Order);
209
210
        // 初期選択の支払い方法をセット
211
        $payments = $this->app['eccube.repository.payment']->findAllowedPayments($deliveries);
212
        $payments = $this->getPayments($payments, $subTotal);
213
214 6
        if (count($payments) > 0) {
215
            $payment = $payments[0];
216
            $Order->setPayment($payment);
217
            $Order->setPaymentMethod($payment->getMethod());
218
            $Order->setCharge($payment->getCharge());
219 6
        } else {
220 6
            $Order->setCharge(0);
221
        }
222
223
        $Order->setTax($tax);
224
225
        // 合計金額の計算
226
        $this->calculatePrice($Order);
227 6
228
        $this->em->flush();
229
230 6
        return $Order;
231 6
232 6
    }
233 6
234 6
    /**
235 6
     * 受注情報を作成
236
     *
237
     * @param $Customer
238
     * @return \Eccube\Entity\Order
239 6
     */
240
    public function getNewOrder(Customer $Customer)
241
    {
242
        $Order = $this->newOrder();
243
        $this->copyToOrderFromCustomer($Order, $Customer);
244
245
        return $Order;
246
    }
247
248
249 6
    /**
250
     * 受注情報を作成
251
     *
252
     * @return \Eccube\Entity\Order
253
     */
254
    public function newOrder()
255
    {
256
        $OrderStatus = $this->app['eccube.repository.order_status']->find($this->app['config']['order_processing']);
257
        $Order = new \Eccube\Entity\Order($OrderStatus);
258
259
        return $Order;
260
    }
261
262
    /**
263
     * 受注情報を作成
264
     *
265
     * @param \Eccube\Entity\Order $Order
266
     * @param \Eccube\Entity\Customer|null $Customer
267
     * @return \Eccube\Entity\Order
268
     */
269
    public function copyToOrderFromCustomer(Order $Order, Customer $Customer = null)
270
    {
271
        if (is_null($Customer)) {
272
            return $Order;
273
        }
274
275
        if ($Customer->getId()) {
276
            $Order->setCustomer($Customer);
277
        }
278
        $Order
279
            ->setName01($Customer->getName01())
280
            ->setName02($Customer->getName02())
281 6
            ->setKana01($Customer->getKana01())
282 6
            ->setKana02($Customer->getKana02())
283
            ->setCompanyName($Customer->getCompanyName())
284
            ->setEmail($Customer->getEmail())
285
            ->setTel01($Customer->getTel01())
286
            ->setTel02($Customer->getTel02())
287
            ->setTel03($Customer->getTel03())
288
            ->setFax01($Customer->getFax01())
289
            ->setFax02($Customer->getFax02())
290
            ->setFax03($Customer->getFax03())
291
            ->setZip01($Customer->getZip01())
292
            ->setZip02($Customer->getZip02())
293
            ->setZipCode($Customer->getZip01().$Customer->getZip02())
294
            ->setPref($Customer->getPref())
295
            ->setAddr01($Customer->getAddr01())
296
            ->setAddr02($Customer->getAddr02())
297
            ->setSex($Customer->getSex())
298
            ->setBirth($Customer->getBirth())
299
            ->setJob($Customer->getJob());
300
301
        return $Order;
302
    }
303
304
305
    /**
306
     * 配送業者情報を取得
307
     *
308
     * @return array
309
     */
310
    public function getDeliveriesCart()
311
    {
312
313
        // カートに保持されている商品種別を取得
314
        $productTypes = $this->cartService->getProductTypes();
315
316
        return $this->getDeliveries($productTypes);
317
318
    }
319
320
    /**
321
     * 配送業者情報を取得
322 9
     *
323
     * @param Order $Order
324
     * @return array
325
     */
326
    public function getDeliveriesOrder(Order $Order)
327
    {
328
329
        // 受注情報から商品種別を取得
330
        $productTypes = $this->orderService->getProductTypes($Order);
331
332
        return $this->getDeliveries($productTypes);
333
334
    }
335
336
    /**
337
     * 配送業者情報を取得
338
     *
339
     * @param $productTypes
340
     * @return array
341 9
     */
342
    public function getDeliveries($productTypes)
343
    {
344
345
        // 商品種別に紐づく配送業者を取得
346
        $deliveries = $this->app['eccube.repository.delivery']->getDeliveries($productTypes);
347
348
        if ($this->BaseInfo->getOptionMultipleShipping() == Constant::ENABLED) {
349
            // 複数配送対応
350
351
            // 支払方法を取得
352
            $payments = $this->app['eccube.repository.payment']->findAllowedPayments($deliveries);
353
354 6
            if (count($productTypes) > 1) {
355
                // 商品種別が複数ある場合、配送対象となる配送業者を取得
356 6
                $deliveries = $this->app['eccube.repository.delivery']->findAllowedDeliveries($productTypes, $payments);
357
            }
358
359
        }
360
361 6
        return $deliveries;
362 6
363
    }
364
365
366
    /**
367
     * お届け先情報を作成
368
     *
369
     * @param Order $Order
370
     * @param Customer $Customer
371
     * @param $deliveries
372
     * @return Order
373
     */
374
    public function getNewShipping(Order $Order, Customer $Customer, $deliveries)
375
    {
376 6
        $productTypes = array();
377 6
        foreach ($deliveries as $Delivery) {
378
            if (!in_array($Delivery->getProductType()->getId(), $productTypes)) {
379
                $Shipping = new Shipping();
380
381
                $this->copyToShippingFromCustomer($Shipping, $Customer)
382
                    ->setOrder($Order)
383
                    ->setDelFlg(Constant::DISABLED);
384
385
                // 配送料金の設定
386 7
                $this->setShippingDeliveryFee($Shipping, $Delivery);
387
388
                $this->em->persist($Shipping);
389 1
390
                $Order->addShipping($Shipping);
391
392 6
                $productTypes[] = $Delivery->getProductType()->getId();
393 6
            }
394 6
        }
395
396
        return $Order;
397
    }
398
399
    /**
400
     * お届け先情報を作成
401
     *
402
     * @param \Eccube\Entity\Shipping $Shipping
403
     * @param \Eccube\Entity\Customer|null $Customer
404
     * @return \Eccube\Entity\Shipping
405
     */
406
    public function copyToShippingFromCustomer(Shipping $Shipping, Customer $Customer = null)
407
    {
408
        if (is_null($Customer)) {
409
            return $Shipping;
410
        }
411
412
        $CustomerAddress = $this->app['eccube.repository.customer_address']->findOneBy(
413
            array('Customer' => $Customer),
414
            array('id' => 'ASC')
415
        );
416
417
        if (!is_null($CustomerAddress)) {
418
            $Shipping
419
                ->setName01($CustomerAddress->getName01())
420
                ->setName02($CustomerAddress->getName02())
421
                ->setKana01($CustomerAddress->getKana01())
422
                ->setKana02($CustomerAddress->getKana02())
423
                ->setCompanyName($CustomerAddress->getCompanyName())
424
                ->setTel01($CustomerAddress->getTel01())
425
                ->setTel02($CustomerAddress->getTel02())
426
                ->setTel03($CustomerAddress->getTel03())
427
                ->setFax01($CustomerAddress->getFax01())
428
                ->setFax02($CustomerAddress->getFax02())
429
                ->setFax03($CustomerAddress->getFax03())
430
                ->setZip01($CustomerAddress->getZip01())
431
                ->setZip02($CustomerAddress->getZip02())
432
                ->setZipCode($CustomerAddress->getZip01().$CustomerAddress->getZip02())
433
                ->setPref($CustomerAddress->getPref())
434
                ->setAddr01($CustomerAddress->getAddr01())
435 5
                ->setAddr02($CustomerAddress->getAddr02());
436
        } else {
437 6
            $Shipping
438 7
                ->setName01($Customer->getName01())
439
                ->setName02($Customer->getName02())
440
                ->setKana01($Customer->getKana01())
441
                ->setKana02($Customer->getKana02())
442
                ->setCompanyName($Customer->getCompanyName())
443
                ->setTel01($Customer->getTel01())
444
                ->setTel02($Customer->getTel02())
445
                ->setTel03($Customer->getTel03())
446
                ->setFax01($Customer->getFax01())
447 6
                ->setFax02($Customer->getFax02())
448
                ->setFax03($Customer->getFax03())
449
                ->setZip01($Customer->getZip01())
450
                ->setZip02($Customer->getZip02())
451
                ->setZipCode($Customer->getZip01().$Customer->getZip02())
452
                ->setPref($Customer->getPref())
453
                ->setAddr01($Customer->getAddr01())
454
                ->setAddr02($Customer->getAddr02());
455
        }
456
457
        return $Shipping;
458
    }
459
460
461
    /**
462
     * 受注明細情報、配送商品情報を作成
463
     *
464
     * @param Order $Order
465
     * @return Order
466
     */
467
    public function getNewDetails(Order $Order)
468 6
    {
469
470 6
        // 受注詳細, 配送商品
471
        foreach ($this->cartService->getCart()->getCartItems() as $item) {
472
            /* @var $ProductClass \Eccube\Entity\ProductClass */
473
            $ProductClass = $item->getObject();
474
            /* @var $Product \Eccube\Entity\Product */
475
            $Product = $ProductClass->getProduct();
476
477
            $quantity = $item->getQuantity();
478
479
            // 受注明細情報を作成
480 6
            $OrderDetail = $this->getNewOrderDetail($Product, $ProductClass, $quantity);
481
            $OrderDetail->setOrder($Order);
482
            $Order->addOrderDetail($OrderDetail);
483
484 6
            // 配送商品情報を作成
485 6
            $this->getNewShipmentItem($Order, $Product, $ProductClass, $quantity);
486
        }
487
488
        return $Order;
489 6
490
    }
491
492
    /**
493
     * 受注明細情報を作成
494
     *
495
     * @param Product $Product
496
     * @param ProductClass $ProductClass
497
     * @param $quantity
498
     * @return \Eccube\Entity\OrderDetail
499
     */
500
    public function getNewOrderDetail(Product $Product, ProductClass $ProductClass, $quantity)
501
    {
502
        $OrderDetail = new OrderDetail();
503
        $TaxRule = $this->app['eccube.repository.tax_rule']->getByRule($Product, $ProductClass);
504
        $OrderDetail->setProduct($Product)
505
            ->setProductClass($ProductClass)
506 6
            ->setProductName($Product->getName())
507 6
            ->setProductCode($ProductClass->getCode())
508
            ->setPrice($ProductClass->getPrice02())
509
            ->setQuantity($quantity)
510
            ->setTaxRule($TaxRule->getCalcRule()->getId())
511
            ->setTaxRate($TaxRule->getTaxRate());
512
513
        $ClassCategory1 = $ProductClass->getClassCategory1();
514
        if (!is_null($ClassCategory1)) {
515
            $OrderDetail->setClasscategoryName1($ClassCategory1->getName());
516
            $OrderDetail->setClassName1($ClassCategory1->getClassName()->getName());
517
        }
518 6
        $ClassCategory2 = $ProductClass->getClassCategory2();
519
        if (!is_null($ClassCategory2)) {
520
            $OrderDetail->setClasscategoryName2($ClassCategory2->getName());
521
            $OrderDetail->setClassName2($ClassCategory2->getClassName()->getName());
522
        }
523
524
        $this->em->persist($OrderDetail);
525 6
526
        return $OrderDetail;
527
    }
528
529 6
    /**
530 6
     * 配送商品情報を作成
531
     *
532 6
     * @param Order $Order
533
     * @param Product $Product
534
     * @param ProductClass $ProductClass
535 6
     * @param $quantity
536
     * @return \Eccube\Entity\ShipmentItem
537
     */
538
    public function getNewShipmentItem(Order $Order, Product $Product, ProductClass $ProductClass, $quantity)
539
    {
540
541
        $ShipmentItem = new ShipmentItem();
542 6
        $shippings = $Order->getShippings();
543 6
544 6
        // 選択された商品がどのお届け先情報と関連するかチェック
545 6
        $Shipping = null;
546
        foreach ($shippings as $s) {
547
            if ($s->getDelivery()->getProductType()->getId() == $ProductClass->getProductType()->getId()) {
548
                // 商品種別が同一のお届け先情報と関連させる
549
                $Shipping = $s;
550
                break;
551
            }
552
        }
553
554
        if (is_null($Shipping)) {
555
            // お届け先情報と関連していない場合、エラー
556
            throw new CartException('shopping.delivery.not.producttype');
557
        }
558
559
        // 商品ごとの配送料合計
560
        $productDeliveryFeeTotal = 0;
561
        if ($this->BaseInfo->getOptionProductDeliveryFee() === Constant::ENABLED) {
562
            $productDeliveryFeeTotal = $ProductClass->getDeliveryFee() * $quantity;
563
        }
564 6
565
        $Shipping->setShippingDeliveryFee($Shipping->getShippingDeliveryFee() + $productDeliveryFeeTotal);
566 6
567
        $ShipmentItem->setShipping($Shipping)
568
            ->setOrder($Order)
569
            ->setProductClass($ProductClass)
570
            ->setProduct($Product)
571
            ->setProductName($Product->getName())
572
            ->setProductCode($ProductClass->getCode())
573
            ->setPrice($ProductClass->getPrice02())
574 7
            ->setQuantity($quantity);
575
576 7
        $ClassCategory1 = $ProductClass->getClassCategory1();
577
        if (!is_null($ClassCategory1)) {
578
            $ShipmentItem->setClasscategoryName1($ClassCategory1->getName());
579
            $ShipmentItem->setClassName1($ClassCategory1->getClassName()->getName());
580
        }
581 7
        $ClassCategory2 = $ProductClass->getClassCategory2();
582
        if (!is_null($ClassCategory2)) {
583
            $ShipmentItem->setClasscategoryName2($ClassCategory2->getName());
584
            $ShipmentItem->setClassName2($ClassCategory2->getClassName()->getName());
585
        }
586
        $Shipping->addShipmentItem($ShipmentItem);
587
        $this->em->persist($ShipmentItem);
588
589
        return $ShipmentItem;
590
591 7
    }
592
593 7
    /**
594
     * お届け先ごとの送料合計を取得
595
     *
596
     * @param $shippings
597 7
     * @return int
598 7
     */
599 7
    public function getShippingDeliveryFeeTotal($shippings)
600
    {
601
        $deliveryFeeTotal = 0;
602
        foreach ($shippings as $Shipping) {
603
            $deliveryFeeTotal += $Shipping->getShippingDeliveryFee();
604
        }
605
606
        return $deliveryFeeTotal;
607 1
608
    }
609
610
    /**
611
     * 商品ごとの配送料を取得
612
     *
613
     * @param Shipping $Shipping
614
     * @return int
615
     */
616
    public function getProductDeliveryFee(Shipping $Shipping)
617
    {
618
        $productDeliveryFeeTotal = 0;
619
        $shipmentItems = $Shipping->getShipmentItems();
620
        foreach ($shipmentItems as $ShipmentItem) {
621
            $productDeliveryFeeTotal += $ShipmentItem->getProductClass()->getDeliveryFee() * $ShipmentItem->getQuantity();
622
        }
623
624
        return $productDeliveryFeeTotal;
625
    }
626
627
    /**
628 1
     * 住所などの情報が変更された時に金額の再計算を行う
629
     *
630 1
     * @param Order $Order
631
     * @return Order
632
     */
633 View Code Duplication
    public function getAmount(Order $Order)
634
    {
635
636
        // 初期選択の配送業者をセット
637
        $shippings = $Order->getShippings();
638 6
639
        // 配送料合計金額
640
        $Order->setDeliveryFeeTotal($this->getShippingDeliveryFeeTotal($shippings));
641
642
        // 配送料無料条件(合計金額)
643
        $this->setDeliveryFreeAmount($Order);
644
645
        // 配送料無料条件(合計数量)
646
        $this->setDeliveryFreeQuantity($Order);
647
648
        // 合計金額の計算
649
        $this->calculatePrice($Order);
650 6
651
        return $Order;
652
653
    }
654
655
    /**
656
     * 配送料金の設定
657
     *
658
     * @param Shipping $Shipping
659
     * @param Delivery|null $Delivery
660
     */
661
    public function setShippingDeliveryFee(Shipping $Shipping, Delivery $Delivery = null)
662
    {
663
        // 配送料金の設定
664
        if (is_null($Delivery)) {
665
            $Delivery = $Shipping->getDelivery();
666
        }
667
        $deliveryFee = $this->app['eccube.repository.delivery_fee']->findOneBy(array('Delivery' => $Delivery, 'Pref' => $Shipping->getPref()));
668
669
        $Shipping->setDeliveryFee($deliveryFee);
670
        $Shipping->setDelivery($Delivery);
671
672
        // 商品ごとの配送料合計
673
        $productDeliveryFeeTotal = 0;
674
        if ($this->BaseInfo->getOptionProductDeliveryFee() === Constant::ENABLED) {
675
            $productDeliveryFeeTotal += $this->getProductDeliveryFee($Shipping);
676
        }
677
678
        $Shipping->setShippingDeliveryFee($deliveryFee->getFee() + $productDeliveryFeeTotal);
679
        $Shipping->setShippingDeliveryName($Delivery->getName());
680
    }
681
682
    /**
683
     * 配送料無料条件(合計金額)の条件を満たしていれば配送料金を0に設定
684
     *
685
     * @param Order $Order
686
     */
687 View Code Duplication
    public function setDeliveryFreeAmount(Order $Order)
688
    {
689
        // 配送料無料条件(合計金額)
690
        $deliveryFreeAmount = $this->BaseInfo->getDeliveryFreeAmount();
691
        if (!is_null($deliveryFreeAmount)) {
692
            // 合計金額が設定金額以上であれば送料無料
693
            if ($Order->getSubTotal() >= $deliveryFreeAmount) {
694
                $Order->setDeliveryFeeTotal(0);
695
                // お届け先情報の配送料も0にセット
696
                $shippings = $Order->getShippings();
697
                foreach ($shippings as $Shipping) {
698
                    $Shipping->setShippingDeliveryFee(0);
699
                }
700
            }
701
        }
702
    }
703
704
    /**
705
     * 配送料無料条件(合計数量)の条件を満たしていれば配送料金を0に設定
706
     *
707
     * @param Order $Order
708
     */
709 View Code Duplication
    public function setDeliveryFreeQuantity(Order $Order)
710
    {
711
        // 配送料無料条件(合計数量)
712 4
        $deliveryFreeQuantity = $this->BaseInfo->getDeliveryFreeQuantity();
713
        if (!is_null($deliveryFreeQuantity)) {
714
            // 合計数量が設定数量以上であれば送料無料
715
            if ($this->orderService->getTotalQuantity($Order) >= $deliveryFreeQuantity) {
716
                $Order->setDeliveryFeeTotal(0);
717
                // お届け先情報の配送料も0にセット
718
                $shippings = $Order->getShippings();
719
                foreach ($shippings as $Shipping) {
720 1
                    $Shipping->setShippingDeliveryFee(0);
721
                }
722
            }
723
        }
724
    }
725
726 1
727
    /**
728
     * 商品公開ステータスチェック、在庫チェック、購入制限数チェックを行い、在庫情報をロックする
729
     *
730 2
     * @param $em トランザクション制御されているEntityManager
731
     * @param Order $Order 受注情報
732
     * @return bool true : 成功、false : 失敗
733
     */
734
    public function isOrderProduct($em, \Eccube\Entity\Order $Order)
735
    {
736
        $orderDetails = $Order->getOrderDetails();
737
738 1
        foreach ($orderDetails as $orderDetail) {
739
740
            // 商品削除チェック
741
            if ($orderDetail->getProductClass()->getDelFlg()) {
742
                // @deprecated 3.1以降ではexceptionをthrowする
743 1
                // throw new ShoppingException('cart.product.delete');
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
744
                return false;
745
            }
746 1
747
            // 商品公開ステータスチェック
748 1
            if ($orderDetail->getProduct()->getStatus()->getId() != \Eccube\Entity\Master\Disp::DISPLAY_SHOW) {
749
                // 商品が非公開ならエラー
750 4
751
                // @deprecated 3.1以降ではexceptionをthrowする
752
                // throw new ShoppingException('cart.product.not.status');
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
753
                return false;
754
            }
755
756
            // 購入制限数チェック
757
            if (!is_null($orderDetail->getProductClass()->getSaleLimit())) {
758 1
                if ($orderDetail->getQuantity() > $orderDetail->getProductClass()->getSaleLimit()) {
759
                    // @deprecated 3.1以降ではexceptionをthrowする
760
                    // throw new ShoppingException('cart.over.sale_limit');
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
761
                    return false;
762
                }
763
            }
764
765
            // 購入数チェック
766 1
            if ($orderDetail->getQuantity() < 1) {
767
                // 購入数量が1未満ならエラー
768
769
                // @deprecated 3.1以降ではexceptionをthrowする
770
                // throw new ShoppingException('???');
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
771 1
                return false;
772
            }
773 1
774
        }
775
776
        // 在庫チェック
777 1
        foreach ($orderDetails as $orderDetail) {
778
            // 在庫が無制限かチェックし、制限ありなら在庫数をチェック
779
            if ($orderDetail->getProductClass()->getStockUnlimited() == Constant::DISABLED) {
780
                // 在庫チェックあり
781
                // 在庫に対してロック(select ... for update)を実行
782
                $productStock = $em->getRepository('Eccube\Entity\ProductStock')->find(
783
                    $orderDetail->getProductClass()->getProductStock()->getId(), LockMode::PESSIMISTIC_WRITE
784 1
                );
785
                // 購入数量と在庫数をチェックして在庫がなければエラー
786
                if ($productStock->getStock() < 1) {
787
                    // @deprecated 3.1以降ではexceptionをthrowする
788
                    // throw new ShoppingException('cart.over.stock');
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
789
                    return false;
790
                } elseif ($orderDetail->getQuantity() > $productStock->getStock()) {
791
                    // @deprecated 3.1以降ではexceptionをthrowする
792
                    // throw new ShoppingException('cart.over.stock');
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
793
                    return false;
794
                }
795
            }
796
        }
797
798
        return true;
799
800
    }
801
802
    /**
803
     * 受注情報、お届け先情報の更新
804
     *
805
     * @param Order $Order 受注情報
806
     * @param $data フォームデータ
807
     *
808 1
     * @deprecated since 3.0.5, to be removed in 3.1
809
     */
810
    public function setOrderUpdate(Order $Order, $data)
811
    {
812
        // 受注情報を更新
813
        $Order->setOrderDate(new \DateTime());
814
        $Order->setOrderStatus($this->app['eccube.repository.order_status']->find($this->app['config']['order_new']));
815
        $Order->setMessage($data['message']);
816
        // お届け先情報を更新
817
        $shippings = $data['shippings'];
818 1
        foreach ($shippings as $Shipping) {
819
            $Delivery = $Shipping->getDelivery();
820
            $deliveryFee = $this->app['eccube.repository.delivery_fee']->findOneBy(array(
821
                'Delivery' => $Delivery,
822
                'Pref' => $Shipping->getPref()
823
            ));
824
            $deliveryTime = $Shipping->getDeliveryTime();
825
            if (!empty($deliveryTime)) {
826
                $Shipping->setShippingDeliveryTime($deliveryTime->getDeliveryTime());
827
            }
828
            $Shipping->setDeliveryFee($deliveryFee);
829
            // 商品ごとの配送料合計
830
            $productDeliveryFeeTotal = 0;
831
            if ($this->BaseInfo->getOptionProductDeliveryFee() === Constant::ENABLED) {
832
                $productDeliveryFeeTotal += $this->getProductDeliveryFee($Shipping);
833
            }
834
            $Shipping->setShippingDeliveryFee($deliveryFee->getFee() + $productDeliveryFeeTotal);
835
            $Shipping->setShippingDeliveryName($Delivery->getName());
836
        }
837
        // 配送料無料条件(合計金額)
838
        $this->setDeliveryFreeAmount($Order);
839
        // 配送料無料条件(合計数量)
840
        $this->setDeliveryFreeQuantity($Order);
841 1
    }
842
843
844
    /**
845
     * 受注情報の更新
846
     *
847
     * @param Order $Order 受注情報
848
     */
849 1
    public function setOrderUpdateData(Order $Order)
850
    {
851
        // 受注情報を更新
852
        $Order->setOrderDate(new \DateTime());
853
        $OrderStatus = $this->app['eccube.repository.order_status']->find($this->app['config']['order_new']);
854
        $this->setOrderStatus($Order, $OrderStatus);
855
856
    }
857
858
859
    /**
860
     * 在庫情報の更新
861
     *
862
     * @param $em トランザクション制御されているEntityManager
863
     * @param Order $Order 受注情報
864
     */
865
    public function setStockUpdate($em, Order $Order)
866
    {
867 7
868
        $orderDetails = $Order->getOrderDetails();
869 7
870
        // 在庫情報更新
871
        foreach ($orderDetails as $orderDetail) {
872
            // 在庫が無制限かチェックし、制限ありなら在庫数を更新
873
            if ($orderDetail->getProductClass()->getStockUnlimited() == Constant::DISABLED) {
874
875
                $productStock = $em->getRepository('Eccube\Entity\ProductStock')->find(
876
                    $orderDetail->getProductClass()->getProductStock()->getId()
877
                );
878
879
                // 在庫情報の在庫数を更新
880
                $stock = $productStock->getStock() - $orderDetail->getQuantity();
881
                $productStock->setStock($stock);
882 7
883
                // 商品規格情報の在庫数を更新
884
                $orderDetail->getProductClass()->setStock($stock);
885
886
            }
887
        }
888
889
    }
890
891
892 1
    /**
893
     * 会員情報の更新
894
     *
895
     * @param Order $Order 受注情報
896 1
     * @param Customer $user ログインユーザ
897 1
     */
898
    public function setCustomerUpdate(Order $Order, Customer $user)
899
    {
900 1
901
        $orderDetails = $Order->getOrderDetails();
902
903
        // 顧客情報を更新
904
        $now = new \DateTime();
905
        $firstBuyDate = $user->getFirstBuyDate();
906
        if (empty($firstBuyDate)) {
907 1
            $user->setFirstBuyDate($now);
908
        }
909
        $user->setLastBuyDate($now);
910
911
        $user->setBuyTimes($user->getBuyTimes() + 1);
912 1
        $user->setBuyTotal($user->getBuyTotal() + $Order->getTotal());
913
914
    }
915 1
916
917
    /**
918
     * 支払方法選択の表示設定
919
     *
920
     * @param $payments 支払選択肢情報
921
     * @param $subTotal 小計
922
     * @return array
923
     */
924
    public function getPayments($payments, $subTotal)
925
    {
926
        $pays = array();
927 1
        foreach ($payments as $payment) {
928
            // 支払方法の制限値内であれば表示
929 1
            if (!is_null($payment)) {
930
                $pay = $this->app['eccube.repository.payment']->find($payment['id']);
931
                if (intval($pay->getRuleMin()) <= $subTotal) {
932
                    if (is_null($pay->getRuleMax()) || $pay->getRuleMax() >= $subTotal) {
933
                        $pays[] = $pay;
934
                    }
935
                }
936
            }
937
        }
938
939
        return $pays;
940
941
    }
942
943
    /**
944
     * お届け日を取得
945
     *
946
     * @param Order $Order
947
     * @return array
948
     */
949
    public function getFormDeliveryDates(Order $Order)
950
    {
951
952
        // お届け日の設定
953
        $minDate = 0;
954
        $deliveryDateFlag = false;
955
956
        // 配送時に最大となる商品日数を取得
957
        foreach ($Order->getOrderDetails() as $detail) {
958
            $deliveryDate = $detail->getProductClass()->getDeliveryDate();
959
            if (!is_null($deliveryDate)) {
960
                if ($deliveryDate->getValue() < 0) {
961
                    // 配送日数がマイナスの場合はお取り寄せなのでスキップする
962
                    $deliveryDateFlag = false;
963
                    break;
964
                }
965
966
                if ($minDate < $deliveryDate->getValue()) {
967
                    $minDate = $deliveryDate->getValue();
968
                }
969
                // 配送日数が設定されている
970
                $deliveryDateFlag = true;
971
            }
972
        }
973
974
        // 配達最大日数期間を設定
975
        $deliveryDates = array();
976
977
        // 配送日数が設定されている
978
        if ($deliveryDateFlag) {
979
            $period = new \DatePeriod (
980
                new \DateTime($minDate.' day'),
981
                new \DateInterval('P1D'),
982
                new \DateTime($minDate + $this->app['config']['deliv_date_end_max'].' day')
983
            );
984
985
            foreach ($period as $day) {
986
                $deliveryDates[$day->format('Y/m/d')] = $day->format('Y/m/d');
987
            }
988
        }
989
990
        return $deliveryDates;
991
992
    }
993
994
    /**
995
     * 支払方法を取得
996
     *
997
     * @param $deliveries
998
     * @param Order $Order
999
     * @return array
1000
     */
1001
    public function getFormPayments($deliveries, Order $Order)
1002
    {
1003
        $productTypes = $this->orderService->getProductTypes($Order);
1004
1005
        if ($this->BaseInfo->getOptionMultipleShipping() == Constant::ENABLED && count($productTypes) > 1) {
1006
            // 複数配送時の支払方法
1007
            $payments = $this->app['eccube.repository.payment']->findAllowedPayments($deliveries);
1008
        } else {
1009
            // 配送業者をセット
1010
            $shippings = $Order->getShippings();
1011
            $payments = array();
1012
            foreach ($shippings as $Shipping) {
1013
                $paymentsShip = $this->app['eccube.repository.payment']->findPayments($Shipping->getDelivery(), true);
1014
                if (!$payments) {
1015
                    $payments = $paymentsShip;
1016
                } else {
1017
                    $payments = array_intersect($payments, $paymentsShip);
1018
                }
1019
            }
1020
        }
1021
        $payments = $this->getPayments($payments, $Order->getSubTotal());
1022
1023
        return $payments;
1024
    }
1025
1026
    /**
1027
     * お届け先ごとにFormを作成
1028
     *
1029
     * @param Order $Order
1030
     * @return \Symfony\Component\Form\Form
1031
     * @deprecated since 3.0, to be removed in 3.1
1032
     */
1033 View Code Duplication
    public function getShippingForm(Order $Order)
1034
    {
1035
        $message = $Order->getMessage();
1036
1037
        $deliveries = $this->getDeliveriesOrder($Order);
1038
1039
        // 配送業者の支払方法を取得
1040
        $payments = $this->getFormPayments($deliveries, $Order);
1041
1042
        $builder = $this->app['form.factory']->createBuilder('shopping', null, array(
1043
            'payments' => $payments,
1044
            'payment' => $Order->getPayment(),
1045
            'message' => $message,
1046
        ));
1047
1048
        $builder
1049
            ->add('shippings', 'collection', array(
1050
                'type' => 'shipping_item',
1051
                'data' => $Order->getShippings(),
1052
            ));
1053
1054
        $form = $builder->getForm();
1055
1056
        return $form;
1057
1058
    }
1059
1060
    /**
1061
     * お届け先ごとにFormBuilderを作成
1062
     *
1063
     * @param Order $Order
1064
     * @return \Symfony\Component\Form\FormBuilderInterface
1065
     */
1066 View Code Duplication
    public function getShippingFormBuilder(Order $Order)
1067
    {
1068
        $message = $Order->getMessage();
1069
1070
        $deliveries = $this->getDeliveriesOrder($Order);
1071
1072
        // 配送業者の支払方法を取得
1073
        $payments = $this->getFormPayments($deliveries, $Order);
1074
1075
        $builder = $this->app['form.factory']->createBuilder('shopping', null, array(
1076
            'payments' => $payments,
1077
            'payment' => $Order->getPayment(),
1078
            'message' => $message,
1079
        ));
1080
1081
        $builder
1082
            ->add('shippings', 'collection', array(
1083
                'type' => 'shipping_item',
1084
                'data' => $Order->getShippings(),
1085
            ));
1086
1087
        return $builder;
1088
1089
    }
1090
1091
1092
    /**
1093
     * フォームデータを更新
1094
     *
1095
     * @param Order $Order
1096
     * @param array $data
1097
     */
1098
    public function setFormData(Order $Order, array $data)
1099
    {
1100
1101
        // お問い合わせ
1102
        $Order->setMessage($data['message']);
1103
1104
        // お届け先情報を更新
1105
        $shippings = $data['shippings'];
1106
        foreach ($shippings as $Shipping) {
1107
1108
            $deliveryTime = $Shipping->getDeliveryTime();
1109
            if (!empty($deliveryTime)) {
1110
                $Shipping->setShippingDeliveryTime($deliveryTime->getDeliveryTime());
1111
            }
1112
1113
        }
1114
1115
    }
1116
1117
    /**
1118
     * 配送料の合計金額を計算
1119
     *
1120
     * @param Order $Order
1121
     * @return Order
1122
     */
1123 View Code Duplication
    public function calculateDeliveryFee(Order $Order)
1124
    {
1125
1126
        // 配送業者を取得
1127
        $shippings = $Order->getShippings();
1128
1129
        // 配送料合計金額
1130
        $Order->setDeliveryFeeTotal($this->getShippingDeliveryFeeTotal($shippings));
1131
1132
        // 配送料無料条件(合計金額)
1133
        $this->setDeliveryFreeAmount($Order);
1134
1135
        // 配送料無料条件(合計数量)
1136
        $this->setDeliveryFreeQuantity($Order);
1137
1138
        return $Order;
1139
1140
    }
1141
1142
1143
    /**
1144
     * 購入処理を行う
1145
     *
1146
     * @param Order $Order
1147
     * @throws ShoppingException
1148
     */
1149
    public function processPurchase(Order $Order)
1150
    {
1151
1152
        $em = $this->app['orm.em'];
1153
1154
        // 合計金額の再計算
1155
        $this->calculatePrice($Order);
1156
1157
        // 商品公開ステータスチェック、商品制限数チェック、在庫チェック
1158
        $check = $this->isOrderProduct($em, $Order);
1159
        if (!$check) {
1160
            throw new ShoppingException('front.shopping.stock.error');
1161
        }
1162
1163
        // 受注情報、配送情報を更新
1164
        $Order = $this->calculateDeliveryFee($Order);
1165
        $this->setOrderUpdateData($Order);
1166
        // 在庫情報を更新
1167
        $this->setStockUpdate($em, $Order);
1168
1169
        if ($this->app->isGranted('ROLE_USER')) {
1170
            // 会員の場合、購入金額を更新
1171
            $this->setCustomerUpdate($Order, $this->app->user());
1172
        }
1173
1174
    }
1175
1176
1177
    /**
1178
     * 値引き可能かチェック
1179
     *
1180
     * @param Order $Order
1181
     * @param       $discount
1182
     * @return bool
1183
     */
1184
    public function isDiscount(Order $Order, $discount)
1185
    {
1186
1187
        if ($Order->getTotal() < $discount) {
1188
            return false;
1189
        }
1190
1191
        return true;
1192
    }
1193
1194
1195
    /**
1196
     * 値引き金額をセット
1197
     *
1198
     * @param Order $Order
1199
     * @param $discount
1200
     */
1201
    public function setDiscount(Order $Order, $discount)
1202
    {
1203
1204
        $Order->setDiscount($Order->getDiscount() + $discount);
1205
1206
    }
1207
1208
1209
    /**
1210
     * 合計金額を計算
1211
     *
1212
     * @param Order $Order
1213
     * @return Order
1214
     */
1215
    public function calculatePrice(Order $Order)
1216
    {
1217
1218
        $total = $Order->getTotalPrice();
1219
1220
        if ($total < 0) {
1221
            // 合計金額がマイナスの場合、0を設定し、discountは値引きされた額のみセット
1222
            $total = 0;
1223
        }
1224
1225
        $Order->setTotal($total);
1226
        $Order->setPaymentTotal($total);
1227
1228
        return $Order;
1229
1230
    }
1231
1232
    /**
1233
     * 受注ステータスをセット
1234
     *
1235
     * @param Order $Order
1236
     * @param $status
1237
     * @return Order
1238
     */
1239
    public function setOrderStatus(Order $Order, $status)
1240
    {
1241
1242
        $Order->setOrderDate(new \DateTime());
1243
        $Order->setOrderStatus($this->app['eccube.repository.order_status']->find($status));
1244
1245
        $event = new EventArgs(
1246
            array(
1247
                'Order' => $Order,
1248
            ),
1249
            null
1250
        );
1251
        $this->app['eccube.event.dispatcher']->dispatch(EccubeEvents::SERVICE_SHOPPING_ORDER_STATUS, $event);
1252
1253
        return $Order;
1254
1255
    }
1256
1257
    /**
1258
     * 受注メール送信を行う
1259
     *
1260
     * @param Order $Order
1261
     * @return MailHistory
1262
     */
1263
    public function sendOrderMail(Order $Order)
1264
    {
1265
1266
        // メール送信
1267
        $message = $this->app['eccube.service.mail']->sendOrderMail($Order);
1268
1269
        // 送信履歴を保存.
1270
        $MailTemplate = $this->app['eccube.repository.mail_template']->find(1);
1271
1272
        $MailHistory = new MailHistory();
1273
        $MailHistory
1274
            ->setSubject($message->getSubject())
1275
            ->setMailBody($message->getBody())
1276
            ->setMailTemplate($MailTemplate)
1277
            ->setSendDate(new \DateTime())
1278
            ->setOrder($Order);
1279
1280
        $this->app['orm.em']->persist($MailHistory);
1281
        $this->app['orm.em']->flush($MailHistory);
1282
1283
        return $MailHistory;
1284
1285
    }
1286
1287
1288
    /**
1289
     * 受注処理完了通知
1290
     *
1291
     * @param Order $Order
1292
     */
1293
    public function notifyComplete(Order $Order)
1294
    {
1295
1296
        $event = new EventArgs(
1297
            array(
1298
                'Order' => $Order,
1299
            ),
1300
            null
1301
        );
1302
        $this->app['eccube.event.dispatcher']->dispatch(EccubeEvents::SERVICE_SHOPPING_NOTIFY_COMPLETE, $event);
1303
1304
    }
1305
1306
1307
}
1308