Completed
Pull Request — experimental/sf (#3292)
by Kiyotaka
733:30 queued 724:35
created

OrderController::index()   C

Complexity

Conditions 10
Paths 24

Size

Total Lines 124

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 54
CRAP Score 10.0328

Importance

Changes 0
Metric Value
cc 10
nc 24
nop 3
dl 0
loc 124
ccs 54
cts 58
cp 0.931
crap 10.0328
rs 6.1333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Util\FormUtil;
33
use Knp\Component\Pager\PaginatorInterface;
34
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
35
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
36
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
37
use Symfony\Component\HttpFoundation\Request;
38
use Symfony\Component\HttpFoundation\StreamedResponse;
39
use Eccube\Entity\Master\OrderStatus;
40
use Symfony\Component\HttpFoundation\RedirectResponse;
41
use Eccube\Entity\Order;
42
use Eccube\Service\PurchaseFlow\PurchaseContext;
43
use Eccube\Service\PurchaseFlow\PurchaseFlow;
44
use Eccube\Service\PurchaseFlow\PurchaseException;
45
46
class OrderController extends AbstractController
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
47
{
48
    /**
49
     * @var PurchaseFlow
50
     */
51
    protected $purchaseFlow;
52
53
    /**
54
     * @var CsvExportService
55
     */
56
    protected $csvExportService;
57
58
    /**
59
     * @var CustomerRepository
60
     */
61
    protected $customerRepository;
62
63
    /**
64
     * @var PaymentRepository
65
     */
66
    protected $paymentRepository;
67
68
    /**
69
     * @var SexRepository
70
     */
71
    protected $sexRepository;
72
73
    /**
74
     * @var OrderStatusRepository
75
     */
76
    protected $orderStatusRepository;
77
78
    /**
79
     * @var PageMaxRepository
80
     */
81
    protected $pageMaxRepository;
82
83
    /**
84
     * @var ProductStatusRepository
85
     */
86
    protected $productStatusRepository;
87
88
    /**
89
     * @var OrderRepository
90
     */
91
    protected $orderRepository;
92
93
    /**
94
     * OrderController constructor.
95
     *
96
     * @param PurchaseFlow $orderPurchaseFlow
0 ignored issues
show
introduced by
Expected 12 spaces after parameter type; 1 found
Loading history...
97
     * @param CsvExportService $csvExportService
0 ignored issues
show
introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
98
     * @param CustomerRepository $customerRepository
0 ignored issues
show
introduced by
Expected 6 spaces after parameter type; 1 found
Loading history...
99
     * @param PaymentRepository $paymentRepository
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
100
     * @param SexRepository $sexRepository
0 ignored issues
show
introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
101
     * @param OrderStatusRepository $orderStatusRepository
0 ignored issues
show
introduced by
Expected 3 spaces after parameter type; 1 found
Loading history...
102
     * @param PageMaxRepository $pageMaxRepository
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
103
     * @param ProductStatusRepository $productStatusRepository
104
     * @param OrderRepository $orderRepository
0 ignored issues
show
introduced by
Expected 9 spaces after parameter type; 1 found
Loading history...
105
     */
106 12
    public function __construct(
107
        PurchaseFlow $orderPurchaseFlow,
108
        CsvExportService $csvExportService,
109
        CustomerRepository $customerRepository,
110
        PaymentRepository $paymentRepository,
111
        SexRepository $sexRepository,
112
        OrderStatusRepository $orderStatusRepository,
113
        PageMaxRepository $pageMaxRepository,
114
        ProductStatusRepository $productStatusRepository,
115
        OrderRepository $orderRepository
116
    ) {
117 12
        $this->purchaseFlow = $orderPurchaseFlow;
118 12
        $this->csvExportService = $csvExportService;
119 12
        $this->customerRepository = $customerRepository;
120 12
        $this->paymentRepository = $paymentRepository;
121 12
        $this->sexRepository = $sexRepository;
122 12
        $this->orderStatusRepository = $orderStatusRepository;
123 12
        $this->pageMaxRepository = $pageMaxRepository;
124 12
        $this->productStatusRepository = $productStatusRepository;
125 12
        $this->orderRepository = $orderRepository;
126
    }
127
128
    /**
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...
129
     * 受注一覧画面.
130
     *
131
     * - 検索条件, ページ番号, 表示件数はセッションに保持されます.
132
     * - クエリパラメータでresume=1が指定された場合、検索条件, ページ番号, 表示件数をセッションから復旧します.
133
     * - 各データの, セッションに保持するアクションは以下の通りです.
134
     *   - 検索ボタン押下時
135
     *      - 検索条件をセッションに保存します
136
     *      - ページ番号は1で初期化し、セッションに保存します。
137
     *   - 表示件数変更時
138
     *      - クエリパラメータpage_countをセッションに保存します。
139
     *      - ただし, mtb_page_maxと一致しない場合, eccube_default_page_countが保存されます.
140
     *   - ページング時
141
     *      - URLパラメータpage_noをセッションに保存します.
142
     *   - 初期表示
143
     *      - 検索条件は空配列, ページ番号は1で初期化し, セッションに保存します.
144
     *
145
     * @Route("/%eccube_admin_route%/order", name="admin_order")
146
     * @Route("/%eccube_admin_route%/order/page/{page_no}", requirements={"page_no" = "\d+"}, name="admin_order_page")
147
     * @Template("@admin/Order/index.twig")
148
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
149 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...
150
    {
151 8
        $builder = $this->formFactory
152 8
            ->createBuilder(SearchOrderType::class);
153
154 8
        $event = new EventArgs(
155
            [
156 8
                'builder' => $builder,
157
            ],
158 8
            $request
159
        );
160 8
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_ORDER_INDEX_INITIALIZE, $event);
161
162 8
        $searchForm = $builder->getForm();
163
164
        /**
165
         * ページの表示件数は, 以下の順に優先される.
166
         * - リクエストパラメータ
167
         * - セッション
168
         * - デフォルト値
169
         * また, セッションに保存する際は mtb_page_maxと照合し, 一致した場合のみ保存する.
170
         **/
171 8
        $page_count = $this->session->get('eccube.admin.order.search.page_count',
172 8
                $this->eccubeConfig->get('eccube_default_page_count'));
173
174 8
        $page_count_param = (int) $request->get('page_count');
175 8
        $pageMaxis = $this->pageMaxRepository->findAll();
176
177 8
        if ($page_count_param) {
178 1
            foreach ($pageMaxis as $pageMax) {
179 1
                if ($page_count_param == $pageMax->getName()) {
180
                    $page_count = $pageMax->getName();
181
                    $this->session->set('eccube.admin.order.search.page_count', $page_count);
182 1
                    break;
183
                }
184
            }
185
        }
186
187 8
        if ('POST' === $request->getMethod()) {
188 6
            $searchForm->handleRequest($request);
189
190 6
            if ($searchForm->isValid()) {
191
                /**
192
                 * 検索が実行された場合は, セッションに検索条件を保存する.
193
                 * ページ番号は最初のページ番号に初期化する.
194
                 */
195 5
                $page_no = 1;
196 5
                $searchData = $searchForm->getData();
197
198
                // 検索条件, ページ番号をセッションに保持.
199 5
                $this->session->set('eccube.admin.order.search', FormUtil::getViewData($searchForm));
200 5
                $this->session->set('eccube.admin.order.search.page_no', $page_no);
201
            } else {
202
                // 検索エラーの際は, 詳細検索枠を開いてエラー表示する.
203
                return [
204 6
                    'searchForm' => $searchForm->createView(),
205
                    'pagination' => [],
206 1
                    'pageMaxis' => $pageMaxis,
207 1
                    'page_no' => $page_no,
208 1
                    'page_count' => $page_count,
209
                    'has_errors' => true,
210
                ];
211
            }
212
        } else {
213 3
            if (null !== $page_no || $request->get('resume')) {
214
                /*
215
                 * ページ送りの場合または、他画面から戻ってきた場合は, セッションから検索条件を復旧する.
216
                 */
217 1
                if ($page_no) {
218
                    // ページ送りで遷移した場合.
219 1
                    $this->session->set('eccube.admin.order.search.page_no', (int) $page_no);
220
                } else {
221
                    // 他画面から遷移した場合.
222
                    $page_no = $this->session->get('eccube.admin.order.search.page_no', 1);
223
                }
224 1
                $viewData = $this->session->get('eccube.admin.order.search', []);
225 1
                $searchData = FormUtil::submitAndGetData($searchForm, $viewData);
226
            } else {
227
                /**
228
                 * 初期表示の場合.
229
                 */
230 2
                $page_no = 1;
231 2
                $viewData = [];
232
233 2
                if ($statusId = (int) $request->get('order_status_id')) {
234
                    $viewData = ['status' => $statusId];
235
                }
236
237 2
                $searchData = FormUtil::submitAndGetData($searchForm, $viewData);
238
239
                // セッション中の検索条件, ページ番号を初期化.
240 2
                $this->session->set('eccube.admin.order.search', $viewData);
241 2
                $this->session->set('eccube.admin.order.search.page_no', $page_no);
242
            }
243
        }
244
245 8
        $qb = $this->orderRepository->getQueryBuilderBySearchDataForAdmin($searchData);
246
247 8
        $event = new EventArgs(
248
            [
249 8
                'qb' => $qb,
250 8
                'searchData' => $searchData,
251
            ],
252 8
            $request
253
        );
254
255 8
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_ORDER_INDEX_SEARCH, $event);
256
257 8
        $pagination = $paginator->paginate(
258 8
            $qb,
259 8
            $page_no,
260 8
            $page_count
261
        );
262
263
        return [
264 8
            'searchForm' => $searchForm->createView(),
265 8
            'pagination' => $pagination,
266 8
            'pageMaxis' => $pageMaxis,
267 8
            'page_no' => $page_no,
268 8
            'page_count' => $page_count,
269
            'has_errors' => false,
270 8
            'OrderStatuses' => $this->orderStatusRepository->findBy([], ['sort_no' => 'ASC']),
271
        ];
272
    }
273
274
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
275
     * @Method("POST")
276
     * @Route("/%eccube_admin_route%/order/bulk_delete", name="admin_order_bulk_delete")
277
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
278 1
    public function bulkDelete(Request $request)
279
    {
280 1
        $this->isTokenValid();
281 1
        $ids = $request->get('ids');
282 1
        foreach ($ids as $order_id) {
283 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...
284 1
                ->find($order_id);
285 1
            if ($Order) {
286 1
                $this->entityManager->remove($Order);
287 1
                log_info('受注削除', [$Order->getId()]);
288
            }
289
        }
290
291 1
        $this->entityManager->flush();
292
293 1
        $this->addSuccess('admin.order.delete.complete', 'admin');
294
295 1
        return $this->redirect($this->generateUrl('admin_order', ['resume' => Constant::ENABLED]));
296
    }
297
298
    /**
299
     * 受注CSVの出力.
300
     *
301
     * @Route("/%eccube_admin_route%/order/export/order", name="admin_order_export_order")
302
     *
303
     * @param Request $request
304
     *
305
     * @return StreamedResponse
306
     */
307 1
    public function exportOrder(Request $request)
308
    {
309
        // タイムアウトを無効にする.
310 1
        set_time_limit(0);
311
312
        // sql loggerを無効にする.
313 1
        $em = $this->entityManager;
314 1
        $em->getConfiguration()->setSQLLogger(null);
315
316 1
        $response = new StreamedResponse();
317 1
        $response->setCallback(function () use ($request) {
318
            // CSV種別を元に初期化.
319 1
            $this->csvExportService->initCsvType(CsvType::CSV_TYPE_ORDER);
320
321
            // ヘッダ行の出力.
322
            $this->csvExportService->exportHeader();
323
324
            // 受注データ検索用のクエリビルダを取得.
325
            $qb = $this->csvExportService
326
                ->getOrderQueryBuilder($request);
327
328
            // データ行の出力.
329
            $this->csvExportService->setExportQueryBuilder($qb);
330
            $this->csvExportService->exportData(function ($entity, $csvService) use ($request) {
331
                $Csvs = $csvService->getCsvs();
332
333
                $Order = $entity;
334
                $OrderItems = $Order->getOrderItems();
335
336
                foreach ($OrderItems as $OrderItem) {
337
                    $ExportCsvRow = new \Eccube\Entity\ExportCsvRow();
338
339
                    // CSV出力項目と合致するデータを取得.
340
                    foreach ($Csvs as $Csv) {
341
                        // 受注データを検索.
342
                        $ExportCsvRow->setData($csvService->getData($Csv, $Order));
343
                        if ($ExportCsvRow->isDataNull()) {
344
                            // 受注データにない場合は, 受注明細を検索.
345
                            $ExportCsvRow->setData($csvService->getData($Csv, $OrderItem));
346
                        }
347
                        if ($ExportCsvRow->isDataNull() && $Shipping = $OrderItem->getShipping()) {
348
                            // 受注明細データにない場合は, 出荷を検索.
349
                            $ExportCsvRow->setData($csvService->getData($Csv, $Shipping));
350
                        }
351
352
                        $event = new EventArgs(
353
                            [
354
                                'csvService' => $csvService,
355
                                'Csv' => $Csv,
356
                                'OrderItem' => $OrderItem,
357
                                'ExportCsvRow' => $ExportCsvRow,
358
                            ],
359
                            $request
360
                        );
361
                        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_ORDER_CSV_EXPORT_ORDER, $event);
362
363
                        $ExportCsvRow->pushData();
364
                    }
365
366
                    //$row[] = number_format(memory_get_usage(true));
367
                    // 出力.
368
                    $csvService->fputcsv($ExportCsvRow->getRow());
369
                }
370
            });
371 1
        });
372
373 1
        $now = new \DateTime();
374 1
        $filename = 'order_'.$now->format('YmdHis').'.csv';
375 1
        $response->headers->set('Content-Type', 'application/octet-stream');
376 1
        $response->headers->set('Content-Disposition', 'attachment; filename='.$filename);
377 1
        $response->send();
378
379
        log_info('受注CSV出力ファイル名', [$filename]);
380
381
        return $response;
382
    }
383
384
    /**
385
     * Bulk action to order status
386
     *
387
     * @Method("POST")
388
     * @Route("/%eccube_admin_route%/order/bulk/order-status/{id}", requirements={"id" = "\d+"}, name="admin_order_bulk_order_status")
389
     *
390
     * @param Request $request
0 ignored issues
show
introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
391
     * @param OrderStatus $OrderStatus
392
     *
393
     * @return RedirectResponse
394
     */
395 2
    public function bulkOrderStatus(Request $request, OrderStatus $OrderStatus)
396
    {
397 2
        $this->isTokenValid();
398
399
        /** @var Order[] $Orders */
400 2
        $Orders = $this->orderRepository->findBy(['id' => $request->get('ids')]);
401
402 2
        $count = 0;
403 2
        foreach ($Orders as $Order) {
404
            try {
405
                // TODO: should support event for plugin customize
406
                // 編集前の受注情報を保持
407 2
                $OriginOrder = clone $Order;
408
409 2
                $Order->setOrderStatus($OrderStatus);
410
411 2
                $purchaseContext = new PurchaseContext($OriginOrder, $OriginOrder->getCustomer());
412
413 2
                $flowResult = $this->purchaseFlow->validate($Order, $purchaseContext);
414 2
                if ($flowResult->hasWarning()) {
415
                    foreach ($flowResult->getWarning() as $warning) {
416
                        $msg = $this->translator->trans('admin.order.index.bulk_warning', [
417
                          '%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...
418
                          '%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...
419
                        ]);
420
                        $this->addWarning($msg, 'admin');
421
                    }
422
                }
423
424 2
                if ($flowResult->hasError()) {
425
                    foreach ($flowResult->getErrors() as $error) {
426
                        $msg = $this->translator->trans('admin.order.index.bulk_error', [
427
                          '%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...
428
                          '%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...
429
                        ]);
430
                        $this->addError($msg, 'admin');
431
                    }
432
                    continue;
433
                }
434
435
                try {
436 2
                    $this->purchaseFlow->commit($Order, $purchaseContext);
437
                } catch (PurchaseException $e) {
438
                    $msg = $this->translator->trans('admin.order.index.bulk_error', [
439
                      '%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...
440
                      '%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...
441
                    ]);
442
                    $this->addError($msg, 'admin');
443
                    continue;
444
                }
445
446 2
                $this->orderRepository->save($Order);
447
448 2
                $count++;
449
            } catch (\Exception $e) {
450 2
                $this->addError('#'.$Order->getId().': '.$e->getMessage(), 'admin');
451
            }
452
        }
453
        try {
454 2 View Code Duplication
            if ($count) {
455 2
                $this->entityManager->flush();
456 2
                $msg = $this->translator->trans('admin.order.index.bulk_order_status_success_count', [
457 2
                    '%count%' => $count,
458 2
                    '%status%' => $OrderStatus->getName(),
459
                ]);
460 2
                $this->addSuccess($msg, 'admin');
461
            }
462
        } catch (\Exception $e) {
463
            log_error('Bulk order status error', [$e]);
464
            $this->addError('admin.flash.register_failed', 'admin');
465
        }
466
467 2
        return $this->redirectToRoute('admin_order', ['resume' => Constant::ENABLED]);
468
    }
469
}
470