osb/app/Models/User.php

288 lines
5.5 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Log;
use Laravel\Passport\HasApiTokens;
use Leenooks\Traits\ScopeActive;
use Leenooks\Traits\UserSwitch;
use App\Interfaces\IDs;
use App\Notifications\ResetPassword as ResetPasswordNotification;
use App\Traits\SiteID;
/**
* Class User
*
* Attributes for users:
* + role : User's role
*/
class User extends Authenticatable implements IDs
{
use HasFactory,HasApiTokens,Notifiable,UserSwitch,ScopeActive,SiteID;
private const CACHE_TIME = 3600;
protected $casts = [
'last_access' => 'datetime:Y-m-d H:i:s',
'passkey' => 'json',
];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Role hierarchy order
*
* @var array
*/
public const role_order = [
'wholesaler',
'reseller',
'customer',
];
/* OVERRIDES */
/**
* Users password reset email notification
*
* @param string $token
*/
public function sendPasswordResetNotification($token)
{
$this->notify((new ResetPasswordNotification($token))
->onQueue('user'));
}
/* INTERFACES */
public function getLIDAttribute(): string
{
return sprintf('#%04s',$this->id);
}
public function getSIDAttribute(): string
{
return sprintf('%02s-%s',$this->site_id,$this->getLIDAttribute());
}
/* RELATIONS */
/**
* This user's accounts
*/
public function accounts()
{
return $this->hasMany(Account::class)
->active();
}
/**
* The accounts that this user manages
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
* @note This cannot be preloaded with load() or with() - $this is a blank object
*/
public function accounts_all()
{
return $this->hasMany(Account::class)
->when((! is_null($this->rtm) && $this->id),
fn($query)=>$query->orWhereIn('rtm_id',$this->rtm?->children_all()->pluck('id')))
->active();
}
/**
* This users language configuration
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function language()
{
return $this->belongsTo(Language::class);
}
/**
* Return the routes to market account for this user
*/
public function rtm()
{
return $this->hasOneThrough(Rtm::class,Account::class);
}
/* ATTRIBUTES */
/**
* Logged in user's full name
*
* @return string
* @deprecated use getNameFullAttribute()
*/
public function getFullNameAttribute(): string
{
Log::alert('UMO:! Deprecated function getFullNameAttribute()');
return $this->getNameFullAttribute();
}
/**
* This is an alias method, as it is used by the framework
*
* @return string
*/
public function getNameAttribute(): string
{
return $this->name_full;
}
/**
* Logged in user's full name
*
* @return string
*/
public function getNameFullAttribute(): string
{
return sprintf('%s %s',$this->firstname,$this->lastname);
}
/**
* Return the name, surname first
*
* @return string
*/
public function getNameSurFirstAttribute()
{
return sprintf('%s, %s',$this->lastname,$this->firstname);
}
/**
* Return a friendly string of this persons role
*
* @return string
*/
public function getRoleAttribute(): string
{
return ucfirst($this->role());
}
/**
* Return the name, surname first
* @return string
* @deprecated use getNameSurFirstAttribute()
*/
public function getSurFirstNameAttribute()
{
Log::alert('UMO:! Deprecated function getSurFirstNameAttribute()');
return $this->getNameSurFirstAttribute();
}
/* SCOPES */
/**
* Search for a record
*
* @param $query
* @param string $term
*/
public function scopeSearch($query,string $term)
{
// Build our where clause
// First Name, Last name
if (preg_match('/\s+/',$term)) {
[$fn,$ln] = explode(' ',$term,2);
$query->where(function($query1) use ($fn,$ln,$term) {
$query1->where(function($query2) use ($fn,$ln) {
return $query2
->where('firstname','ilike','%'.$fn.'%')
->where('lastname','ilike','%'.$ln.'%');
});
});
} elseif (is_numeric($term)) {
$query->where('users.id','like','%'.$term.'%');
} elseif (preg_match('/@/',$term)) {
$query->where('email','ilike','%'.$term.'%');
} else {
$query
->Where('firstname','ilike','%'.$term.'%')
->orWhere('lastname','ilike','%'.$term.'%');
}
return $query;
}
/* METHODS */
/**
* Determine if the user is an admin of the user with $id
*
* @param User|null $user
* @return bool
*/
public function isAdmin(User $user=NULL): bool
{
return $user->exists
&& $this->isReseller()
&& $this->accounts_all
->pluck('user_id')
->contains($user->id);
}
/**
* Determine if the logged in user is a reseller or wholesaler
*
* @return bool
*/
public function isReseller(): bool
{
return in_array($this->role(),['wholesaler','reseller']);
}
/**
* Determine if the logged in user is a wholesaler
*
* @return bool
*/
public function isWholesaler(): bool
{
return in_array($this->role(),['wholesaler']);
}
/**
* Determine what the logged in user's role is
* + Wholesaler - aka Super User
* + Reseller - services accounts on behalf of their customers
* + Customer - end user customer
*
* @return string
*/
public function role()
{
return $this->rtm
? ($this->rtm->parent_id ? 'reseller' : 'wholesaler')
: 'customer';
}
}