'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'); } }