ldc-portsalaries/app/Models/Employee.php
2021-11-26 12:42:02 +01:00

315 lines
9.6 KiB
PHP

<?php
namespace App\Models;
use App\Jobs\SendEmployeeCreatedAccountMail;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection as SupportCollection;
use Illuminate\Support\Str;
use Kwaadpepper\CrudPolicies\Enums\CrudAction;
use Kwaadpepper\CrudPolicies\Enums\CrudType;
use Kwaadpepper\CrudPolicies\Traits\IsCrudModel;
class Employee extends Authenticatable
{
use HasFactory;
use IsCrudModel;
protected $crudLabelColumn = 'email';
protected $crudValueColumn = 'id';
protected $fillable = [
'matricule',
'firstname',
'lastname',
'email',
'site_id'
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'password_date' => 'datetime',
];
protected $attributes = [
'password_attempts' => 0
];
public function __construct($attributes = [])
{
self::$editableProperties = [
'matricule' => [
'label' => trans('Matricule'),
'type' => CrudType::string(),
'readonly' => true,
'validate' => [
'digits_between:7,8',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
$q = Employee::query();
if ($this->id) {
$q = $q->where('id', '!=', $this->id);
}
if ($q->where('matricule', $value)->exists()) {
$fail(__(':attribute est déjà utilisé', [
'attribute' => $attribute
]));
}
}
],
'actions' => [
CrudAction::viewAny(),
CrudAction::view(),
CrudAction::create(),
CrudAction::update()
]
],
'firstname' => [
'label' => trans('Prénom'),
'type' => CrudType::string(),
'validate' => [
'string',
'max:60'
],
'actions' => [
CrudAction::view(),
CrudAction::create(),
CrudAction::update(),
]
],
'lastname' => [
'label' => trans('Nom'),
'type' => CrudType::string(),
'nullable' => false,
'validate' => [
'string',
'max:60'
],
'actions' => [
CrudAction::viewAny(),
CrudAction::view(),
CrudAction::create(),
CrudAction::update(),
]
],
'email' => [
'label' => trans('Email'),
'type' => CrudType::email(),
'nullable' => false,
'validate' => [
'max:150',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
$q = Employee::query();
if ($this->id) {
$q = $q->where('id', '!=', $this->id);
}
if ($q->where('email', $value)->exists()) {
$fail(__(':attribute est déjà utilisé', [
'attribute' => $attribute
]));
}
}
],
'actions' => [
CrudAction::viewAny(),
CrudAction::view(),
CrudAction::create(),
CrudAction::update(),
]
],
'password' => [
'label' => trans('Mot de passe'),
'placeholder' => '#M1s3Cure.P4ss0rd!',
'type' => CrudType::password(),
'nullable' => true,
'validate' => [
'max:150'
],
'actions' => [
CrudAction::create(),
CrudAction::delete()
]
],
'site_id' => [
'label' => trans('Site'),
'type' => CrudType::belongsTo(),
'belongsTo' => Site::class,
'actions' => [
CrudAction::create(),
CrudAction::update()
]
],
'blocked' => [
'label' => trans('Verrouillé'),
'type' => CrudType::boolean(),
'actions' => [
CrudAction::viewAny(),
CrudAction::view(),
CrudAction::update(),
],
'getAttribute' => function (Employee $model) {
return $model->getAttribute('password_attempts') >= 3;
},
'setAttribute' => function (Employee $model, $value) {
$model->setAttribute('password_attempts', $value ? 3 : 0);
return $model->getAttribute('password_attempts');
},
]
];
parent::__construct($attributes);
}
protected static function booted()
{
static::creating(function ($employee) {
if (!strlen($employee->password)) {
$employee->password = Str::random(13);
}
$employee->password = Hash::make($employee->password);
$employee->password_date = Carbon::now()->subDay();
});
static::updating(function ($employee) {
if (Hash::needsRehash($employee->password)) {
$employee->password = Hash::make($employee->password);
}
});
}
// RELATIONS
/**
* Has one Site
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function site()
{
return $this->belongsTo(Site::class);
}
/**
* Has many Planning
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function plannings()
{
return $this->hasMany(Planning::class);
}
/**
* Has one EmployeeMailToken
*
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function token()
{
return $this->hasOne(EmployeeMailToken::class);
}
/**
* BelongsToMany
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function reponseSondages()
{
return $this->belongsToMany(ReponseSondage::class)->withTimestamps();
}
// METHODS
/**
* Has the user answered to a specific sondage ?
* @param Sondage $sondage
* @return bool
*/
public function hasAnweredToSondage(Sondage $sondage): bool
{
$responsesIDS = $sondage->reponseSondages()->pluck(sprintf('%s.id', (new ReponseSondage())->getTable()));
return (bool)$this->reponseSondages()->wherePivotIn('reponse_sondage_id', $responsesIDS)->count();
}
/**
* Get Employee site flashes
*
* @return Collection
*/
public function getFlashes(): Collection
{
return $this->site->flashes()
->orderBy('created_at', 'DESC')
->get();
}
/**
* Get Employee unanswered Sondages
*
* @return Collection
*/
public function unAnsweredSondages(): Collection
{
$siteId = $this->site_id;
$sondagesIDS = $this->reponseSondages()->with('sondage')->get()->pluck('sondage.id');
return Sondage::whereHas('site', function ($q) use ($siteId) {
$q->whereId($siteId);
})->whereNotIn('id', $sondagesIDS)
->orderBy('created_at', 'DESC')
->get();
}
/**
* Prevent Infinite loop on mail send to Employee
* {@inheritdoc}
* @url https://stackoverflow.com/questions/52514863/laravel-getqueueablerelations-circular-relation
*/
public function getQueueableRelations()
{
return [];
}
/**
* Get Plannings for the current week + next week
*
* @return \Illuminate\Support\Collection
*/
public function getWeekAndNextPlannings(): SupportCollection
{
$now = Carbon::now()->format('Y/m/d');
$nowPlus7 = Carbon::now()->addDays(7)->format('Y/m/d');
return collect([
'now' => Planning::whereDate('start', '<=', $now)
->whereDate('end', '>=', $now)
->where('employee_id', $this->id)
->first(),
'next' => Planning::whereDate('start', '<=', $nowPlus7)
->whereDate('end', '>=', $nowPlus7)
->where('employee_id', $this->id)
->first()
]);
}
public function sendMailConfirm()
{
if ($this->hashcode) {
$this->hashcode->delete();
}
$this->hashcode = new EmployeeMailToken([
'email' => $this->email,
'employee_id' => $this->id
]);
$this->hashcode->saveOrFail();
dispatch(new SendEmployeeCreatedAccountMail($this))
->onConnection('database');
}
}