Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
45 / 45
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
StatsController
100.00% covered (success)
100.00%
45 / 45
100.00% covered (success)
100.00%
3 / 3
5
100.00% covered (success)
100.00%
1 / 1
 brandStats
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 questionStats
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 answersByDays
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace App\Http\Controllers\Api\V2;
4
5use App\Http\Controllers\Controller;
6use App\Http\Requests\Api\V2\GetBrandStatsRequest;
7use App\Http\Requests\Api\V2\GetQuestionStatsRequest;
8use App\Http\Resources\Api\V2\BrandStatsResource;
9use App\Http\Resources\Api\V2\QuestionStatsResource;
10use App\Models\BrandStat;
11use App\Models\CustomerAnswer;
12use App\Models\Question;
13use App\Models\Service;
14use Illuminate\Http\Resources\Json\ResourceCollection;
15use Illuminate\Support\Carbon;
16use Illuminate\Support\Collection;
17
18class StatsController extends Controller
19{
20    /**
21     * Get specific brand statistics.
22     *
23     * @param \App\Http\Requests\Api\V2\GetBrandStatsRequest $request
24     * @param \App\Models\Service                            $service
25     * @return \Illuminate\Http\Resources\Json\ResourceCollection
26     */
27    public function brandStats(GetBrandStatsRequest $request, Service $service): ResourceCollection
28    {
29        $stats = BrandStat::query()->whereDate('created_at', '>=', $request->start)
30            ->whereDate('created_at', '<=', $request->end)
31            ->whereBrandId($service->brand->id)->get();
32        return new BrandStatsResource($stats);
33    }
34
35    /**
36     * Get statistics for a specific question.
37     *
38     * @param \App\Http\Requests\Api\V2\GetQuestionStatsRequest $request
39     * @param \App\Models\Question                              $question
40     * @return \App\Http\Resources\Api\V2\QuestionStatsResource
41     */
42    public function questionStats(GetQuestionStatsRequest $request, Question $question): QuestionStatsResource
43    {
44        // * Make sure we are accessing a customer that belongs to our service.
45        $this->authorize('questionBelongsToService', $question);
46
47        $answers = $question->answers;
48        $start   = Carbon::parse($request->start);
49        $end     = Carbon::parse($request->end);
50
51        return new QuestionStatsResource(
52            $this->answersByDays($answers, $start, $end),
53            $question
54        );
55    }
56
57    /**
58     * Total rĂ©ponses par dates.
59     *
60     * @param \Illuminate\Support\Collection $answers
61     * @param \Illuminate\Support\Carbon     $start
62     * @param \Illuminate\Support\Carbon     $end
63     * @return \Illuminate\Support\Collection
64     */
65    private function answersByDays(Collection $answers, Carbon $start, Carbon $end): Collection
66    {
67        // * Totalize by date all answers.
68        $answersByDays = CustomerAnswer::query()->whereDate('created_at', '>=', $start)
69            ->whereDate('created_at', '<=', $end)
70            ->whereIn('answer_id', $answers->pluck('id'))
71            ->get()->map(function ($custAnswer) {
72                return [
73                    'answer_id' => $custAnswer->answer_id,
74                    'created_at' => $custAnswer->created_at->isoFormat('YYYY-MM-DD'),
75                ];
76            })->groupBy(['created_at', 'answer_id'])->map(function ($day) {
77                return $day->map(function ($custAnswers) {
78                    return $custAnswers->count();
79                });
80            });
81
82        do {
83            $currentDate = $start->isoFormat('YYYY-MM-DD');
84            /** @var \Illuminate\Support\Collection $answersByDays */
85            if (!$answersByDays->has($currentDate)) {
86                $answersByDays->put(
87                    $currentDate,
88                    $answers->mapWithKeys(function ($answer) {
89                        return [$answer->id => 0];
90                    })
91                );
92            } else {
93                $curentAnswers = $answersByDays->pull($currentDate);
94                $answersByDays->put(
95                    $currentDate,
96                    $answers->mapWithKeys(function ($answer) use ($curentAnswers) {
97                        return [$answer->id =>
98                        $curentAnswers->has($answer->id) ?
99                            $curentAnswers->get($answer->id) : 0];
100                    })
101                );
102            }
103
104            $start = $start->addDay();
105        } while ($start->lessThanOrEqualTo($end));
106
107        return $answersByDays;
108    }
109}