Completed
Pull Request — experimental/sf (#3335)
by Kiyotaka
586:38 queued 579:18
created

OrderController   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 551
Duplicated Lines 1.45 %

Coupling/Cohesion

Components 1
Dependencies 29

Test Coverage

Coverage 63.72%

Importance

Changes 0
Metric Value
dl 8
loc 551
ccs 137
cts 215
cp 0.6372
rs 8.64
c 0
b 0
f 0
wmc 47
lcom 1
cbo 29

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 25 1
C index() 0 124 10
A bulkDelete() 0 19 3
B exportOrder() 0 76 6
B updateOrderStatus() 0 44 11
C bulkOrderStatus() 8 74 10
B updateTrackingNumber() 0 42 6

How to fix   Duplicated Code    Complexity   

Duplicated Code

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

Common duplication problems, and corresponding solutions are:

Complex Class

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

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

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

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

1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) LOCKON CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.lockon.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube\Controller\Admin\Order;
15
16
use Eccube\Common\Constant;
17
use Eccube\Controller\AbstractController;
18
use Eccube\Entity\Csv;
19
use Eccube\Entity\Master\CsvType;
20
use Eccube\Entity\OrderItem;
21
use Eccube\Event\EccubeEvents;
22
use Eccube\Event\EventArgs;
23
use Eccube\Form\Type\Admin\SearchOrderType;
24
use Eccube\Repository\CustomerRepository;
25
use Eccube\Repository\Master\OrderStatusRepository;
26
use Eccube\Repository\Master\PageMaxRepository;
27
use Eccube\Repository\Master\ProductStatusRepository;
28
use Eccube\Repository\Master\SexRepository;
29
use Eccube\Repository\OrderRepository;
30
use Eccube\Repository\PaymentRepository;
31
use Eccube\Service\CsvExportService;
32
use Eccube\Service\OrderStateMachine;
33
use Eccube\Util\FormUtil;
34
use Knp\Component\Pager\PaginatorInterface;
35
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
36
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
37
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
38
use Symfony\Component\HttpFoundation\Response;
39
use Symfony\Component\HttpFoundation\Request;
40
use Symfony\Component\HttpFoundation\StreamedResponse;
41
use Eccube\Entity\Master\OrderStatus;
42
use Symfony\Component\HttpFoundation\RedirectResponse;
43
use Eccube\Entity\Order;
44
use Eccube\Entity\Shipping;
45
use Eccube\Service\PurchaseFlow\PurchaseContext;
46
use Eccube\Service\PurchaseFlow\PurchaseFlow;
47
use Eccube\Service\PurchaseFlow\PurchaseException;
48
use Symfony\Component\Validator\Constraints as Assert;
49
use Symfony\Component\Validator\Validator\ValidatorInterface;
50
51
class OrderController extends AbstractController
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
52
{
53
    /**
54
     * @var PurchaseFlow
55
     */
56
    protected $purchaseFlow;
57
58
    /**
59
     * @var CsvExportService
60
     */
61
    protected $csvExportService;
62
63
    /**
64
     * @var CustomerRepository
65
     */
66
    protected $customerRepository;
67
68
    /**
69
     * @var PaymentRepository
70
     */
71
    protected $paymentRepository;
72
73
    /**
74
     * @var SexRepository
75
     */
76
    protected $sexRepository;
77
78
    /**
79
     * @var OrderStatusRepository
80
     */
81
    protected $orderStatusRepository;
82
83
    /**
84
     * @var PageMaxRepository
85
     */
86
    protected $pageMaxRepository;
87
88
    /**
89
     * @var ProductStatusRepository
90
     */
91
    protected $productStatusRepository;
92
93
    /**
94
     * @var OrderRepository
95
     */
96
    protected $orderRepository;
97
98
    /**
99
     * @var ValidatorInterface
100
     */
101
    protected $validator;
102
103
    /**
104
     * @var OrderStateMachine
105
     */
106
    protected $orderStateMachine;
107
108
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$validator" missing
Loading history...
introduced by
Doc comment for parameter "$orderStateMachine" missing
Loading history...
109
     * OrderController constructor.
110
     *
111
     * @param PurchaseFlow $orderPurchaseFlow
0 ignored issues
show
introduced by
Expected 12 spaces after parameter type; 1 found
Loading history...
112
     * @param CsvExportService $csvExportService
0 ignored issues
show
introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
113
     * @param CustomerRepository $customerRepository
0 ignored issues
show
introduced by
Expected 6 spaces after parameter type; 1 found
Loading history...
114
     * @param PaymentRepository $paymentRepository
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
115
     * @param SexRepository $sexRepository
0 ignored issues
show
introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
116
     * @param OrderStatusRepository $orderStatusRepository
0 ignored issues
show
introduced by
Expected 3 spaces after parameter type; 1 found
Loading history...
117
     * @param PageMaxRepository $pageMaxRepository
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
118
     * @param ProductStatusRepository $productStatusRepository
119
     * @param OrderRepository $orderRepository
0 ignored issues
show
introduced by
Expected 9 spaces after parameter type; 1 found
Loading history...
120
     * @param OrderStateMachine $orderStateMachine;
0 ignored issues
show
Documentation introduced by
There is no parameter named $orderStateMachine;. Did you maybe mean $orderStateMachine?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
introduced by
Doc comment for parameter $orderStateMachine; does not match actual variable name $validator
Loading history...
121
     */
122 14
    public function __construct(
123
        PurchaseFlow $orderPurchaseFlow,
124
        CsvExportService $csvExportService,
125
        CustomerRepository $customerRepository,
126
        PaymentRepository $paymentRepository,
127
        SexRepository $sexRepository,
128
        OrderStatusRepository $orderStatusRepository,
129
        PageMaxRepository $pageMaxRepository,
130
        ProductStatusRepository $productStatusRepository,
131
        OrderRepository $orderRepository,
132
        ValidatorInterface $validator,
133
        OrderStateMachine $orderStateMachine
134
    ) {
135 14
        $this->purchaseFlow = $orderPurchaseFlow;
136 14
        $this->csvExportService = $csvExportService;
137 14
        $this->customerRepository = $customerRepository;
138 14
        $this->paymentRepository = $paymentRepository;
139 14
        $this->sexRepository = $sexRepository;
140 14
        $this->orderStatusRepository = $orderStatusRepository;
141 14
        $this->pageMaxRepository = $pageMaxRepository;
142 14
        $this->productStatusRepository = $productStatusRepository;
143 14
        $this->orderRepository = $orderRepository;
144 14
        $this->validator = $validator;
145 14
        $this->orderStateMachine = $orderStateMachine;
146
    }
147
148
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$page_no" missing
Loading history...
introduced by
Doc comment for parameter "$paginator" missing
Loading history...
149
     * 受注一覧画面.
150
     *
151
     * - 検索条件, ページ番号, 表示件数はセッションに保持されます.
152
     * - クエリパラメータでresume=1が指定された場合、検索条件, ページ番号, 表示件数をセッションから復旧します.
153
     * - 各データの, セッションに保持するアクションは以下の通りです.
154
     *   - 検索ボタン押下時
155
     *      - 検索条件をセッションに保存します
156
     *      - ページ番号は1で初期化し、セッションに保存します。
157
     *   - 表示件数変更時
158
     *      - クエリパラメータpage_countをセッションに保存します。
159
     *      - ただし, mtb_page_maxと一致しない場合, eccube_default_page_countが保存されます.
160
     *   - ページング時
161
     *      - URLパラメータpage_noをセッションに保存します.
162
     *   - 初期表示
163
     *      - 検索条件は空配列, ページ番号は1で初期化し, セッションに保存します.
164
     *
165
     * @Route("/%eccube_admin_route%/order", name="admin_order")
166
     * @Route("/%eccube_admin_route%/order/page/{page_no}", requirements={"page_no" = "\d+"}, name="admin_order_page")
167
     * @Template("@admin/Order/index.twig")
168
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
169 8
    public function index(Request $request, $page_no = null, PaginatorInterface $paginator)
0 ignored issues
show
Coding Style introduced by
Parameters which have default values should be placed at the end.

If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway:

// $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
Loading history...
170
    {
171 8
        $builder = $this->formFactory
172 8
            ->createBuilder(SearchOrderType::class);
173
174 8
        $event = new EventArgs(
175
            [
176 8
                'builder' => $builder,
177
            ],
178 8
            $request
179
        );
180 8
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_ORDER_INDEX_INITIALIZE, $event);
181
182 8
        $searchForm = $builder->getForm();
183
184
        /**
185
         * ページの表示件数は, 以下の順に優先される.
186
         * - リクエストパラメータ
187
         * - セッション
188
         * - デフォルト値
189
         * また, セッションに保存する際は mtb_page_maxと照合し, 一致した場合のみ保存する.
190
         **/
191 8
        $page_count = $this->session->get('eccube.admin.order.search.page_count',
192 8
                $this->eccubeConfig->get('eccube_default_page_count'));
193
194 8
        $page_count_param = (int) $request->get('page_count');
195 8
        $pageMaxis = $this->pageMaxRepository->findAll();
196
197 8
        if ($page_count_param) {
198 1
            foreach ($pageMaxis as $pageMax) {
199 1
                if ($page_count_param == $pageMax->getName()) {
200
                    $page_count = $pageMax->getName();
201
                    $this->session->set('eccube.admin.order.search.page_count', $page_count);
202 1
                    break;
203
                }
204
            }
205
        }
206
207 8
        if ('POST' === $request->getMethod()) {
208 6
            $searchForm->handleRequest($request);
209
210 6
            if ($searchForm->isValid()) {
211
                /**
212
                 * 検索が実行された場合は, セッションに検索条件を保存する.
213
                 * ページ番号は最初のページ番号に初期化する.
214
                 */
215 5
                $page_no = 1;
216 5
                $searchData = $searchForm->getData();
217
218
                // 検索条件, ページ番号をセッションに保持.
219 5
                $this->session->set('eccube.admin.order.search', FormUtil::getViewData($searchForm));
220 5
                $this->session->set('eccube.admin.order.search.page_no', $page_no);
221
            } else {
222
                // 検索エラーの際は, 詳細検索枠を開いてエラー表示する.
223
                return [
224 6
                    'searchForm' => $searchForm->createView(),
225
                    'pagination' => [],
226 1
                    'pageMaxis' => $pageMaxis,
227 1
                    'page_no' => $page_no,
228 1
                    'page_count' => $page_count,
229
                    'has_errors' => true,
230
                ];
231
            }
232
        } else {
233 3
            if (null !== $page_no || $request->get('resume')) {
234
                /*
235
                 * ページ送りの場合または、他画面から戻ってきた場合は, セッションから検索条件を復旧する.
236
                 */
237 1
                if ($page_no) {
238
                    // ページ送りで遷移した場合.
239 1
                    $this->session->set('eccube.admin.order.search.page_no', (int) $page_no);
240
                } else {
241
                    // 他画面から遷移した場合.
242
                    $page_no = $this->session->get('eccube.admin.order.search.page_no', 1);
243
                }
244 1
                $viewData = $this->session->get('eccube.admin.order.search', []);
245 1
                $searchData = FormUtil::submitAndGetData($searchForm, $viewData);
246
            } else {
247
                /**
248
                 * 初期表示の場合.
249
                 */
250 2
                $page_no = 1;
251 2
                $viewData = [];
252
253 2
                if ($statusId = (int) $request->get('order_status_id')) {
254
                    $viewData = ['status' => $statusId];
255
                }
256
257 2
                $searchData = FormUtil::submitAndGetData($searchForm, $viewData);
258
259
                // セッション中の検索条件, ページ番号を初期化.
260 2
                $this->session->set('eccube.admin.order.search', $viewData);
261 2
                $this->session->set('eccube.admin.order.search.page_no', $page_no);
262
            }
263
        }
264
265 8
        $qb = $this->orderRepository->getQueryBuilderBySearchDataForAdmin($searchData);
266
267 8
        $event = new EventArgs(
268
            [
269 8
                'qb' => $qb,
270 8
                'searchData' => $searchData,
271
            ],
272 8
            $request
273
        );
274
275 8
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_ORDER_INDEX_SEARCH, $event);
276
277 8
        $pagination = $paginator->paginate(
278 8
            $qb,
279 8
            $page_no,
280 8
            $page_count
281
        );
282
283
        return [
284 8
            'searchForm' => $searchForm->createView(),
285 8
            'pagination' => $pagination,
286 8
            'pageMaxis' => $pageMaxis,
287 8
            'page_no' => $page_no,
288 8
            'page_count' => $page_count,
289
            'has_errors' => false,
290 8
            'OrderStatuses' => $this->orderStatusRepository->findBy([], ['sort_no' => 'ASC']),
291
        ];
292
    }
293
294
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
295
     * @Method("POST")
296
     * @Route("/%eccube_admin_route%/order/bulk_delete", name="admin_order_bulk_delete")
297
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
298 1
    public function bulkDelete(Request $request)
299
    {
300 1
        $this->isTokenValid();
301 1
        $ids = $request->get('ids');
302 1
        foreach ($ids as $order_id) {
303 1
            $Order = $this->orderRepository
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $Order is correct as $this->orderRepository->find($order_id) (which targets Doctrine\ORM\EntityRepository::find()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
304 1
                ->find($order_id);
305 1
            if ($Order) {
306 1
                $this->entityManager->remove($Order);
307 1
                log_info('受注削除', [$Order->getId()]);
308
            }
309
        }
310
311 1
        $this->entityManager->flush();
312
313 1
        $this->addSuccess('admin.order.delete.complete', 'admin');
314
315 1
        return $this->redirect($this->generateUrl('admin_order', ['resume' => Constant::ENABLED]));
316
    }
317
318
    /**
319
     * 受注CSVの出力.
320
     *
321
     * @Route("/%eccube_admin_route%/order/export/order", name="admin_order_export_order")
322
     *
323
     * @param Request $request
324
     *
325
     * @return StreamedResponse
326
     */
327 1
    public function exportOrder(Request $request)
328
    {
329
        // タイムアウトを無効にする.
330 1
        set_time_limit(0);
331
332
        // sql loggerを無効にする.
333 1
        $em = $this->entityManager;
334 1
        $em->getConfiguration()->setSQLLogger(null);
335
336 1
        $response = new StreamedResponse();
337 1
        $response->setCallback(function () use ($request) {
338
            // CSV種別を元に初期化.
339 1
            $this->csvExportService->initCsvType(CsvType::CSV_TYPE_ORDER);
340
341
            // ヘッダ行の出力.
342
            $this->csvExportService->exportHeader();
343
344
            // 受注データ検索用のクエリビルダを取得.
345
            $qb = $this->csvExportService
346
                ->getOrderQueryBuilder($request);
347
348
            // データ行の出力.
349
            $this->csvExportService->setExportQueryBuilder($qb);
350
            $this->csvExportService->exportData(function ($entity, $csvService) use ($request) {
351
                $Csvs = $csvService->getCsvs();
352
353
                $Order = $entity;
354
                $OrderItems = $Order->getOrderItems();
355
356
                foreach ($OrderItems as $OrderItem) {
357
                    $ExportCsvRow = new \Eccube\Entity\ExportCsvRow();
358
359
                    // CSV出力項目と合致するデータを取得.
360
                    foreach ($Csvs as $Csv) {
361
                        // 受注データを検索.
362
                        $ExportCsvRow->setData($csvService->getData($Csv, $Order));
363
                        if ($ExportCsvRow->isDataNull()) {
364
                            // 受注データにない場合は, 受注明細を検索.
365
                            $ExportCsvRow->setData($csvService->getData($Csv, $OrderItem));
366
                        }
367
                        if ($ExportCsvRow->isDataNull() && $Shipping = $OrderItem->getShipping()) {
368
                            // 受注明細データにない場合は, 出荷を検索.
369
                            $ExportCsvRow->setData($csvService->getData($Csv, $Shipping));
370
                        }
371
372
                        $event = new EventArgs(
373
                            [
374
                                'csvService' => $csvService,
375
                                'Csv' => $Csv,
376
                                'OrderItem' => $OrderItem,
377
                                'ExportCsvRow' => $ExportCsvRow,
378
                            ],
379
                            $request
380
                        );
381
                        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_ORDER_CSV_EXPORT_ORDER, $event);
382
383
                        $ExportCsvRow->pushData();
384
                    }
385
386
                    //$row[] = number_format(memory_get_usage(true));
387
                    // 出力.
388
                    $csvService->fputcsv($ExportCsvRow->getRow());
389
                }
390
            });
391 1
        });
392
393 1
        $now = new \DateTime();
394 1
        $filename = 'order_'.$now->format('YmdHis').'.csv';
395 1
        $response->headers->set('Content-Type', 'application/octet-stream');
396 1
        $response->headers->set('Content-Disposition', 'attachment; filename='.$filename);
397 1
        $response->send();
398
399
        log_info('受注CSV出力ファイル名', [$filename]);
400
401
        return $response;
402
    }
403
404
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$Shipping" missing
Loading history...
405
     * Update to order status
406
     *
407
     * @Method("PUT")
408
     * @Route("/%eccube_admin_route%/shipping/{id}/order_status", requirements={"id" = "\d+"}, name="admin_shipping_update_order_status")
409
     *
410
     * @param Request $request
0 ignored issues
show
introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
411
     * @param Shipping $shipping
0 ignored issues
show
Documentation introduced by
There is no parameter named $shipping. Did you maybe mean $Shipping?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
introduced by
Doc comment for parameter $shipping does not match case of actual variable name $Shipping
Loading history...
412
     *
413
     * @return RedirectResponse
414
     */
415
    public function updateOrderStatus(Request $request, Shipping $Shipping)
416
    {
417
        if (!($request->isXmlHttpRequest() && $this->isTokenValid())) {
418
            return $this->json(['status' => 'NG'], 400);
419
        }
420
421
        $Order = $Shipping->getOrder();
422
        $OrderStatus = $this->entityManager->find(OrderStatus::class, $request->get('order_status'));
423
424
        try {
425
            // 発送済みに変更された場合は、関連する出荷がすべて出荷済みになったら OrderStatus を変更する
426
            if (OrderStatus::DELIVERED == $OrderStatus->getId()) {
427
                if (!$Shipping->getShippingDate()) {
428
                    $Shipping->setShippingDate(\DateTime());
429
                    $this->entityManager->flush($Shipping);
0 ignored issues
show
Unused Code introduced by
The call to EntityManagerInterface::flush() has too many arguments starting with $Shipping.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
430
                }
431
                $RelateShippings = $Order->getShippings();
432
                $allShipped = false;
433
                foreach ($RelateShippings as $RelateShipping) {
434
                    if (!$RelateShipping->getShippingDate()) {
435
                        continue;
436
                    }
437
                    $allShipped = true;
438
                }
439
                if ($allShipped) {
440
                    if ($this->orderStateMachine->can($Order, $OrderStatus)) {
441
                        $this->orderStateMachine->apply($Order, $OrderStatus);
442
                    }
443
                }
444
            } else {
445
                if ($this->orderStateMachine->can($Order, $OrderStatus)) {
446
                    $this->orderStateMachine->apply($Order, $OrderStatus);
447
                }
448
            }
449
            $this->entityManager->flush($Order);
0 ignored issues
show
Unused Code introduced by
The call to EntityManagerInterface::flush() has too many arguments starting with $Order.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
450
            log_info('対応状況一括変更処理完了', [$Order->getId()]);
451
        } catch (\Exception $e) {
452
            log_error('予期しないエラーです', [$e->getMessage()]);
453
454
            return $this->json(['status' => 'NG'], 500);
455
        }
456
457
        return $this->json(['status' => 'OK']);
458
    }
459
460
    /**
461
     * Bulk action to order status
462
     *
463
     * @Method("POST")
464
     * @Route("/%eccube_admin_route%/order/bulk/order-status/{id}", requirements={"id" = "\d+"}, name="admin_order_bulk_order_status")
465
     *
466
     * @param Request $request
0 ignored issues
show
introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
467
     * @param OrderStatus $OrderStatus
468
     *
469
     * @return RedirectResponse
470
     *
471
     * @deprecated 使用していない
472
     */
473 2
    public function bulkOrderStatus(Request $request, OrderStatus $OrderStatus)
474
    {
475 2
        $this->isTokenValid();
476
477
        /** @var Order[] $Orders */
478 2
        $Orders = $this->orderRepository->findBy(['id' => $request->get('ids')]);
479
480 2
        $count = 0;
481 2
        foreach ($Orders as $Order) {
482
            try {
483
                // TODO: should support event for plugin customize
484
                // 編集前の受注情報を保持
485 2
                $OriginOrder = clone $Order;
486
487 2
                $Order->setOrderStatus($OrderStatus);
488
489 2
                $purchaseContext = new PurchaseContext($OriginOrder, $OriginOrder->getCustomer());
490
491 2
                $flowResult = $this->purchaseFlow->validate($Order, $purchaseContext);
492 2
                if ($flowResult->hasWarning()) {
493 1
                    foreach ($flowResult->getWarning() as $warning) {
494 1
                        $msg = $this->translator->trans('admin.order.index.bulk_warning', [
495 1
                          '%orderId%' => $Order->getId(),
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 28 spaces, but found 26.
Loading history...
496 1
                          '%message%' => $warning->getMessage(),
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 28 spaces, but found 26.
Loading history...
497
                        ]);
498 1
                        $this->addWarning($msg, 'admin');
499
                    }
500
                }
501
502 2
                if ($flowResult->hasError()) {
503
                    foreach ($flowResult->getErrors() as $error) {
504
                        $msg = $this->translator->trans('admin.order.index.bulk_error', [
505
                          '%orderId%' => $Order->getId(),
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 28 spaces, but found 26.
Loading history...
506
                          '%message%' => $error->getMessage(),
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 28 spaces, but found 26.
Loading history...
507
                        ]);
508
                        $this->addError($msg, 'admin');
509
                    }
510
                    continue;
511
                }
512
513
                try {
514 2
                    $this->purchaseFlow->commit($Order, $purchaseContext);
515
                } catch (PurchaseException $e) {
516
                    $msg = $this->translator->trans('admin.order.index.bulk_error', [
517
                      '%orderId%' => $Order->getId(),
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 24 spaces, but found 22.
Loading history...
518
                      '%message%' => $e->getMessage(),
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 24 spaces, but found 22.
Loading history...
519
                    ]);
520
                    $this->addError($msg, 'admin');
521
                    continue;
522
                }
523
524 2
                $this->orderRepository->save($Order);
525
526 2
                $count++;
527
            } catch (\Exception $e) {
528 2
                $this->addError('#'.$Order->getId().': '.$e->getMessage(), 'admin');
529
            }
530
        }
531
        try {
532 2 View Code Duplication
            if ($count) {
533 2
                $this->entityManager->flush();
534 2
                $msg = $this->translator->trans('admin.order.index.bulk_order_status_success_count', [
535 2
                    '%count%' => $count,
536 2
                    '%status%' => $OrderStatus->getName(),
537
                ]);
538 2
                $this->addSuccess($msg, 'admin');
539
            }
540
        } catch (\Exception $e) {
541
            log_error('Bulk order status error', [$e]);
542
            $this->addError('admin.flash.register_failed', 'admin');
543
        }
544
545 2
        return $this->redirectToRoute('admin_order', ['resume' => Constant::ENABLED]);
546
    }
547
548
    /**
549
     * Update to Tracking number.
550
     *
551
     * @Method("PUT")
552
     * @Route("/%eccube_admin_route%/shipping/{id}/tracking_number", requirements={"id" = "\d+"}, name="admin_shipping_update_tracking_number")
553
     *
554
     * @param Request $request
0 ignored issues
show
introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
555
     * @param Shipping $shipping
556
     *
557
     * @return Response
558
     */
559 2
    public function updateTrackingNumber(Request $request, Shipping $shipping)
560
    {
561 2
        if (!($request->isXmlHttpRequest() && $this->isTokenValid())) {
562
            return $this->json(['status' => 'NG'], 400);
563
        }
564
565 2
        $trackingNumber = mb_convert_kana($request->get('tracking_number'), 'a', 'utf-8');
566
        /** @var \Symfony\Component\Validator\ConstraintViolationListInterface $errors */
567 2
        $errors = $this->validator->validate(
568 2
            $trackingNumber,
569
            [
570 2
                new Assert\Length(['max' => $this->eccubeConfig['eccube_stext_len']]),
571 2
                new Assert\Regex(
572 2
                    ['pattern' => '/^[0-9a-zA-Z-]+$/u', 'message' => trans('form.type.admin.nottrackingnumberstyle')]
573
                ),
574
            ]
575
        );
576
577 2
        if ($errors->count() != 0) {
578 1
            log_info('送り状番号入力チェックエラー');
579 1
            $messages = [];
580
            /** @var \Symfony\Component\Validator\ConstraintViolationInterface $error */
581 1
            foreach ($errors as $error) {
582 1
                $messages[] = $error->getMessage();
583
            }
584
585 1
            return $this->json(['status' => 'NG', 'messages' => $messages], 400);
586
        }
587
588
        try {
589 1
            $shipping->setTrackingNumber($trackingNumber);
590 1
            $this->entityManager->flush($shipping);
0 ignored issues
show
Unused Code introduced by
The call to EntityManagerInterface::flush() has too many arguments starting with $shipping.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
591 1
            log_info('送り状番号変更処理完了', [$shipping->getId()]);
592 1
            $message = ['status' => 'OK', 'shipping_id' => $shipping->getId(), 'tracking_number' => $trackingNumber];
593
594 1
            return $this->json($message);
595
        } catch (\Exception $e) {
596
            log_error('予期しないエラー', [$e->getMessage()]);
597
598
            return $this->json(['status' => 'NG'], 500);
599
        }
600
    }
601
}
602