ReportsController   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 13
eloc 64
c 1
b 0
f 0
dl 0
loc 120
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
C indexAction() 0 87 12
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MonsieurBiz\SyliusSalesReportsPlugin\Controller\Admin;
6
7
use MonsieurBiz\SyliusSalesReportsPlugin\Event\CustomReportEvent;
8
use MonsieurBiz\SyliusSalesReportsPlugin\Exception\InvalidDateException;
9
use MonsieurBiz\SyliusSalesReportsPlugin\Form\Type\PeriodType;
10
use MonsieurBiz\SyliusSalesReportsPlugin\Repository\ReportRepository;
11
use Sylius\Component\Core\Model\ChannelInterface;
12
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
13
use Symfony\Component\Form\FormError;
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\HttpFoundation\Response;
16
use MonsieurBiz\SyliusSalesReportsPlugin\Form\Type\DateType;
17
use Webmozart\Assert\Assert;
18
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
19
20
final class ReportsController extends AbstractController
21
{
22
    const APPEND_REPORTS_EVENT = 'monsieurbiz.sylius_sales_report.append_reports';
23
24
    /**
25
     * @var ReportRepository
26
     */
27
    protected $reportRepository;
28
29
    /**
30
     * @var EventDispatcherInterface
31
     */
32
    protected $eventDispatcher;
33
34
    /**
35
     * ReportsController constructor.
36
     * @param ReportRepository $reportRepository
37
     * @param EventDispatcherInterface $eventDispatcher
38
     */
39
    public function __construct(
40
        ReportRepository $reportRepository,
41
        EventDispatcherInterface $eventDispatcher
42
    ) {
43
        $this->reportRepository = $reportRepository;
44
        $this->eventDispatcher = $eventDispatcher;
45
    }
46
47
    /**
48
     * View the report for a single date
49
     *
50
     * @param Request $request
51
     * @return Response
52
     */
53
    public function indexAction(Request $request): Response
54
    {
55
        $form = $this->createForm(DateType::class);
56
        $formPeriod = $this->createForm(PeriodType::class);
57
58
        // Form not submitted yet
59
        if (null === $request->request->get($form->getName()) && null === $request->request->get($formPeriod->getName())) {
60
            return $this->render('@MonsieurBizSyliusSalesReportsPlugin/Admin/index.html.twig', [
61
                'form' => $form->createView(),
62
                'form_period' => $formPeriod->createView(),
63
            ]);
64
        }
65
66
        // Submit request data and return form if form is not valid
67
        if ($request->request->get($form->getName())) {
68
            $form->submit($request->request->get($form->getName()));
69
            if (!$form->isSubmitted() || !$form->isValid()) {
70
                return $this->render('@MonsieurBizSyliusSalesReportsPlugin/Admin/index.html.twig', [
71
                    'form' => $form->createView(),
72
                    'form_period' => $formPeriod->createView(),
73
                ]);
74
            }
75
        }
76
77
        // Submit request data and return form period if form period is not valid
78
        if ($request->request->get($formPeriod->getName())) {
79
            $formPeriod->submit($request->request->get($formPeriod->getName()));
80
            if (!$formPeriod->isSubmitted() || !$formPeriod->isValid()) {
81
                return $this->render('@MonsieurBizSyliusSalesReportsPlugin/Admin/index.html.twig', [
82
                    'form' => $form->createView(),
83
                    'form_period' => $formPeriod->createView(),
84
                ]);
85
            }
86
        }
87
88
        // Assert retrieved data
89
        $data = $form->getData();
90
        $isPeriod = false;
91
        if (!$data) {
92
            $data = $formPeriod->getData();
93
            $isPeriod = true;
94
        }
95
        $channel = $data['channel'];
96
        $from = $data['date'] ?? $data['from'];
97
        $to = $data['date'] ?? $data['to'];
98
99
        // Reverse date if from date greater than end date
100
        if ($from > $to) {
101
            $tmp = $to; $to = $from; $from = $tmp; $data['from'] = $from; $data['to'] = $to;
102
        }
103
104
        Assert::isInstanceOf($channel, ChannelInterface::class);
105
        Assert::isInstanceOf($from, \DateTimeInterface::class);
106
        Assert::isInstanceOf($to, \DateTimeInterface::class);
107
108
        // Form is valid, we can generate the report
109
        try {
110
            $totalSalesResult = $this->reportRepository->getSalesForChannelForDates($channel, $from, $to);
111
            $averageSalesResult = $this->reportRepository->getAverageSalesForChannelForDates($channel, $from, $to);
112
            $productSalesResult = $this->reportRepository->getProductSalesForChannelForDates($channel, $from, $to);
113
            $productVariantSalesResult = $this->reportRepository->getProductVariantSalesForChannelForDates($channel, $from, $to);
114
            $productOptionSalesResult = $this->reportRepository->getProductOptionSalesForChannelForDates($channel, $from, $to);
115
            $productOptionValueSalesResult = $this->reportRepository->getProductOptionValueSalesForChannelForDates($channel, $from, $to);
116
        } catch (InvalidDateException $e) {
117
            $form->addError(new FormError($e->getMessage()));
118
            return $this->render('@MonsieurBizSyliusSalesReportsPlugin/Admin/index.html.twig', [
119
                'form' => $form->createView(),
120
            ]);
121
        }
122
123
        $event = new CustomReportEvent($channel, $from, $to);
124
        $this->eventDispatcher->dispatch($event);
125
126
        return $this->render('@MonsieurBizSyliusSalesReportsPlugin/Admin/view.html.twig', [
127
            'form' => $form->createView(),
128
            'form_period' => $formPeriod->createView(),
129
            'from' => $from,
130
            'to' => $to,
131
            'channel' => $data['channel'],
132
            'total_sales_result' => $totalSalesResult,
133
            'average_sales_result' => $averageSalesResult,
134
            'product_sales_result' => $productSalesResult,
135
            'product_variant_sales_result' => $productVariantSalesResult,
136
            'product_option_sales_result' => $productOptionSalesResult,
137
            'product_option_value_sales_result' => $productOptionValueSalesResult,
138
            'is_period' => $isPeriod,
139
            'custom_reports' => $event->getCustomReports(),
140
        ]);
141
    }
142
}
143