CRM/backend/app/Support/AccessControl.php

208 خطوط
6.2 KiB
PHP

<?php
namespace App\Support;
use App\Models\Campaign;
use App\Models\Call;
use App\Models\FollowUp;
use App\Models\Lead;
use App\Models\Team;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
class AccessControl
{
public static function canAccessLead(User $user, Lead $lead, bool $allowUnassignedClaim = false): bool
{
if ($user->hasRole('admin')) {
return true;
}
if ($user->hasRole('agent')) {
return $lead->assigned_to === $user->id
|| ($allowUnassignedClaim && is_null($lead->assigned_to) && (bool) $lead->is_unassigned);
}
if ($user->hasRole('supervisor')) {
return $lead->assigned_to === $user->id
|| in_array($lead->team_id, self::teamIds($user), true)
|| (is_null($lead->team_id) && is_null($lead->assigned_to));
}
return false;
}
public static function canAccessCall(User $user, Call $call): bool
{
if ($user->hasRole('admin')) {
return true;
}
if ($user->hasRole('agent')) {
return $call->user_id === $user->id;
}
if ($user->hasRole('supervisor')) {
return in_array($call->user_id, self::teamMemberIds($user), true)
|| ($call->lead && self::canAccessLead($user, $call->lead));
}
return false;
}
public static function canAccessFollowUp(User $user, FollowUp $followUp): bool
{
if ($user->hasRole('admin')) {
return true;
}
if ($user->hasRole('agent')) {
return $followUp->user_id === $user->id;
}
if ($user->hasRole('supervisor')) {
return in_array($followUp->user_id, self::teamMemberIds($user), true)
|| ($followUp->lead && self::canAccessLead($user, $followUp->lead));
}
return false;
}
public static function canAccessCampaign(User $user, Campaign $campaign): bool
{
if ($user->hasRole('admin')) {
return true;
}
if ($user->hasRole('agent')) {
return $campaign->assignedAgents()->whereKey($user->id)->exists()
|| $campaign->leads()->where('assigned_to', $user->id)->exists();
}
if ($user->hasRole('supervisor')) {
$teamIds = self::teamIds($user);
return $campaign->assignedSupervisors()->whereKey($user->id)->exists()
|| $campaign->leads()->whereIn('team_id', $teamIds)->exists();
}
return false;
}
public static function scopeLeads(Builder $query, User $user, bool $allowUnassignedForSupervisor = true): Builder
{
if ($user->hasRole('admin')) {
return $query;
}
if ($user->hasRole('agent')) {
return $query->where('assigned_to', $user->id);
}
if ($user->hasRole('supervisor')) {
$teamIds = self::teamIds($user);
return $query->where(function (Builder $q) use ($user, $teamIds, $allowUnassignedForSupervisor): void {
$q->whereIn('team_id', $teamIds)
->orWhere('assigned_to', $user->id);
if ($allowUnassignedForSupervisor) {
$q->orWhere(function (Builder $unassigned): void {
$unassigned->whereNull('team_id')->whereNull('assigned_to');
});
}
});
}
return $query->whereRaw('1 = 0');
}
public static function scopeCalls(Builder $query, User $user): Builder
{
if ($user->hasRole('admin')) {
return $query;
}
if ($user->hasRole('agent')) {
return $query->where('user_id', $user->id);
}
if ($user->hasRole('supervisor')) {
return $query->where(function (Builder $q) use ($user): void {
$q->whereIn('user_id', self::teamMemberIds($user))
->orWhereHas('lead', fn(Builder $leadQuery) => self::scopeLeads($leadQuery, $user));
});
}
return $query->whereRaw('1 = 0');
}
public static function scopeFollowUps(Builder $query, User $user): Builder
{
if ($user->hasRole('admin')) {
return $query;
}
if ($user->hasRole('agent')) {
return $query->where('user_id', $user->id);
}
if ($user->hasRole('supervisor')) {
return $query->where(function (Builder $q) use ($user): void {
$q->whereIn('user_id', self::teamMemberIds($user))
->orWhereHas('lead', fn(Builder $leadQuery) => self::scopeLeads($leadQuery, $user));
});
}
return $query->whereRaw('1 = 0');
}
public static function scopeCampaigns(Builder $query, User $user): Builder
{
if ($user->hasRole('admin')) {
return $query;
}
if ($user->hasRole('agent')) {
return $query->where(function (Builder $q) use ($user): void {
$q->whereHas('assignedAgents', fn(Builder $agentQuery) => $agentQuery->whereKey($user->id))
->orWhereHas('leads', fn(Builder $leadQuery) => $leadQuery->where('assigned_to', $user->id));
});
}
if ($user->hasRole('supervisor')) {
$teamIds = self::teamIds($user);
return $query->where(function (Builder $q) use ($user, $teamIds): void {
$q->whereHas('assignedSupervisors', fn(Builder $supervisorQuery) => $supervisorQuery->whereKey($user->id))
->orWhereHas('leads', fn(Builder $leadQuery) => $leadQuery->whereIn('team_id', $teamIds));
});
}
return $query->whereRaw('1 = 0');
}
public static function teamIds(User $user): array
{
return $user->teams()->pluck('teams.id')->all();
}
public static function teamMemberIds(User $user): array
{
$teamIds = self::teamIds($user);
if (!$teamIds) {
return [];
}
return Team::whereIn('id', $teamIds)
->with('members:id')
->get()
->pluck('members.*.id')
->flatten()
->unique()
->values()
->all();
}
}