refactor: simplify status transition logic in Internship

This commit is contained in:
2025-11-29 14:34:05 +01:00
parent e309d8ea5d
commit fcb6cc13fa
2 changed files with 55 additions and 35 deletions

View File

@@ -44,9 +44,7 @@ class InternshipStatusDataController extends Controller
abort(403, 'Unauthorized');
}
$currentStatus = $internship->status;
$nextPossibleStatuses = $this->possibleNewStatuses($currentStatus->status, $user->role, $internship->report_confirmed);
$nextPossibleStatuses = $internship->nextStates($user->role);
return response()->json($nextPossibleStatuses);
}
@@ -109,7 +107,7 @@ class InternshipStatusDataController extends Controller
}
$internshipStatus = $internship->status;
$newStatusValidator = 'in:' . implode(',', $this->possibleNewStatuses($internshipStatus->status, $user->role, $internship->report_confirmed));
$newStatusValidator = 'in:' . implode(',', $internship->nextStates($user->role));
$request->validate([
'status' => ['required', 'string', 'uppercase', $newStatusValidator],
@@ -136,35 +134,4 @@ class InternshipStatusDataController extends Controller
{
//
}
private function possibleNewStatuses(string $current_status, string $userRole, bool $report_confirmed)
{
if ($userRole === "STUDENT")
return [];
switch ($current_status) {
case 'SUBMITTED':
return ['CONFIRMED', 'DENIED'];
case 'CONFIRMED':
if ($userRole === 'EMPLOYER') {
return ['DENIED'];
}
if ($report_confirmed) {
return ['SUBMITTED', 'DENIED', 'DEFENDED', 'NOT_DEFENDED'];
}
return ['SUBMITTED', 'DENIED'];
case 'DENIED':
if ($userRole === 'EMPLOYER') {
return ['CONFIRMED'];
}
return ['SUBMITTED', 'CONFIRMED'];
case 'DEFENDED':
case 'NOT_DEFENDED':
return [];
default:
throw new \InvalidArgumentException('Unknown status');
}
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Models;
use App\Enums\InternshipStatus;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
@@ -66,6 +67,58 @@ class Internship extends Model
return $this->hasOne(InternshipStatusData::class, 'internship_id')->latestOfMany();
}
public function nextStates(string $userRole)
{
$current_status = $this->status->status;
$report_confirmed = $this->report_confirmed;
// študent nemôže meniť stav
if ($userRole === 'STUDENT')
return [];
/*
nasledujúci platný stav je určený podľa:
- aktuálneho stavu
- roly používateľa, ktorý ide meniť stav
- či bol výkaz potvrdený firmou
*/
return match (true) {
// prax bola iba vytvorená a ide ju meniť admin alebo firma
$current_status === InternshipStatus::SUBMITTED
=> ['CONFIRMED_BY_COMPANY', 'DENIED_BY_COMPANY'],
// prax bola potvrdená firmou a ide ju meniť admin
$current_status === InternshipStatus::CONFIRMED_BY_COMPANY && $userRole === "ADMIN"
=> ['CONFIRMED_BY_ADMIN', 'DENIED_BY_ADMIN'],
// prax bola potvrdená firmou a ide ju meniť firma
$current_status === InternshipStatus::CONFIRMED_BY_COMPANY && $userRole === "EMPLOYER"
=> ['DENIED_BY_COMPANY'],
// prax bola zamietnutá firmou a ide ju meniť admin
$current_status === InternshipStatus::DENIED_BY_COMPANY && $userRole === "ADMIN"
=> ['CONFIRMED_BY_COMPANY', 'SUBMITTED'],
// prax bola potvrdená garantom, ide ju meniť admin a výkaz bol potvrdený firmou
$current_status === InternshipStatus::CONFIRMED_BY_ADMIN && $userRole === "ADMIN" && $report_confirmed
=> ['DENIED_BY_ADMIN', 'CONFIRMED_BY_COMPANY', 'DENIED_BY_COMPANY', 'DEFENDED', 'NOT_DEFENDED'],
// prax bola potvrdená garantom, ide ju meniť admin a výkaz nebol potvrdený firmou
$current_status === InternshipStatus::CONFIRMED_BY_ADMIN && $userRole === "ADMIN" && !$report_confirmed
=> ['DENIED_BY_ADMIN', 'CONFIRMED_BY_COMPANY', 'DENIED_BY_COMPANY'],
// prax bola obhájená a ide ju meniť admin
$current_status === InternshipStatus::DEFENDED && $userRole === "ADMIN"
=> ['NOT_DEFENDED'],
// prax nebola obhájená a ide ju meniť admin
$current_status === InternshipStatus::NOT_DEFENDED && $userRole === "ADMIN"
=> ['DEFENDED'],
default => []
};
}
/**
* Prepare the model for JSON serialization.
*