use App\Enums\Role;
use App\Models\Project;
use App\Models\TimeInterval;
use App\Models\User;
use Cache;
use Illuminate\Contracts\Database\Query\Builder;
class TimeIntervalPolicy
{
public function before(User $user): ?bool
{
return $user->isAdmin() ?: null;
}
public function viewAny(): bool
{
return true;
}
public function view(User $user, TimeInterval $timeInterval): bool
{
return $timeInterval->user_id === $user->id || $user->can('view', $timeInterval->task);
}
public function create(User $user, int $userId, int $taskId, bool $isManual): bool
{
$projectId = self::getProjectIdByTaskId($taskId);
if ($isManual) {
if ((bool)$user->manual_time === false) {
return false;
}
if ($user->id !== $userId) {
return $user->hasRole(Role::MANAGER) || $user->hasProjectRole(Role::MANAGER, $projectId);
}
return (
$user->hasProjectRole([Role::USER, Role::MANAGER], $projectId)
|| $user->hasRole(Role::MANAGER)
);
}
return $user->hasProjectRole([Role::USER, Role::MANAGER], $projectId);
}
public function update(User $user, TimeInterval $timeInterval): bool
{
return $user->id === $timeInterval->user_id;
}
public function bulkUpdate(User $user, array $timeIntervalIds): bool
{
foreach ($timeIntervalIds as $id) {
if (!$user->can('update', TimeInterval::find($id))) {
return false;
}
}
return true;
}
public function destroy(User $user, TimeInterval $timeInterval): bool
{
return $user->id === $timeInterval->user_id;
}
public function bulkDestroy(User $user, array $timeIntervalIds): bool
{
foreach ($timeIntervalIds as $id) {
$can = $user->can('destroy', TimeInterval::find($id));
if (!$can) {
return false;
}
}
return true;
}
private static function getProjectIdByTaskId(int $taskId): int
{
return Cache::store('octane')->remember(
"project_of_task_$taskId",
config('cache.role_caching_ttl'),
static fn() => Project::whereHas(
'tasks',
static fn(Builder $query) => $query->where('id', '=', $taskId)
)->firstOrFail()->id
);
}
}