95 lines
2.3 KiB
PHP
95 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Client;
|
|
use App\Models\User;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
class UserHierarchyService
|
|
{
|
|
public function visibleUserIds(User $user): array
|
|
{
|
|
if ($user->hasRole('Admin')) {
|
|
return User::query()->pluck('id')->all();
|
|
}
|
|
|
|
$visibleIds = [$user->id];
|
|
$frontier = [$user->id];
|
|
|
|
while ($frontier !== []) {
|
|
$directReportIds = User::query()
|
|
->whereIn('manager_id', $frontier)
|
|
->pluck('id')
|
|
->all();
|
|
|
|
$directReportIds = array_values(array_diff($directReportIds, $visibleIds));
|
|
|
|
if ($directReportIds === []) {
|
|
break;
|
|
}
|
|
|
|
$visibleIds = array_merge($visibleIds, $directReportIds);
|
|
$frontier = $directReportIds;
|
|
}
|
|
|
|
return $visibleIds;
|
|
}
|
|
|
|
public function scopeClientsVisibleTo(Builder $query, User $user): Builder
|
|
{
|
|
if ($user->hasRole('Admin')) {
|
|
return $query;
|
|
}
|
|
|
|
$visibleUserIds = $this->visibleUserIds($user);
|
|
|
|
return $query->whereHas('assignations', function (Builder $query) use ($visibleUserIds) {
|
|
$query->whereIn('user_id', $visibleUserIds);
|
|
});
|
|
}
|
|
|
|
public function canViewClient(User $user, Client $client): bool
|
|
{
|
|
if ($user->hasRole('Admin')) {
|
|
return true;
|
|
}
|
|
|
|
return $client->assignations()
|
|
->whereIn('user_id', $this->visibleUserIds($user))
|
|
->exists();
|
|
}
|
|
|
|
public function wouldCreateCycle(User $user, ?int $managerId): bool
|
|
{
|
|
if ($managerId === null) {
|
|
return false;
|
|
}
|
|
|
|
if ($user->id === $managerId) {
|
|
return true;
|
|
}
|
|
|
|
$frontier = [$user->id];
|
|
$checkedIds = [$user->id];
|
|
|
|
while ($frontier !== []) {
|
|
$directReportIds = User::query()
|
|
->whereIn('manager_id', $frontier)
|
|
->pluck('id')
|
|
->all();
|
|
|
|
$directReportIds = array_values(array_diff($directReportIds, $checkedIds));
|
|
|
|
if (in_array($managerId, $directReportIds, true)) {
|
|
return true;
|
|
}
|
|
|
|
$checkedIds = array_merge($checkedIds, $directReportIds);
|
|
$frontier = $directReportIds;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|