post()) { $stats = BrandStat::whereDate('created_at', '>=', $request->start) ->whereDate('created_at', '<=', $request->end) ->whereBrandId($request->brand)->get(); } return view('stats.view-stats-by-brands', \compact('stats')); } /** * Exports stats by brand as a csv file * * @param StatsByBrandRequest $request * @return \Illuminate\Http\Response */ public function exportByBrandCsv(StatsByBrandRequest $request) { $brand = Brand::findOrFail($request->brand); $stats = BrandStat::with('brand')->whereDate('created_at', '>=', $request->start) ->whereDate('created_at', '<=', $request->end) ->whereBrandId($request->brand)->get(); $columns = collect(Schema::getColumnListing((new BrandStat())->getTable())) ->filter(function ($value) { return !in_array($value, ['created_at', 'brand_id']); })->all(); $header = '"date";"marque";' . implode(';', $columns); $w = Writer::createFromString($header . PHP_EOL); $w->setDelimiter(';'); $w->setEnclosure('"'); $w->setOutputBOM(Writer::BOM_UTF8); foreach ($stats as $stat) { $cols = [ $stat->created_at->format('Y-m-d'), $stat->brand->name ]; foreach ($columns as $colname) { $cols[] = $stat->{$colname}; } $w->insertOne($cols); } return response((string)$w, 200, [ 'Content-Encoding' => 'none', 'Content-Type' => 'text/csv; charset=UTF-8', // phpcs:ignore Generic.Files.LineLength.TooLong 'Content-Disposition' => "attachment; filename=\"Statistiques du $request->start au $request->end pour $brand->name.csv\"", 'Content-Description' => 'File Transfer', ]); } /** * Views stats for a specific question * * @param StatsByQuestionRequest $request * @return \Illuminate\Http\Response */ public function viewByQuestion(StatsByQuestionRequest $request) { $question = null; $answers = null; $answersByDays = null; if ($request->post()) { $question = Question::findOrFail($request->question); $answers = $question->answers; $start = Carbon::parse($request->start); $end = Carbon::parse($request->end); $answersByDays = $this->answersByDays($answers, $start, $end); } return view('stats.view-stats-by-questions', \compact('question', 'answers', 'answersByDays')); } /** * Exports stats for a specific question as csv * * @param StatsByQuestionRequest $request * @return \Illuminate\Http\Response */ public function exportByQuestionCsv(StatsByQuestionRequest $request) { $question = Question::findOrFail($request->question); $answers = $question->answers; $start = Carbon::parse($request->start); $end = Carbon::parse($request->end); $answersByDays = $this->answersByDays($answers, $start, $end); $header = '"date";' . implode(';', $answers->map(function ($answer) { return "\"$answer->answer\""; })->all()); $w = Writer::createFromString($header . PHP_EOL); $w->setDelimiter(';'); $w->setEnclosure('"'); $w->setOutputBOM(Writer::BOM_UTF8); foreach ($answersByDays as $day => $dayAnswers) { $w->insertOne(array_merge( [ $day ], $dayAnswers->values()->all() )); } return response((string)$w, 200, [ 'Content-Encoding' => 'none', 'Content-Type' => 'text/csv; charset=UTF-8', // phpcs:ignore Generic.Files.LineLength.TooLong 'Content-Disposition' => "attachment; filename=\"Statistiques du $request->start au $request->end pour $question->question.csv\"", 'Content-Description' => 'File Transfer', ]); } /** * Makes a collection of total users answers by day * * @param Collection $answers A collection of Answer. * @param Carbon $start The wanted start period. * @param Carbon $end The wanted end period. * @return Collection A collection with date as Y_m_d index with array of answers and their total. */ private function answersByDays(Collection $answers, Carbon $start, Carbon $end): Collection { // * Totalize by date all answers. $answersByDays = CustomerAnswer::whereDate('created_at', '>=', $start) ->whereDate('created_at', '<=', $end) ->whereIn('answer_id', $answers->pluck('id')) ->get()->map(function ($custAnswer) { return [ 'answer_id' => $custAnswer->answer_id, 'created_at' => $custAnswer->created_at->format('Y-m-d'), ]; })->groupBy(['created_at', 'answer_id'])->map(function ($day) { return $day->map(function ($custAnswers) { return $custAnswers->count(); }); }); do { $currentDate = $start->format('Y-m-d'); /** @var \Illuminate\Support\Collection $answersByDays */ if (!$answersByDays->has($currentDate)) { $answersByDays->put( $currentDate, $answers->mapWithKeys(function ($answer) { return [$answer->answer => 0]; }) ); } else { $curentAnswers = $answersByDays->pull($currentDate); $answersByDays->put( $currentDate, $answers->mapWithKeys(function ($answer) use ($curentAnswers) { return [$answer->answer => $curentAnswers->has($answer->id) ? $curentAnswers->get($answer->id) : 0]; }) ); } $start = $start->addDay(); } while ($start->lessThanOrEqualTo($end)); return $answersByDays; } }