Files
go-no-go/app/Http/Controllers/SessionController.php
2026-02-03 11:12:41 +01:00

134 lines
3.8 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Http\Requests\Session\UpdateSessionRequest;
use App\Models\Session;
use App\Services\ScoringService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
final class SessionController extends Controller
{
/**
* Create a new session for the selected category.
*/
public function store(Request $request): RedirectResponse
{
$session = Session::create([
'user_id' => auth()->id(),
'category_id' => $request->input('category_id'),
'screening_id' => $request->input('screening_id'),
'status' => 'in_progress',
]);
return redirect()->route('sessions.show', $session);
}
/**
* Display the session questionnaire with category, question groups, questions, and existing answers.
*/
public function show(Session $session): Response
{
$session->load('category', 'user');
$questionGroups = $session->category
->questionGroups()
->with(['questions' => fn ($q) => $q->orderBy('sort_order')])
->orderBy('sort_order')
->get();
$answers = $session->answers()->get()->keyBy('question_id');
$scoringService = new ScoringService;
$score = $scoringService->calculateScore($session);
return Inertia::render('Session/Show', [
'session' => $session,
'questionGroups' => $questionGroups,
'answers' => $answers,
'score' => $score,
]);
}
/**
* Save session basic info, answers, and additional comments.
*/
public function update(UpdateSessionRequest $request, Session $session): RedirectResponse
{
$validated = $request->validated();
if (isset($validated['basic_info'])) {
$session->update(['basic_info' => $validated['basic_info']]);
}
if (isset($validated['answers'])) {
$this->saveAnswers($session, $validated['answers']);
}
if (isset($validated['additional_comments'])) {
$session->update(['additional_comments' => $validated['additional_comments']]);
}
if ($request->boolean('complete')) {
return $this->completeSession($session);
}
return back();
}
/**
* Save or update answers for the session using composite key upsert.
*/
private function saveAnswers(Session $session, array $answers): void
{
foreach ($answers as $questionId => $answer) {
$session->answers()->updateOrCreate(
['question_id' => (int) $questionId],
[
'value' => $answer['value'] ?? null,
'text_value' => $answer['text_value'] ?? null,
]
);
}
}
/**
* Complete the session by calculating final score and result.
*/
private function completeSession(Session $session): RedirectResponse
{
$scoringService = new ScoringService;
$score = $scoringService->calculateScore($session);
$result = $scoringService->determineResult($score);
$session->update([
'score' => $score,
'result' => $result,
'status' => 'completed',
'completed_at' => now(),
]);
return redirect()->route('sessions.result', $session);
}
/**
* Display the final session result.
*/
public function result(Session $session): Response
{
$session->load('category');
return Inertia::render('Session/Result', [
'session' => $session,
'score' => $session->score,
'result' => $session->result,
'categoryName' => $session->category->name,
]);
}
}