File: /www/wwwroot/erp.nhatnamsst.com/domains/Admin/Models/Admin.php
<?php
namespace Domains\Admin\Models;
use Domains\Admin\Observers\AdminObserver;
use Domains\Admin\Supports\Authorization\AccessRoute;
use Domains\Brand\Models\Brand;
use Domains\Core\Enums\AdminRole;
use Domains\Core\Enums\Gender;
use Domains\Core\Traits\ModelTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
use Illuminate\Database\Eloquent\Casts\Attribute;
#[ObservedBy([AdminObserver::class])]
class Admin extends Authenticatable
{
use HasFactory, Notifiable, AccessRoute, ModelTrait;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'code',
'username',
'fullname',
'phone',
'email',
'birthday',
'gender',
'avatar',
'status',
'birthday',
'is_superadmin',
'role',
'password',
'access_route_names',
'team_id',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'is_superadmin' => 'boolean',
'email_verified_at' => 'datetime',
'password' => 'hashed',
'access_route_names' => AsArrayObject::class,
'gender' => Gender::class,
'role' => AdminRole::class
];
}
protected function fullname(): Attribute
{
return Attribute::make(
get: fn (mixed $value, array $attributes) => $attributes['fullname'] ?: $attributes['username'] ?: $attributes['email']
);
}
protected function avatar(): Attribute
{
return Attribute::make(
get: fn (string|null $value = null) => asset($value ?: config('core.images.avatar'))
);
}
public function getRoleNames()
{
if($this->checkIsSuperAdmin())
{
return trans('Super Admin');
}
if($this->role) {
return $this->role->description();
}
return '';
}
public function isSaleOrLeaderSale(): bool
{
if (!$this->role) {
return false;
}
return $this->role === AdminRole::SALE || $this->role === AdminRole::LEADER_SALE;
}
public function isAdmin(): bool
{
if (!$this->role) {
return false;
}
return $this->role === AdminRole::ADMIN || $this->checkIsSuperAdmin();
}
public function isInterOrLeaderInter(): bool
{
if (!$this->role) {
return false;
}
return $this->role === AdminRole::INTER || $this->role === AdminRole::LEADER_INTER;
}
public function isLeaderOrAbove(): bool
{
if ($this->checkIsSuperAdmin()) {
return true;
}
if (!$this->role) {
return false;
}
return in_array($this->role, [
AdminRole::ADMIN,
AdminRole::LEADER_SALE,
AdminRole::LEADER_INTER
]);
}
public function brands(): BelongsToMany
{
return $this->belongsToMany(Brand::class, 'brand_admin', 'admin_id', 'brand_id')
->withTimestamps();
}
/**
* Get the team this admin belongs to (as a member)
*/
public function team(): BelongsTo
{
return $this->belongsTo(Team::class);
}
/**
* Get the team this admin leads (as a leader)
*/
public function ledTeam(): HasOne
{
return $this->hasOne(Team::class, 'leader_id');
}
/**
* Get team members (if this admin is a leader)
*/
public function getTeamMembers()
{
$team = $this->ledTeam;
if ($team) {
return $team->members;
}
return collect();
}
/**
* Get all team member IDs (including self if leader)
*/
public function getTeamMemberIds(): array
{
if ($this->role === AdminRole::LEADER_SALE || $this->role === AdminRole::LEADER_INTER) {
// Load relationship if not already loaded
if (!$this->relationLoaded('ledTeam')) {
$this->load('ledTeam.members');
}
$team = $this->ledTeam;
if ($team) {
return $team->getMemberIds();
}
}
return [$this->id];
}
/**
* Check if admin is a team leader
*/
public function isTeamLeader(): bool
{
return in_array($this->role, [AdminRole::LEADER_SALE, AdminRole::LEADER_INTER]);
}
/**
* Check if admin belongs to a team
*/
public function belongsToTeam(): bool
{
return !is_null($this->team_id);
}
public function checkRouteNameAccess(string $route_name): bool
{
if(in_array($route_name, config('cms.roles_permissions.whitelist_routes_name', [])))
{
return true;
}
if(in_array($route_name, $this->getRouteNamesAccess()))
{
return true;
}
$routeRoleAccess = config('cms.route_role_access', []);
if (isset($routeRoleAccess[$route_name]) && $this->role) {
$allowedRoles = $routeRoleAccess[$route_name];
if (in_array($this->role, $allowedRoles)) {
return true;
}
}
return false;
}
public function getRouteNamesAccess(): array
{
$routes = [];
if($this->access_route_names?->count())
{
$routes = array_merge($routes, $this->access_route_names->toArray());
}
if ($this->role) {
$routeRoleAccess = config('cms.route_role_access', []);
foreach ($routeRoleAccess as $routeName => $allowedRoles) {
if (in_array($this->role, $allowedRoles)) {
$routes[] = $routeName;
}
}
}
return array_unique($routes);
}
}