Completed
Pull Request — experimental/sf (#3452)
by k-yamamura
420:35 queued 357:42
created

AdminController   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 569
Duplicated Lines 10.54 %

Coupling/Cohesion

Components 2
Dependencies 24

Test Coverage

Coverage 94.51%

Importance

Changes 0
Metric Value
dl 60
loc 569
ccs 172
cts 182
cp 0.9451
rs 10
c 0
b 0
f 0
wmc 26
lcom 2
cbo 24

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 19 1
A login() 0 24 2
B index() 0 90 1
A sale() 0 31 3
A changePassword() 0 54 4
A searchNonStockProducts() 0 12 1
A searchCustomer() 0 11 1
A getOrderEachStatus() 0 26 2
A getSalesByMonth() 30 30 2
A getSalesByDay() 30 30 2
A countNonStockProducts() 0 10 1
A countProducts() 0 9 1
A countCustomers() 0 9 1
A getData() 0 15 1
A convert() 0 15 3

How to fix   Duplicated Code   

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:

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;
15
16
use Carbon\Carbon;
17
use Doctrine\Common\Collections\Criteria;
18
use Doctrine\ORM\NoResultException;
19
use Doctrine\ORM\Query\ResultSetMapping;
20
use Eccube\Controller\AbstractController;
21
use Eccube\Entity\Master\CustomerStatus;
22
use Eccube\Entity\Master\OrderStatus;
23
use Eccube\Entity\Master\ProductStatus;
24
use Eccube\Entity\ProductStock;
25
use Eccube\Event\EccubeEvents;
26
use Eccube\Event\EventArgs;
27
use Eccube\Form\Type\Admin\ChangePasswordType;
28
use Eccube\Form\Type\Admin\LoginType;
29
use Eccube\Repository\CustomerRepository;
30
use Eccube\Repository\Master\OrderStatusRepository;
31
use Eccube\Repository\MemberRepository;
32
use Eccube\Repository\OrderRepository;
33
use Eccube\Repository\ProductRepository;
34
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
35
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
36
use Symfony\Component\HttpFoundation\Request;
37
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
38
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
39
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
40
41
class AdminController extends AbstractController
42
{
43
    /**
44
     * @var AuthorizationCheckerInterface
45
     */
46
    protected $authorizationChecker;
47
48
    /**
49
     * @var AuthenticationUtils
50
     */
51
    protected $helper;
52
53
    /**
54
     * @var MemberRepository
55
     */
56
    protected $memberRepository;
57
58
    /**
59
     * @var EncoderFactoryInterface
60
     */
61
    protected $encoderFactory;
62
63
    /**
64
     * @var OrderRepository
65
     */
66
    protected $orderRepository;
67
68 10
    /**
69
     * @var OrderStatusRepository
70
     */
71
    protected $orderStatusRepository;
72
73
    /**
74 10
     * @var CustomerRepository
75 10
     */
76 10
    protected $customerRepository;
77 10
78
    /**
79
     * @var ProductRepository
80
     */
81
    protected $productRepository;
82
83
    /**
84 2
     * AdminController constructor.
85
     *
86 2
     * @param AuthorizationCheckerInterface $authorizationChecker
87
     * @param AuthenticationUtils $helper
88
     * @param MemberRepository $memberRepository
89
     * @param EncoderFactoryInterface $encoderFactory
90
     * @param OrderRepository $orderRepository
91 2
     * @param OrderStatusRepository $orderStatusRepository
92
     * @param CustomerRepository $custmerRepository
93 2
     * @param ProductRepository $productRepository
94
     */
95 2
    public function __construct(
96
        AuthorizationCheckerInterface $authorizationChecker,
97 2
        AuthenticationUtils $helper,
98
        MemberRepository $memberRepository,
99 2
        EncoderFactoryInterface $encoderFactory,
100
        OrderRepository $orderRepository,
101 2
        OrderStatusRepository $orderStatusRepository,
102
        CustomerRepository $custmerRepository,
103
        ProductRepository $productRepository
104 2
    ) {
105 2
        $this->authorizationChecker = $authorizationChecker;
106
        $this->helper = $helper;
107
        $this->memberRepository = $memberRepository;
108
        $this->encoderFactory = $encoderFactory;
109
        $this->orderRepository = $orderRepository;
110
        $this->orderStatusRepository = $orderStatusRepository;
111
        $this->customerRepository = $custmerRepository;
112
        $this->productRepository = $productRepository;
113 4
    }
114
115
    /**
116 4
     * @Route("/%eccube_admin_route%/login", name="admin_login")
117
     * @Template("@admin/login.twig")
118
     */
119
    public function login(Request $request)
120
    {
121
        if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
122
            return $this->redirectToRoute('admin_homepage');
123
        }
124
125
        /* @var $form \Symfony\Component\Form\FormInterface */
126
        $builder = $this->formFactory->createNamedBuilder('', LoginType::class);
127
128
        $event = new EventArgs(
129
            [
130 4
                'builder' => $builder,
131
            ],
132 4
            $request
133
        );
134 4
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_ADMIM_LOGIN_INITIALIZE, $event);
135
136 4
        $form = $builder->getForm();
137
138 4
        return [
139 4
            'error' => $this->helper->getLastAuthenticationError(),
140 4
            'form' => $form->createView(),
141
        ];
142 4
    }
143
144 4
    /**
145
     * 管理画面ホーム
146
     *
147 4
     * @param Request $request
148
     *
149
     * @return array
150 4
     *
151
     * @throws NoResultException
152
     * @throws \Doctrine\ORM\NonUniqueResultException
153 4
     *
154
     * @Route("/%eccube_admin_route%/", name="admin_homepage")
155
     * @Template("@admin/index.twig")
156
     */
157
    public function index(Request $request)
158 4
    {
159 4
        /**
160 4
         * 受注状況.
161 4
         */
162 4
        $excludes = [];
163
        $excludes[] = OrderStatus::PENDING;
164 4
        $excludes[] = OrderStatus::PROCESSING;
165
        $excludes[] = OrderStatus::CANCEL;
166 4
        $excludes[] = OrderStatus::DELIVERED;
167
168 4
        $event = new EventArgs(
169
            [
170 4
                'excludes' => $excludes,
171 4
            ],
172
            $request
173
        );
174 4
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_ADMIM_INDEX_ORDER, $event);
175
        $excludes = $event->getArgument('excludes');
176 4
177
        // 受注ステータスごとの受注件数.
178
        $Orders = $this->getOrderEachStatus($this->entityManager, $excludes);
179
180
        // 受注ステータスの一覧.
181 4
        $Criteria = new Criteria();
182 4
        $Criteria->where($Criteria::expr()->notIn('id', $excludes));
183 4
        $OrderStatuses = $this->orderStatusRepository->matching($Criteria, $Criteria->orderBy(['sort_no' => 'ASC']));
0 ignored issues
show
Unused Code introduced by
The call to OrderStatusRepository::matching() has too many arguments starting with $Criteria->orderBy(array('sort_no' => 'ASC')).

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...
184 4
185
        /**
186 4
         * 売り上げ状況
187
         */
188 4
        $excludes = [];
189
        $excludes[] = OrderStatus::PROCESSING;
190 4
        $excludes[] = OrderStatus::CANCEL;
191
        $excludes[] = OrderStatus::PENDING;
192 4
193 4
        $event = new EventArgs(
194
            [
195
                'excludes' => $excludes,
196 4
            ],
197
            $request
198 4
        );
199
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_ADMIM_INDEX_SALES, $event);
200 4
        $excludes = $event->getArgument('excludes');
201
202
        // 今日の売上/件数
203
        $salesToday = $this->getSalesByDay($this->entityManager, new \DateTime(), $excludes);
204
        // 昨日の売上/件数
205
        $salesYesterday = $this->getSalesByDay($this->entityManager, new \DateTime('-1 day'), $excludes);
206 4
        // 今月の売上/件数
207
        $salesThisMonth = $this->getSalesByMonth($this->entityManager, new \DateTime(), $excludes);
208 4
209
        /**
210 4
         * ショップ状況
211
         */
212 4
        // 在庫切れ商品数
213 4
        $countNonStockProducts = $this->countNonStockProducts();
214 4
215 4
        // 取り扱い商品数
216 4
        $countProducts = $this->countProducts();
217 4
218 4
        // 本会員数
219
        $countCustomers = $this->countCustomers();
220 4
221
        $event = new EventArgs(
222 4
            [
223
                'Orders' => $Orders,
224
                'OrderStatuses' => $OrderStatuses,
225 4
                'salesThisMonth' => $salesThisMonth,
226 4
                'salesToday' => $salesToday,
227 4
                'salesYesterday' => $salesYesterday,
228 4
                'countNonStockProducts' => $countNonStockProducts,
229 4
                'countProducts' => $countProducts,
230 4
                'countCustomers' => $countCustomers,
231 4
            ],
232 4
            $request
233 4
        );
234 4
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_ADMIM_INDEX_COMPLETE, $event);
235
236
        return [
237
            'Orders' => $Orders,
238
            'OrderStatuses' => $OrderStatuses,
239
            'salesThisMonth' => $salesThisMonth,
240
            'salesToday' => $salesToday,
241
            'salesYesterday' => $salesYesterday,
242
            'countNonStockProducts' => $countNonStockProducts,
243
            'countProducts' => $countProducts,
244
            'countCustomers' => $countCustomers,
245
        ];
246
    }
247
248 3
    /**
249
     * 売上状況の取得
250 3
     *
251 3
     * @param Request $request
252
     *
253 3
     * @Route("/%eccube_admin_route%/sale_chart", name="admin_homepage_sale")
254
     *
255 3
     * @return \Symfony\Component\HttpFoundation\JsonResponse
256
     */
257 3
    public function sale(Request $request)
258
    {
259 3
        if (!($request->isXmlHttpRequest() && $this->isTokenValid())) {
260
            return $this->json(['status' => 'NG'], 400);
261 3
        }
262 3
263
        /**
264 3
         * 売り上げ状況
265 1
         */
266 1
        $excludes = [];
267 1
        $excludes[] = OrderStatus::PROCESSING;
268
        $excludes[] = OrderStatus::CANCEL;
269 1
        $excludes[] = OrderStatus::PENDING;
270
271
        // 週間の売上金額
272 1
        $toDate = Carbon::now();
273
        $fromDate = Carbon::today()->subWeek();
274
        $rawWeekly = $this->getData($excludes, $fromDate, $toDate, 'Y/m/d');
275
276 1
        // 月間の売上金額
277
        $fromDate = Carbon::now()->startOfMonth();
278
        $rawMonthly = $this->getData($excludes, $fromDate, $toDate, 'Y/m/d');
279 1
280 1
        // 年間の売上金額
281
        $fromDate = Carbon::now()->subYear()->startOfMonth();
282 1
        $rawYear = $this->getData($excludes, $fromDate, $toDate, 'Y/m');
283
284 1
        $datas = [$rawWeekly, $rawMonthly, $rawYear];
285
286 1
        return $this->json($datas);
287 1
    }
288
289 1
    /**
290
     * パスワード変更画面
291 1
     *
292
     * @Route("/%eccube_admin_route%/change_password", name="admin_change_password")
293 1
     * @Template("@admin/change_password.twig")
294
     *
295 1
     * @param Request $request
296
     *
297
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|array
298
     */
299 2
    public function changePassword(Request $request)
300
    {
301
        $builder = $this->formFactory
302
            ->createBuilder(ChangePasswordType::class);
303
304
        $event = new EventArgs(
305
            [
306
                'builder' => $builder,
307
            ],
308
            $request
309
        );
310
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_ADMIM_CHANGE_PASSWORD_INITIALIZE, $event);
311
312 2
        $form = $builder->getForm();
313
        $form->handleRequest($request);
314
315
        if ($form->isSubmitted() && $form->isValid()) {
316 2
            $Member = $this->getUser();
317 2
            $salt = $Member->getSalt();
318 2
            $password = $form->get('change_password')->getData();
319
320 2
            $encoder = $this->encoderFactory->getEncoder($Member);
0 ignored issues
show
Documentation introduced by
$Member is of type null|object, but the function expects a object<Symfony\Component...r\UserInterface>|string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
321 2
322
            // 2系からのデータ移行でsaltがセットされていない場合はsaltを生成.
323 1
            if (empty($salt)) {
324 1
                $salt = $encoder->createSalt();
325 1
            }
326 1
327
            $password = $encoder->encodePassword($password, $salt);
328 1
329 1
            $Member
330 1
                ->setPassword($password)
331
                ->setSalt($salt);
332
333 1
            $this->memberRepository->save($Member);
0 ignored issues
show
Documentation introduced by
$Member is of type null|object, but the function expects a object<Eccube\Entity\Member>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
334
335
            $event = new EventArgs(
336
                [
337
                    'form' => $form,
338
                    'Member' => $Member,
339
                ],
340
                $request
341
            );
342 4
            $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_ADMIN_CHANGE_PASSWORD_COMPLETE, $event);
343
344
            $this->addSuccess('admin.change_password.save.complete', 'admin');
345
346 4
            return $this->redirectToRoute('admin_change_password');
347 4
        }
348
349
        return [
350 4
            'form' => $form->createView(),
351 4
        ];
352 4
    }
353 4
354
    /**
355
     * 在庫なし商品の検索結果を表示する.
356
     *
357
     * @Route("/%eccube_admin_route%/search_nonstock", name="admin_homepage_nonstock")
358
     *
359
     * @param Request $request
360
     *
361
     * @return \Symfony\Component\HttpFoundation\Response
362 4
     */
363
    public function searchNonStockProducts(Request $request)
364 4
    {
365
        // 在庫なし商品の検索条件をセッションに付与し, 商品マスタへリダイレクトする.
366
        $searchData = [];
367
        $searchData['stock'] = [ProductStock::OUT_OF_STOCK];
368
        $session = $request->getSession();
369
        $session->set('eccube.admin.product.search', $searchData);
370
371
        return $this->redirectToRoute('admin_product_page', [
372
            'page_no' => 1,
373
            'status' => $this->eccubeConfig['eccube_admin_product_stock_status'], ]);
374
    }
375 4
376 4
    /**
377 4
     * 本会員の検索結果を表示する.
378 4
     *
379 4
     * @Route("/%eccube_admin_route%/search_customer", name="admin_homepage_customer")
380 4
     *
381 4
     * @param Request $request
382 4
     *
383 1
     * @return \Symfony\Component\HttpFoundation\Response
384
     */
385
    public function searchCustomer(Request $request)
386 4
    {
387
        $searchData = [];
388
        $searchData['customer_status'] = [CustomerStatus::REGULAR];
389
        $session = $request->getSession();
390
        $session->set('eccube.admin.customer.search', $searchData);
391
392
        return $this->redirectToRoute('admin_customer_page', [
393
            'page_no' => 1,
394
        ]);
395
    }
396 4
397
    /**
398
     * @param \Doctrine\ORM\EntityManagerInterface $em
399
     * @param array $excludes
400 4
     *
401
     * @return null|Request
402
     */
403
    private function getOrderEachStatus($em, array $excludes)
404
    {
405
        $sql = 'SELECT
406
                    t1.order_status_id as status,
407
                    COUNT(t1.id) as count
408
                FROM
409
                    dtb_order t1
410
                WHERE
411
                    t1.order_status_id NOT IN (:excludes)
412
                GROUP BY
413 4
                    t1.order_status_id
414 4
                ORDER BY
415 4
                    t1.order_status_id';
416
        $rsm = new ResultSetMapping();
417 4
        $rsm->addScalarResult('status', 'status');
418
        $rsm->addScalarResult('count', 'count');
419 4
        $query = $em->createNativeQuery($sql, $rsm);
420 3
        $query->setParameters([':excludes' => $excludes]);
421
        $result = $query->getResult();
422
        $orderArray = [];
423
        foreach ($result as $row) {
424 4
            $orderArray[$row['status']] = $row['count'];
425
        }
426
427
        return $orderArray;
428
    }
429
430
    /**
431
     * @param \Doctrine\ORM\EntityManagerInterface $em
432
     * @param \DateTime $dateTime
433
     * @param array $excludes
434 4
     *
435
     * @return null|Request
436
     */
437 View Code Duplication
    private function getSalesByMonth($em, $dateTime, array $excludes)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
438 4
    {
439
        // concat... for pgsql
440
        // http://stackoverflow.com/questions/1091924/substr-does-not-work-with-datatype-timestamp-in-postgres-8-3
441
        $dql = 'SELECT
442
                  SUBSTRING(CONCAT(o.order_date, \'\'), 1, 7) AS order_month,
443
                  SUM(o.payment_total) AS order_amount,
444
                  COUNT(o) AS order_count
445
                FROM
446
                  Eccube\Entity\Order o
447
                WHERE
448
                    o.OrderStatus NOT IN (:excludes)
449
                    AND SUBSTRING(CONCAT(o.order_date, \'\'), 1, 7) = SUBSTRING(:targetDate, 1, 7)
450
                GROUP BY
451 4
                  order_month';
452 4
453 4
        $q = $em
454
            ->createQuery($dql)
455 4
            ->setParameter(':excludes', $excludes)
456
            ->setParameter(':targetDate', $dateTime);
457 4
458 3
        $result = [];
459
        try {
460
            $result = $q->getSingleResult();
461
        } catch (NoResultException $e) {
462 4
            // 結果がない場合は空の配列を返す.
463
        }
464
465
        return $result;
466
    }
467
468
    /**
469
     * @param \Doctrine\ORM\EntityManagerInterface $em
470
     * @param \DateTime $dateTime
471
     * @param array $excludes
472
     *
473 4
     * @return null|Request
474
     */
475 View Code Duplication
    private function getSalesByDay($em, $dateTime, array $excludes)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
476 4
    {
477 4
        // concat... for pgsql
478 4
        // http://stackoverflow.com/questions/1091924/substr-does-not-work-with-datatype-timestamp-in-postgres-8-3
479 4
        $dql = 'SELECT
480 4
                  SUBSTRING(CONCAT(o.order_date, \'\'), 1, 10) AS order_day,
481 4
                  SUM(o.payment_total) AS order_amount,
482
                  COUNT(o) AS order_count
483
                FROM
484 4
                  Eccube\Entity\Order o
485 4
                WHERE
486
                    o.OrderStatus NOT IN (:excludes)
487
                    AND SUBSTRING(CONCAT(o.order_date, \'\'), 1, 10) = SUBSTRING(:targetDate, 1, 10)
488
                GROUP BY
489
                  order_day';
490
491
        $q = $em
492
            ->createQuery($dql)
493
            ->setParameter(':excludes', $excludes)
494
            ->setParameter(':targetDate', $dateTime);
495
496 4
        $result = [];
497
        try {
498
            $result = $q->getSingleResult();
499 4
        } catch (NoResultException $e) {
500 4
            // 結果がない場合は空の配列を返す.
501
        }
502
503 4
        return $result;
504 4
    }
505 4
506 4
    /**
507 4
     * 在庫切れ商品数を取得
508
     *
509
     * @return mixed
510 4
     *
511 4
     * @throws \Doctrine\ORM\NonUniqueResultException
512
     */
513
    private function countNonStockProducts()
514
    {
515
        $qb = $this->productRepository->createQueryBuilder('p')
516
            ->select('count(DISTINCT p.id)')
517
            ->innerJoin('p.ProductClasses', 'pc')
518
            ->where('pc.stock_unlimited = :StockUnlimited AND pc.stock = 0')
519
            ->setParameter('StockUnlimited', false);
520
521
        return $qb->getQuery()->getSingleScalarResult();
522
    }
523
524
    /**
525
     * 商品数を取得
526
     *
527
     * @return mixed
528
     *
529
     * @throws \Doctrine\ORM\NonUniqueResultException
530
     */
531
    private function countProducts()
532
    {
533
        $qb = $this->productRepository->createQueryBuilder('p')
534
            ->select('count(p.id)')
535
            ->where('p.Status in (:Status)')
536
            ->setParameter('Status', [ProductStatus::DISPLAY_SHOW, ProductStatus::DISPLAY_HIDE]);
537
538
        return $qb->getQuery()->getSingleScalarResult();
539
    }
540
541
    /**
542
     * 本会員数を取得
543
     *
544
     * @return mixed
545
     *
546
     * @throws \Doctrine\ORM\NonUniqueResultException
547
     */
548
    private function countCustomers()
549
    {
550
        $qb = $this->customerRepository->createQueryBuilder('c')
551
            ->select('count(c.id)')
552
            ->where('c.Status = :Status')
553
            ->setParameter('Status', CustomerStatus::REGULAR);
554
555
        return $qb->getQuery()->getSingleScalarResult();
556
    }
557
558
    /**
559
     * 期間指定のデータを取得
560
     *
561
     * @param array $excludes
562
     * @param Carbon $fromDate
563
     * @param Carbon $toDate
564
     * @param $format
565
     *
566
     * @return array
567
     */
568
    private function getData(array $excludes, Carbon $fromDate, Carbon $toDate, $format)
569
    {
570
        $qb = $this->orderRepository->createQueryBuilder('o')
571
            ->andWhere('o.order_date >= :fromDate')
572
            ->andWhere('o.order_date <= :toDate')
573
            ->andWhere('o.OrderStatus NOT IN (:excludes)')
574
            ->setParameter(':excludes', $excludes)
575
            ->setParameter(':fromDate', $fromDate->copy())
576
            ->setParameter(':toDate', $toDate->copy())
577
            ->orderBy('o.order_date');
578
579
        $result = $qb->getQuery()->getResult();
580
581
        return $this->convert($result, $fromDate, $toDate, $format);
582
    }
583
584
    /**
585
     * 期間毎にデータをまとめる
586
     *
587
     * @param $result
588
     * @param Carbon $fromDate
589
     * @param Carbon $toDate
590
     * @param $format
591
     *
592
     * @return array
593
     */
594
    private function convert($result, Carbon $fromDate, Carbon $toDate, $format)
595
    {
596
        $raw = [];
597
        for ($date = $fromDate; $date <= $toDate; $date = $date->addDay()) {
598
            $raw[$date->format($format)]['price'] = 0;
599
            $raw[$date->format($format)]['count'] = 0;
600
        }
601
602
        foreach ($result as $Order) {
603
            $raw[$Order->getOrderDate()->format($format)]['price'] += $Order->getPaymentTotal();
604
            ++$raw[$Order->getOrderDate()->format($format)]['count'];
605
        }
606
607
        return $raw;
608
    }
609
}
610