First developed project version
This commit is contained in:
parent
28e75bc2d7
commit
1af6018447
326 changed files with 53983 additions and 353 deletions
37
.env.example
37
.env.example
|
|
@ -10,7 +10,7 @@ LOG_LEVEL=debug
|
|||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=laravel
|
||||
DB_DATABASE=portsalaries
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
|
||||
|
|
@ -20,30 +20,13 @@ QUEUE_CONNECTION=sync
|
|||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
MEMCACHED_HOST=127.0.0.1
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=mailhog
|
||||
MAIL_PORT=1025
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS=null
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
MAIL_MAILER=
|
||||
MAIL_HOST=
|
||||
MAIL_PORT=
|
||||
MAIL_USERNAME=
|
||||
MAIL_PASSWORD=
|
||||
MAIL_ENCRYPTION=
|
||||
MAIL_FROM_ADDRESS="no-reply@portsalaries.test"
|
||||
MAIL_FROM_NAME="Ne pas répondre (Poartail Salariés)"
|
||||
MAIL_LIST_SERVICEWEB=informatique.internet@ldc.fr
|
||||
|
|
|
|||
8
.gitignore
vendored
8
.gitignore
vendored
|
|
@ -1,7 +1,13 @@
|
|||
/node_modules
|
||||
/public/hot
|
||||
/public/storage
|
||||
/public/js/*
|
||||
/public/css/*
|
||||
/public/fonts/*
|
||||
/public/uploads/*
|
||||
mix-manifest.json
|
||||
/storage/*.key
|
||||
/storage/framework/laravel-excel/*
|
||||
/vendor
|
||||
.env
|
||||
.env.backup
|
||||
|
|
@ -11,3 +17,5 @@ Homestead.json
|
|||
Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
workspace.code-workspace
|
||||
.vscode
|
||||
|
|
|
|||
9118
Planning_LTA001_wb0112062.xls
Normal file
9118
Planning_LTA001_wb0112062.xls
Normal file
File diff suppressed because it is too large
Load diff
49
PortailSalariés/resources/views/loginPassExpired.blade.php
Normal file
49
PortailSalariés/resources/views/loginPassExpired.blade.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
@extends("layouts.app")
|
||||
|
||||
@section('title')
|
||||
Mot de passe expiré | Portail Salariés
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<form method="post" action=" ">
|
||||
@csrf
|
||||
<img src="{{ asset('images/logo_LDC.jpg') }}" alt="Logo-LDC">
|
||||
<h1>Portail Salariés</h1>
|
||||
<h1 class="passExpired">Mot de passe expiré</h1>
|
||||
<div class="instructions">
|
||||
<h2>Votre mot de passe est expiré, vous devez le changez pour accéder à votre compte</h2>
|
||||
<p>Il doit respecter les conditions suivantes : </p>
|
||||
<ul>
|
||||
<li>Au moins une lettre majuscule</li>
|
||||
<li>Au moins une lettre minuscule</li>
|
||||
<li>Au moins 10 caractères</li>
|
||||
<li>Au plus 13 caractères</li>
|
||||
<li>Au moins un chiffre</li>
|
||||
<li>Au moins un symbole (% ! : ; # - _ = )</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<label for="password">Nouveau Mot de passe</label> <br>
|
||||
<input type="password" name="password" id="password" placeholder="Saisir votre nouveau mot de passe" >
|
||||
|
||||
<div class="changeMDPError active">
|
||||
<p class="changeMDPError_content">Mot de passe invalide</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<label for="confirmPassword">Confirmer mot de passe</label> <br>
|
||||
<input type="password" name="confirmPassword" id="confirmPassword" placeholder="Confirmer votre mot de passe">
|
||||
|
||||
<div class="changeMDPError active">
|
||||
<p class="changeMDPError_content">Mot de passe invalide</p>
|
||||
</div>
|
||||
|
||||
<div class="formLoginBottom ">
|
||||
<input type="submit" name="submit" value="Sauvegarder" id="centerBtn">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</form>
|
||||
@endsection
|
||||
22
PortailSalariés/resources/views/loginPassForgotten.blade.php
Normal file
22
PortailSalariés/resources/views/loginPassForgotten.blade.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
@extends("layouts.app")
|
||||
|
||||
@section('title')
|
||||
Mot de passe oublié | Portail Salariés
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<form method="post" action=" ">
|
||||
@csrf
|
||||
<img src="{{ asset('images/logo_LDC.jpg') }}" alt="Logo-LDC">
|
||||
<h1>Portail Salariés</h1>
|
||||
<h1 class="passExpired">Mot de passe Oublié?</h1>
|
||||
<div class="instructions">
|
||||
<p>Vous recevrez un lien à votre adresse mail pour réinitialiser votre mot de passe.</p>
|
||||
</div>
|
||||
<label for="login">Matricule</label> <br>
|
||||
<input type="text" name="login" id="login" placeholder="Saisir votre Matricule" > <br>
|
||||
<div class="formLoginBottom">
|
||||
<input type="submit" name="submit" value="Recevoir le lien" id="centerBtn">
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
47
app/Casts/HtmlColor.php
Normal file
47
app/Casts/HtmlColor.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
|
||||
/**
|
||||
* Custom cast Html Color
|
||||
* https://laravel.com/docs/8.x/eloquent-mutators#custom-casts
|
||||
*/
|
||||
//phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed
|
||||
//phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
|
||||
class HtmlColor implements CastsAttributes
|
||||
{
|
||||
/**
|
||||
* Cast the given value.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public function get($model, $key, $value, $attributes)
|
||||
{
|
||||
return "#" . $this->zeropad(dechex($value), 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the given value for storage.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param array $value
|
||||
* @param array $attributes
|
||||
* @return int
|
||||
*/
|
||||
public function set($model, $key, $value, $attributes)
|
||||
{
|
||||
return \intval(hexdec(ltrim($value, '#')));
|
||||
}
|
||||
|
||||
private function zeropad($num, $lim)
|
||||
{
|
||||
return (strlen($num) >= $lim) ? $num : $this->zeropad("0" . $num, $lim);
|
||||
}
|
||||
}
|
||||
23
app/Casts/NiceDate.php
Normal file
23
app/Casts/NiceDate.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
//phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed
|
||||
//phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
|
||||
class NiceDate implements CastsAttributes
|
||||
{
|
||||
public function get($model, $key, $value, $attributes)
|
||||
{
|
||||
$value = Carbon::parse($value);
|
||||
return $value->isToday() ?
|
||||
trans('Aujourd\'hui à :time', ['time' => $value->format('H:i')]) : $value->format('Y/m/d H:i');
|
||||
}
|
||||
|
||||
public function set($model, $key, $value, $attributes)
|
||||
{
|
||||
return Carbon::parse($value)->format('Y-m-d H:i:s');
|
||||
}
|
||||
}
|
||||
44
app/Console/Commands/UserChangePassword.php
Normal file
44
app/Console/Commands/UserChangePassword.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Changes the user password
|
||||
*/
|
||||
class UserChangePassword extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'user:password';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Changes a user password';
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$email = $this->ask('What is the email?');
|
||||
$user = User::where('email', $email)->first();
|
||||
|
||||
if (!$user) {
|
||||
$this->error(sprintf('User %s could not be found', $email));
|
||||
return -1;
|
||||
}
|
||||
|
||||
$user->password = $this->secret('What is the password?');
|
||||
$user->saveOrFail();
|
||||
|
||||
$this->info('User updated.');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
118
app/Console/Commands/UserCreate.php
Normal file
118
app/Console/Commands/UserCreate.php
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\Role;
|
||||
use App\Models\Site;
|
||||
use App\Models\User;
|
||||
use Exception;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
/**
|
||||
* Creates a new user
|
||||
*/
|
||||
class UserCreate extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'user:create';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a backend user';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$sitename = $this->ask('For which site would you like to create a user ?');
|
||||
$site = Site::where('name', 'LIKE', "%$sitename%")->first();
|
||||
if ($site) {
|
||||
if (!$this->confirm(sprintf('Would you like to use %s ? ', $site->name))) {
|
||||
$this->info('Command cancelled');
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
$this->error(sprintf('Site %s not found cancelled', $sitename));
|
||||
return 0;
|
||||
}
|
||||
$name = null;
|
||||
while (is_null($name)) {
|
||||
try {
|
||||
$tmp = $this->ask('What is user the name?');
|
||||
$validator = Validator::make(['nom' => $tmp], [
|
||||
'nom' => 'required|min:5,max:255'
|
||||
]);
|
||||
$validator->validate();
|
||||
$name = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid name %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$email = null;
|
||||
while (is_null($email)) {
|
||||
try {
|
||||
$tmp = $this->ask('What is the email?');
|
||||
$validator = Validator::make(['email' => $tmp], [
|
||||
'email' => 'required|email:rfc,dns'
|
||||
]);
|
||||
$validator->validate();
|
||||
$email = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid email %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$role = null;
|
||||
while (is_null($role)) {
|
||||
try {
|
||||
$num = $this->ask(sprintf(
|
||||
'What is the user role %s ?',
|
||||
implode(',', collect(Role::toArray())->map(function ($role) {
|
||||
return sprintf('(%s) %d', $role->label, $role->value);
|
||||
})->all())
|
||||
));
|
||||
if (!\is_numeric($num)) {
|
||||
$this->error('Please provide a valid role.');
|
||||
continue;
|
||||
}
|
||||
$role = Role::make(intval($num))->value;
|
||||
} catch (Exception $e) {
|
||||
$this->error('Please provide a valid role.');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$password = $this->secret('What is the password?');
|
||||
|
||||
$user = new User([
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'role' => $role,
|
||||
'password' => $password,
|
||||
'site_id' => $site->id
|
||||
]);
|
||||
$user->saveOrFail();
|
||||
|
||||
$this->info('User created.');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,18 +2,22 @@
|
|||
|
||||
namespace App\Console;
|
||||
|
||||
use App\Console\Commands\UserChangePassword;
|
||||
use App\Console\Commands\UserCreate;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
|
||||
/**
|
||||
* The Artisan commands provided by your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $commands = [
|
||||
//
|
||||
UserChangePassword::class,
|
||||
UserCreate::class
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -34,7 +38,7 @@ class Kernel extends ConsoleKernel
|
|||
*/
|
||||
protected function commands()
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
$this->load(__DIR__ . '/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
|
|
|
|||
49
app/Enums/CrudAction.php
Normal file
49
app/Enums/CrudAction.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnum;
|
||||
|
||||
/**
|
||||
*
|
||||
* https://laravel.com/docs/8.x/authorization
|
||||
* Controller Method Policy Method
|
||||
* index viewAny
|
||||
* show view
|
||||
* create create
|
||||
* store create
|
||||
* edit update
|
||||
* update update
|
||||
* destroy delete
|
||||
*
|
||||
* @method static self viewAny()
|
||||
* @method static self view()
|
||||
* @method static self create()
|
||||
* @method static self update()
|
||||
* @method static self delete()
|
||||
*/
|
||||
|
||||
class CrudAction extends BaseEnum
|
||||
{
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'viewAny' => 0,
|
||||
'view' => 1,
|
||||
'create' => 2,
|
||||
'update' => 3,
|
||||
'delete' => 4,
|
||||
];
|
||||
}
|
||||
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'viewAny' => trans('Liste'),
|
||||
'view' => trans('Voir'),
|
||||
'create' => trans('Créer'),
|
||||
'update' => trans('Éditer'),
|
||||
'delete' => trans('Supprimer'),
|
||||
];
|
||||
}
|
||||
}
|
||||
53
app/Enums/CrudType.php
Normal file
53
app/Enums/CrudType.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnum;
|
||||
|
||||
/**
|
||||
* @method static self boolean()
|
||||
* @method static self int()
|
||||
* @method static self string()
|
||||
* @method static self text()
|
||||
* @method static self email()
|
||||
* @method static self password()
|
||||
* @method static self float()
|
||||
* @method static self enum()
|
||||
* @method static self belongsTo()
|
||||
* @method static self belongsToMany()
|
||||
*/
|
||||
|
||||
class CrudType extends BaseEnum
|
||||
{
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'boolean' => 0,
|
||||
'int' => 1,
|
||||
'string' => 2,
|
||||
'text' => 3,
|
||||
'email' => 4,
|
||||
'password' => 5,
|
||||
'float' => 6,
|
||||
'enum' => 7,
|
||||
'belongsTo' => 8,
|
||||
'belongsToMany' => 9
|
||||
];
|
||||
}
|
||||
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'boolean' => trans('Booléen'),
|
||||
'int' => trans('Nombre'),
|
||||
'string' => trans('Chaîne de charactères simple'),
|
||||
'text' => trans('Texte'),
|
||||
'email' => trans('Chaîne de charactères email'),
|
||||
'password' => trans('Mot de passe'),
|
||||
'float' => trans('Nombre à virgule flotante'),
|
||||
'enum' => trans('Énumération'),
|
||||
'belongsTo' => trans('Clé étrangère'),
|
||||
'belongsToMany' => trans('Relation Belongs To Many')
|
||||
];
|
||||
}
|
||||
}
|
||||
29
app/Enums/Role.php
Normal file
29
app/Enums/Role.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnum;
|
||||
|
||||
/**
|
||||
* @method static self admin()
|
||||
* @method static self rh()
|
||||
*/
|
||||
|
||||
class Role extends BaseEnum
|
||||
{
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'admin' => 0,
|
||||
'rh' => 1
|
||||
];
|
||||
}
|
||||
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'admin' => trans('Administrateur'),
|
||||
'rh' => trans('Ressource humaines')
|
||||
];
|
||||
}
|
||||
}
|
||||
29
app/Enums/TypeSondage.php
Normal file
29
app/Enums/TypeSondage.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnum;
|
||||
|
||||
/**
|
||||
* @method static self radio()
|
||||
* @method static self checkbox()
|
||||
*/
|
||||
|
||||
class TypeSondage extends BaseEnum
|
||||
{
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'radio' => 0,
|
||||
'checkbox' => 1
|
||||
];
|
||||
}
|
||||
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'radio' => trans('Choix unique'),
|
||||
'checkbox' => trans('Choix multiples')
|
||||
];
|
||||
}
|
||||
}
|
||||
9
app/Exceptions/CrudException.php
Normal file
9
app/Exceptions/CrudException.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class CrudException extends Exception
|
||||
{
|
||||
}
|
||||
|
|
@ -3,10 +3,13 @@
|
|||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
|
|
@ -35,7 +38,27 @@ class Handler extends ExceptionHandler
|
|||
public function register()
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
//
|
||||
try {
|
||||
if (!config('app.debug')) {
|
||||
if ($this->shouldntReport($e)) {
|
||||
return false;
|
||||
}
|
||||
Mail::send([
|
||||
'html' => 'emails.exception',
|
||||
'text' => 'emails.exception-plain'
|
||||
], [
|
||||
'exception' => $e,
|
||||
'appName' => config('app.name')
|
||||
], function ($m) {
|
||||
$m->to(
|
||||
config('mail.contactsList.serviceweb'),
|
||||
sprintf('%s Exception Handler', config('app.name'))
|
||||
)->subject('Need help !, an error occured in your application, please check Logs ASAP');
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
39
app/Http/Controllers/Auth/ConfirmPasswordController.php
Normal file
39
app/Http/Controllers/Auth/ConfirmPasswordController.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\ConfirmsPasswords;
|
||||
|
||||
class ConfirmPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Confirm Password Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password confirmations and
|
||||
| uses a simple trait to include the behavior. You're free to explore
|
||||
| this trait and override any functions that require customization.
|
||||
|
|
||||
*/
|
||||
use ConfirmsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users when the intended url fails.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
}
|
||||
21
app/Http/Controllers/Auth/ForgotPasswordController.php
Normal file
21
app/Http/Controllers/Auth/ForgotPasswordController.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset emails and
|
||||
| includes a trait which assists in sending these notifications from
|
||||
| your application to your users. Feel free to explore this trait.
|
||||
|
|
||||
*/
|
||||
use SendsPasswordResetEmails;
|
||||
}
|
||||
39
app/Http/Controllers/Auth/LoginController.php
Normal file
39
app/Http/Controllers/Auth/LoginController.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Login Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles authenticating users for the application and
|
||||
| redirecting them to your home screen. The controller uses a trait
|
||||
| to conveniently provide its functionality to your applications.
|
||||
|
|
||||
*/
|
||||
use AuthenticatesUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest:web')->except('logout');
|
||||
}
|
||||
}
|
||||
72
app/Http/Controllers/Auth/RegisterController.php
Normal file
72
app/Http/Controllers/Auth/RegisterController.php
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles the registration of new users as well as their
|
||||
| validation and creation. By default this controller uses a trait to
|
||||
| provide this functionality without requiring any additional code.
|
||||
|
|
||||
*/
|
||||
use RegistersUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after registration.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest:web');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
*/
|
||||
protected function validator(array $data)
|
||||
{
|
||||
return Validator::make($data, [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \App\Models\User
|
||||
*/
|
||||
protected function create(array $data)
|
||||
{
|
||||
return User::create([
|
||||
'name' => $data['name'],
|
||||
'email' => $data['email'],
|
||||
'password' => Hash::make($data['password']),
|
||||
]);
|
||||
}
|
||||
}
|
||||
29
app/Http/Controllers/Auth/ResetPasswordController.php
Normal file
29
app/Http/Controllers/Auth/ResetPasswordController.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset requests
|
||||
| and uses a simple trait to include this behavior. You're free to
|
||||
| explore this trait and override any methods you wish to tweak.
|
||||
|
|
||||
*/
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users after resetting their password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
}
|
||||
41
app/Http/Controllers/Auth/VerificationController.php
Normal file
41
app/Http/Controllers/Auth/VerificationController.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\VerifiesEmails;
|
||||
|
||||
class VerificationController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Email Verification Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling email verification for any
|
||||
| user that recently registered with the application. Emails may also
|
||||
| be re-sent if the user didn't receive the original email message.
|
||||
|
|
||||
*/
|
||||
use VerifiesEmails;
|
||||
|
||||
/**
|
||||
* Where to redirect users after verification.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->middleware('signed')->only('verify');
|
||||
$this->middleware('throttle:6,1')->only('verify', 'resend');
|
||||
}
|
||||
}
|
||||
|
|
@ -2,12 +2,26 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
use AuthorizesRequests;
|
||||
use DispatchesJobs;
|
||||
use ValidatesRequests;
|
||||
|
||||
/**
|
||||
* Get authenticated Employee
|
||||
*
|
||||
* @return Employee
|
||||
*/
|
||||
protected function getEmployee(): Employee
|
||||
{
|
||||
return Auth::guard('employee')->user();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
199
app/Http/Controllers/CrudController.php
Normal file
199
app/Http/Controllers/CrudController.php
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Exceptions\CrudException;
|
||||
use App\Http\Requests\StoreCrudModel;
|
||||
use App\Http\Requests\UpdateCrudModel;
|
||||
use App\Http\Resources\CrudResource;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class CrudController extends Controller
|
||||
{
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Model */
|
||||
protected static $modelClass = null;
|
||||
|
||||
// Eloquent callbacks
|
||||
public function indexQuery(Builder $query): Builder
|
||||
{
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function storeModel(Model &$model)
|
||||
{
|
||||
}
|
||||
|
||||
public function updateModel(Model &$model)
|
||||
{
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// AUTH CONTROL TO ROOT POLICY
|
||||
$this->authorizeResource(static::$modelClass);
|
||||
|
||||
$modelClass = static::$modelClass;
|
||||
if (is_null($modelClass) or !class_exists($modelClass)) {
|
||||
throw new CrudException(sprintf(
|
||||
'%s needs the modelClass prop to be a class, %s %s given',
|
||||
__CLASS__,
|
||||
gettype($modelClass),
|
||||
$modelClass
|
||||
));
|
||||
}
|
||||
if (!is_subclass_of(new $modelClass(), Model::class)) {
|
||||
throw new CrudException(sprintf(
|
||||
'%s needs the model prop to be a class the extends %s',
|
||||
__CLASS__,
|
||||
Model::class
|
||||
));
|
||||
}
|
||||
if (!request()->ajax() and !app()->runningInConsole()) {
|
||||
self::shareCrudModelsClassesToView();
|
||||
$this->shareModelClassToView();
|
||||
$this->shareModelTableToView();
|
||||
$this->shareModelPropsToView();
|
||||
}
|
||||
}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder */
|
||||
$models = static::$modelClass::query();
|
||||
if ($request->s) {
|
||||
$model = static::$modelClass;
|
||||
$col = (new $model())->crudLabelColumn;
|
||||
$models = $models->where($col, 'LIKE', "%$request->s%");
|
||||
}
|
||||
$models = $this->indexQuery($models);
|
||||
/** @var \Illuminate\Pagination\AbstractPaginator */
|
||||
$models = $models->paginate(config('crud.paginate', 15));
|
||||
if ($request->ajax()) {
|
||||
return response()->json(CrudResource::collection($models));
|
||||
} else {
|
||||
$models = $models->withQueryString();
|
||||
return view('crud.index', compact('models'));
|
||||
}
|
||||
}
|
||||
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
public function show(Model $model)
|
||||
{
|
||||
return view('crud.show', compact('model'));
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view('crud.create');
|
||||
}
|
||||
|
||||
public function store(StoreCrudModel $request)
|
||||
{
|
||||
$modelClass = static::$modelClass;
|
||||
$model = new $modelClass();
|
||||
$model->fill($request->validated());
|
||||
$this->storeModel($model);
|
||||
$model->saveOrFail();
|
||||
$model->saveRelations($request);
|
||||
return \redirect()->route(sprintf('bo.%s.edit', $model->getTable()), $model)
|
||||
->with('success', trans(':model à bien été enregisté.', ['model' => $model->getModelName()]));
|
||||
}
|
||||
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
public function edit(Model $model)
|
||||
{
|
||||
return view('crud.edit', compact('model'));
|
||||
}
|
||||
|
||||
public function update(UpdateCrudModel $request, Model $model)
|
||||
{
|
||||
$model->fill($request->validated());
|
||||
$this->updateModel($model);
|
||||
$model->saveOrFail();
|
||||
$model->saveRelations($request);
|
||||
return \redirect()->route(sprintf('bo.%s.edit', $model->getTable()), $model)
|
||||
->with('success', trans(':model à bien été enregisté.', ['model' => $model->getModelName()]));
|
||||
}
|
||||
|
||||
public function destroy(Model $model)
|
||||
{
|
||||
if ($restrict = $model->gotHasManyRelationWithRestrictOnDelete()) {
|
||||
return redirect()->back()
|
||||
->with('error', trans(
|
||||
':model n\'as pas pu être supprimé car il est encore associé avec des :associated',
|
||||
[
|
||||
'model' => $model->getModelName(),
|
||||
'associated' => Str::plural($restrict)
|
||||
]
|
||||
));
|
||||
}
|
||||
if ($model->delete()) {
|
||||
return \redirect()->route(sprintf('bo.%s.index', $model->getTable()))
|
||||
->with('warning', trans(':model à bien été supprimé.', ['model' => $model->getModelName()]));
|
||||
} else {
|
||||
return redirect()->back()
|
||||
->with('error', trans(':model n\'as pas pu être supprimé', ['model' => $model->getModelName()]));
|
||||
}
|
||||
}
|
||||
|
||||
public function getModelClass()
|
||||
{
|
||||
return static::$modelClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current model class
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function shareCrudModelsClassesToView(): void
|
||||
{
|
||||
$models = [];
|
||||
foreach (File::allFiles(\app_path('Http/Controllers')) as $file) {
|
||||
$class = sprintf('App\Http\Controllers\%s', \substr($file->getFilename(), 0, -4));
|
||||
if (is_subclass_of($class, CrudController::class) and $class::$modelClass) {
|
||||
$models[] = $class::$modelClass;
|
||||
}
|
||||
}
|
||||
View::share('modelsClasses', $models);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current model class
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function shareModelClassToView(): void
|
||||
{
|
||||
View::share('modelClass', static::$modelClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current model table
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function shareModelTableToView(): void
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Model $model */
|
||||
$model = static::$modelClass;
|
||||
View::share('modelTable', (new $model())->getTable());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current model properties
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function shareModelPropsToView(): void
|
||||
{
|
||||
$model = static::$modelClass;
|
||||
View::share('props', (new $model())->getEditableProperties());
|
||||
}
|
||||
}
|
||||
384
app/Http/Controllers/EmployeesController.php
Normal file
384
app/Http/Controllers/EmployeesController.php
Normal file
|
|
@ -0,0 +1,384 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\EmployeeAddressUpdateRequest;
|
||||
use App\Http\Requests\EmployeeBankUpdateRequest;
|
||||
use App\Http\Requests\EmployeeFamilyUpdateRequest;
|
||||
use App\Http\Requests\EmployeeForgottenPasswordRequest;
|
||||
use App\Http\Requests\EmployeeFormationQuestionRequest;
|
||||
use App\Http\Requests\EmployeeLoginRequest;
|
||||
use App\Http\Requests\EmployeeMailChangeRequest;
|
||||
use App\Http\Requests\EmployeePasswordChangeRequest;
|
||||
use App\Http\Requests\EmployeeRdvQuestionRequest;
|
||||
use App\Http\Requests\EmployeeResetPasswordRequest;
|
||||
use App\Http\Requests\ImportEmployeesCsvFile;
|
||||
use App\Imports\EmployeeImport;
|
||||
use App\Imports\EmployeeSortie;
|
||||
use App\Jobs\SendMailConfirmToEmployee;
|
||||
use App\Jobs\SendMailResetPasswordToEmployee;
|
||||
use App\Jobs\SendEmployeeInfoMailToSiteRH;
|
||||
use App\Jobs\SendEmployeeLockedDownMailToEmployee;
|
||||
use App\Jobs\SendEmployeeLockedDownMailToSiteRH;
|
||||
use App\Mail\EmployeeInfoAddress;
|
||||
use App\Mail\EmployeeInfoBank;
|
||||
use App\Mail\EmployeeInfoFamily;
|
||||
use App\Mail\EmployeeLockedDown;
|
||||
use App\Mail\EmployeeQuestionFormation;
|
||||
use App\Mail\EmployeeQuestionRdv;
|
||||
use App\Mail\EmployeeYourAccountIsLockedDown;
|
||||
use App\Models\Employee;
|
||||
use App\Models\EmployeeMailToken;
|
||||
use App\Models\Site;
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Str;
|
||||
use Maatwebsite\Excel\Excel as LExcel;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Maatwebsite\Excel\Validators\ValidationException;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
|
||||
|
||||
class EmployeesController extends CrudController
|
||||
{
|
||||
|
||||
/** @var Employee */
|
||||
protected static $modelClass = Employee::class;
|
||||
|
||||
// BO
|
||||
|
||||
// Eloquent callbacks
|
||||
public function indexQuery(Builder $query): Builder
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
return $query->whereIn('site_id', $user->sites()->pluck('id'));
|
||||
}
|
||||
|
||||
public function storeModel(Model &$model)
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
$model->site_id = $user->selected_site_id;
|
||||
}
|
||||
|
||||
public function updateModel(Model &$model)
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
$model->site_id = $user->selected_site_id;
|
||||
}
|
||||
|
||||
public function importExit()
|
||||
{
|
||||
$this->authorize('importExit', Employee::class);
|
||||
CrudController::shareCrudModelsClassesToView();
|
||||
return view('back.employees.import-exit');
|
||||
}
|
||||
|
||||
public function importExitSubmit(ImportEmployeesCsvFile $request)
|
||||
{
|
||||
$this->authorize('import', Employee::class);
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
/** @var \App\Models\Site */
|
||||
$site = Site::where('id', $user->selected_site_id)->firstOrFail();
|
||||
$employeeImport = null;
|
||||
try {
|
||||
$employeeImport = new EmployeeSortie($site);
|
||||
Excel::import(
|
||||
$employeeImport,
|
||||
$request->file,
|
||||
null,
|
||||
LExcel::CSV
|
||||
);
|
||||
} catch (ReaderException $e) {
|
||||
// this time cannot read anything
|
||||
return redirect()->back()->withErrors('Echec lors de l\'import le fichier doit être conforme à celui fourni lors du developement de l\'application');
|
||||
} catch (Exception $e) {
|
||||
// $employeeImport->errorMessages
|
||||
// this time cannot read anything
|
||||
return redirect()->back()->withErrors(sprintf(
|
||||
'Echec lors de l\'import %s',
|
||||
$e->getMessage()
|
||||
));
|
||||
} finally {
|
||||
$message = sprintf(
|
||||
"%d salariés on été supprimés",
|
||||
$employeeImport->removedCount,
|
||||
);
|
||||
if (count($employeeImport->importedFailed)) {
|
||||
$message .= sprintf(
|
||||
"\n %d echecs\n Les lignes suivantes ont été ignorés \n%s\n",
|
||||
count($employeeImport->importedFailed),
|
||||
\collect($employeeImport->importedFailed)->map(function ($d) {
|
||||
return $d->implode(',');
|
||||
})->implode("\n"),
|
||||
);
|
||||
}
|
||||
if (count($employeeImport->errorMessages)) {
|
||||
$message .= sprintf(
|
||||
"\n %d erreurs\n Les erreurs suivantes sont apparues %s",
|
||||
count($employeeImport->errorMessages),
|
||||
implode("\n", $employeeImport->errorMessages),
|
||||
);
|
||||
}
|
||||
return redirect()->route('bo.employees.importExit')
|
||||
->with('success', $message);
|
||||
}
|
||||
}
|
||||
|
||||
public function import()
|
||||
{
|
||||
$this->authorize('import', Employee::class);
|
||||
CrudController::shareCrudModelsClassesToView();
|
||||
return view('back.employees.import');
|
||||
}
|
||||
|
||||
public function importSubmit(ImportEmployeesCsvFile $request)
|
||||
{
|
||||
$this->authorize('import', Employee::class);
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
/** @var \App\Models\Site */
|
||||
$site = Site::where('id', $user->selected_site_id)->firstOrFail();
|
||||
$employeeImport = null;
|
||||
try {
|
||||
$employeeImport = new EmployeeImport($site);
|
||||
Excel::import(
|
||||
$employeeImport,
|
||||
$request->file,
|
||||
null,
|
||||
LExcel::CSV
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
// this time cannot read anything
|
||||
return redirect()->back()->withErrors(sprintf(
|
||||
'Echec lors de l\'import %s',
|
||||
$e->getMessage()
|
||||
));
|
||||
} catch (ReaderException $e) {
|
||||
// this time cannot read anything
|
||||
return redirect()->back()->withErrors('Echec lors de l\'import le fichier doit être conforme à celui fourni lors du developement de l\'application');
|
||||
} finally {
|
||||
$message = '';
|
||||
$errors = [];
|
||||
foreach ($employeeImport->errorMessages as $k => $err) {
|
||||
$errors[] = sprintf(
|
||||
"\nLigne %d :\n%s\nDonnée:\n%s\n",
|
||||
$k + 1,
|
||||
\implode("\n", $err),
|
||||
\implode(", ", $employeeImport->importedFailed[$k]->all())
|
||||
);
|
||||
}
|
||||
if (count($errors)) {
|
||||
$message = sprintf(
|
||||
"%d salariés on été importés \n %d salariés mis à jour\n %d erreurs\n Les erreurs suivantes sont apparues %s",
|
||||
$employeeImport->importedCount,
|
||||
$employeeImport->updatedCount,
|
||||
count($errors),
|
||||
implode("\n", $errors),
|
||||
);
|
||||
} else {
|
||||
$message = sprintf(
|
||||
"%d salariés on été importés",
|
||||
$employeeImport->importedCount,
|
||||
);
|
||||
}
|
||||
return redirect()->route('bo.employees.import')
|
||||
->with('success', $message);
|
||||
}
|
||||
}
|
||||
|
||||
// FO
|
||||
|
||||
public function logout()
|
||||
{
|
||||
/** @var \Illuminate\Auth\SessionGuard */
|
||||
$guard = Auth::guard('employee');
|
||||
$guard->logout();
|
||||
return redirect()->route('employees.login');
|
||||
}
|
||||
|
||||
public function loginSubmit(EmployeeLoginRequest $request)
|
||||
{
|
||||
/** @var \Illuminate\Auth\SessionGuard */
|
||||
$guard = Auth::guard('employee');
|
||||
|
||||
if (!($employee = Employee::where('matricule', $request->login)->first())) {
|
||||
return \redirect()->route('employees.login')
|
||||
->withErrors(['Les identifiants fournis sont incorrects'], 'login');
|
||||
}
|
||||
|
||||
// Is employee locked down ?
|
||||
if ($employee->password_attempts >= 3) {
|
||||
return \redirect()->route('employees.login')
|
||||
->withErrors([trans(sprintf(
|
||||
'Votre compte est verouillé, il vous faut contacter votre responsable RH pour le deverouiller',
|
||||
3 - $employee->password_attempts
|
||||
))], 'lockedDown')->with('site', $employee->site);
|
||||
}
|
||||
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
if (!$guard->attempt(['matricule' => $request->login, 'password' => $request->password], $request->rememberMe)) {
|
||||
$employee->password_attempts = $employee->password_attempts + 1;
|
||||
$employee->saveOrFail();
|
||||
|
||||
// Is employee locked down ?
|
||||
if ($employee->password_attempts >= 3) {
|
||||
SendEmployeeLockedDownMailToEmployee::dispatchAfterResponse(new EmployeeLockedDown($employee), $employee);
|
||||
SendEmployeeLockedDownMailToSiteRH::dispatchAfterResponse(new EmployeeYourAccountIsLockedDown($employee), $employee);
|
||||
return \redirect()->route('employees.login')
|
||||
->withErrors(
|
||||
[trans('Votre compte est verouillé, il vous faut contacter votre responsable RH pour le deverouiller')],
|
||||
'lockedDown'
|
||||
)->with('site', $employee->site);
|
||||
}
|
||||
|
||||
return \redirect()->route('employees.login')
|
||||
->withErrors([trans(sprintf(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'Attention plus que %d essais, après cela votre compte sera verrouillé, un mail à été envoyé pour prévenir votre responsable RH (seul lui peux déverouiller votre compte)',
|
||||
3 - $employee->password_attempts
|
||||
))], 'login');
|
||||
}
|
||||
$request->session()->regenerate();
|
||||
return redirect()->intended(route('fo.flash.index'));
|
||||
}
|
||||
|
||||
public function passwordForgottenSubmit(EmployeeForgottenPasswordRequest $request)
|
||||
{
|
||||
$employee = Employee::where('matricule', $request->matricule)->firstOrFail();
|
||||
$token = $employee->token ?? new EmployeeMailToken();
|
||||
$token->fill([
|
||||
'email' => $employee->email,
|
||||
'employee_id' => $employee->id
|
||||
]);
|
||||
$token->saveOrFail();
|
||||
$token->employee()->associate($token);
|
||||
SendMailResetPasswordToEmployee::dispatchAfterResponse($employee);
|
||||
return \redirect()->back()->with('successMail', true);
|
||||
}
|
||||
|
||||
public function resetPassword(EmployeeMailToken $token = null)
|
||||
{
|
||||
if ($token) {
|
||||
Session::put('resetMail', time());
|
||||
Session::put('resetMailEmployee', $token->employee);
|
||||
Session::save();
|
||||
$token->delete();
|
||||
}
|
||||
|
||||
// If token has been consumed and we has a resetMail in Session then pass trough
|
||||
if (Session::has('resetMail') and (Session::get('resetMail') + 60 * 4) > time()) {
|
||||
return view('front.employees.changePassword', ['reset' => true]);
|
||||
}
|
||||
Session::forget('resetMail');
|
||||
Session::forget('resetMailEmployee');
|
||||
Session::save();
|
||||
abort(redirect()->route('fo.flash.index'));
|
||||
}
|
||||
|
||||
public function resetPasswordSubmit(EmployeeResetPasswordRequest $request)
|
||||
{
|
||||
/** @var Employee */
|
||||
if ($employee = Session::get('resetMailEmployee', null)) {
|
||||
$employee->password = $request->newpassword;
|
||||
$employee->saveOrFail();
|
||||
Session::forget('resetMail');
|
||||
Session::forget('resetMailEmployee');
|
||||
Session::save();
|
||||
return redirect()->route('employees.done-reset-password');
|
||||
}
|
||||
abort(redirect()->route('fo.flash.index'));
|
||||
}
|
||||
|
||||
public function passwordChangeSubmit(EmployeePasswordChangeRequest $request)
|
||||
{
|
||||
$employee = $this->getEmployee();
|
||||
$employee->password = $request->newpassword;
|
||||
$employee->saveOrFail();
|
||||
if (Session::has('required')) {
|
||||
Session::remove('required');
|
||||
Session::save();
|
||||
return redirect()->route('fo.flash.index')
|
||||
->with('message', trans('Votre mot de passe à bien été mis à jour'));
|
||||
}
|
||||
return \redirect()->back()->with('success', true);
|
||||
}
|
||||
|
||||
public function mailUpdate(EmployeeMailChangeRequest $request)
|
||||
{
|
||||
$employee = $this->getEmployee();
|
||||
$token = $employee->token ?? new EmployeeMailToken();
|
||||
$token->fill([
|
||||
'email' => $request->email,
|
||||
'employee_id' => $employee->id
|
||||
]);
|
||||
$token->saveOrFail();
|
||||
$token->employee()->associate($token);
|
||||
SendMailConfirmToEmployee::dispatchAfterResponse($employee);
|
||||
return \redirect()->back()->with('successMail', true)
|
||||
->with('message', trans('Informations mises à jour'));
|
||||
}
|
||||
|
||||
public function confirmMail(EmployeeMailToken $token)
|
||||
{
|
||||
$employee = $token->employee;
|
||||
$employee->email = $token->email;
|
||||
$employee->saveOrFail();
|
||||
$token->delete();
|
||||
return view('front.emailActivated');
|
||||
}
|
||||
|
||||
public function familyUpdate(EmployeeFamilyUpdateRequest $request)
|
||||
{
|
||||
$this->sendInfo(EmployeeInfoFamily::class, $request);
|
||||
return \redirect()->back()->with('success', true)
|
||||
->with('message', trans('Informations transmises'));
|
||||
}
|
||||
|
||||
public function addressUpdate(EmployeeAddressUpdateRequest $request)
|
||||
{
|
||||
$this->sendInfo(EmployeeInfoAddress::class, $request);
|
||||
return \redirect()->back()->with('success', true)
|
||||
->with('message', trans('Informations transmises'));
|
||||
}
|
||||
|
||||
public function bankUpdate(EmployeeBankUpdateRequest $request)
|
||||
{
|
||||
$this->sendInfo(EmployeeInfoBank::class, $request);
|
||||
return \redirect()->back()->with('success', true)
|
||||
->with('message', trans('Informations transmises'));
|
||||
}
|
||||
|
||||
public function questionFormation(EmployeeFormationQuestionRequest $request)
|
||||
{
|
||||
$this->sendInfo(EmployeeQuestionFormation::class, $request);
|
||||
return \redirect()->back()->with('success', true)
|
||||
->with('message', trans('Informations transmises'));
|
||||
}
|
||||
|
||||
public function questionRdv(EmployeeRdvQuestionRequest $request)
|
||||
{
|
||||
$this->sendInfo(EmployeeQuestionRdv::class, $request);
|
||||
return \redirect()->back()->with('success', true)
|
||||
->with('message', trans('Informations transmises'));
|
||||
}
|
||||
|
||||
private function sendInfo(string $mailClass, FormRequest $request)
|
||||
{
|
||||
SendEmployeeInfoMailToSiteRH::dispatchAfterResponse(
|
||||
new $mailClass(
|
||||
array_merge(
|
||||
['employee' => auth('employee')->user()],
|
||||
$request->validated()
|
||||
)
|
||||
),
|
||||
auth('employee')->user()
|
||||
);
|
||||
}
|
||||
}
|
||||
57
app/Http/Controllers/FlashesController.php
Normal file
57
app/Http/Controllers/FlashesController.php
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Flash;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class FlashesController extends CrudController
|
||||
{
|
||||
|
||||
/** @var Flash */
|
||||
protected static $modelClass = Flash::class;
|
||||
|
||||
// BO
|
||||
|
||||
// Eloquent callbacks
|
||||
public function indexQuery(Builder $query): Builder
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
$flashesID = \collect([]);
|
||||
$user->sites()->with('flashes')->get()->map(function (Site $site) use (&$flashesID) {
|
||||
$flashesID = $flashesID->merge($site->flashes->pluck('id')->all());
|
||||
});
|
||||
return $query->whereIn('id', $flashesID->unique());
|
||||
}
|
||||
|
||||
public function storeModel(Model &$model)
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
$model->site_id = $user->selected_site_id;
|
||||
}
|
||||
|
||||
public function updateModel(Model &$model)
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
$model->site_id = $user->selected_site_id;
|
||||
}
|
||||
|
||||
// FO
|
||||
|
||||
public function inform()
|
||||
{
|
||||
$flashes = $this->getEmployee()->getFlashes();
|
||||
return view('front.flashes.index', compact('flashes'));
|
||||
}
|
||||
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
public function informShow(Flash $flash)
|
||||
{
|
||||
return view('front.flashes.show', compact('flash'));
|
||||
}
|
||||
}
|
||||
14
app/Http/Controllers/HomeController.php
Normal file
14
app/Http/Controllers/HomeController.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
// BO
|
||||
|
||||
public function home()
|
||||
{
|
||||
CrudController::shareCrudModelsClassesToView();
|
||||
return view('back.home');
|
||||
}
|
||||
}
|
||||
148
app/Http/Controllers/PlanningController.php
Normal file
148
app/Http/Controllers/PlanningController.php
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\ImportPlanningXlsFile;
|
||||
use App\Imports\PlanningImport;
|
||||
use App\Models\Planning;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Maatwebsite\Excel\Excel as LExcel;
|
||||
use Maatwebsite\Excel\HeadingRowImport;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
|
||||
|
||||
class PlanningController extends Controller
|
||||
{
|
||||
|
||||
// BO
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// AUTH CONTROL TO ROOT POLICY
|
||||
$this->authorizeResource(Planning::class);
|
||||
}
|
||||
|
||||
public function import()
|
||||
{
|
||||
$this->authorize('import', Planning::class);
|
||||
CrudController::shareCrudModelsClassesToView();
|
||||
return view('back.plannings.import');
|
||||
}
|
||||
|
||||
public function importSubmit(ImportPlanningXlsFile $request)
|
||||
{
|
||||
$this->authorize('import', Planning::class);
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
/** @var \App\Models\Site */
|
||||
$site = Site::where('id', $user->selected_site_id)->firstOrFail();
|
||||
$planningImport = null;
|
||||
try {
|
||||
try {
|
||||
$planningImport = new PlanningImport($site, (new HeadingRowImport())->toArray(
|
||||
$request->file,
|
||||
null,
|
||||
LExcel::XLS
|
||||
));
|
||||
Excel::import(
|
||||
$planningImport,
|
||||
$request->file,
|
||||
null,
|
||||
LExcel::XLS
|
||||
);
|
||||
} catch (ReaderException $e) {
|
||||
// Assert This is XML
|
||||
$xmlString = $this->filterXml($request->file);
|
||||
|
||||
// create ne temp file
|
||||
$stream = tmpfile();
|
||||
fwrite($stream, $xmlString);
|
||||
$file = new UploadedFile(
|
||||
stream_get_meta_data($stream)['uri'],
|
||||
'xml data',
|
||||
'application/vnd.ms-excel'
|
||||
);
|
||||
$planningImport = new PlanningImport($site, (new HeadingRowImport())->toArray(
|
||||
$file,
|
||||
null,
|
||||
LExcel::XML
|
||||
));
|
||||
Excel::import(
|
||||
$planningImport,
|
||||
$file,
|
||||
null,
|
||||
LExcel::XML
|
||||
);
|
||||
\fclose($stream);
|
||||
}
|
||||
} catch (ReaderException $e) {
|
||||
// this time cannot read anything
|
||||
return redirect()->back()->withErrors('Echec lors de l\'import le fichier doit être conforme à celui fourni lors du developement de l\'application');
|
||||
} finally {
|
||||
return redirect()->route('bo.plannings.import')
|
||||
->with('success', sprintf(
|
||||
"%d plannings on été importés \n Les plannings suivant n'ont pu être importés \n %s",
|
||||
$planningImport->importedCount,
|
||||
collect($planningImport->importedFailed)->map(function ($d) {
|
||||
return $d->implode(',');
|
||||
})->implode("\n")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Le parser Xml ne supporte pas la lecture de cellule
|
||||
* dont le contenu est encapsulé avec du style... (toujours plus)
|
||||
* Donc on va essayer de virer ceux-ci
|
||||
*
|
||||
* NOTE: Conforme au fichier transmis par Ossan et gitté dans resources/documents à cette date
|
||||
* eg :
|
||||
* <Cell ss:MergeDown="2" ss:StyleID="m2129200830208"><ss:Data ss:Type="String"
|
||||
* xmlns="http://www.w3.org/TR/REC-html40"><B><Font html:Color="#000000">CHUPE JEAN CHARLES </Font><I><Font
|
||||
* html:Face="Parisine Plus Ptf Sombre" x:Family="Swiss" html:Size="11"
|
||||
* html:Color="#FFFFFF">SSsT</Font></I></B></ss:Data></Cell>
|
||||
*
|
||||
* @param UploadedFile $file
|
||||
* @return string
|
||||
*/
|
||||
private function filterXml(UploadedFile $file): string
|
||||
{
|
||||
$xmlString = $file->get();
|
||||
$xmlString = str_replace(
|
||||
[
|
||||
'<B>',
|
||||
'</B>',
|
||||
'<I>',
|
||||
'</I>',
|
||||
'<Font>',
|
||||
'<Font ss:FontName="Arial" x:Family="Swiss" ss:Color="#000000" ss:Size="8" ss:Bold="1"/>',
|
||||
'<Font ss:FontName="Arial" x:Family="Swiss" ss:Size="8" ss:Color="#000000" ss:Bold="1"/>',
|
||||
'<Font ss:FontName="Arial" x:Family="Swiss" ss:Size="8" ss:Color="#FF0000" ss:Bold="1"/>',
|
||||
'<Font html:Face=\'Parisine Plus Ptf Sombre\' x:Family=\'Swiss\' html:Size=\'11\' html:Color=\'#FFFFFF\'>',
|
||||
"<Font ss:FontName=\"Arial\" x:Family=\"Swiss\" ss:Size=\"8\" ss:Color=\"#000000\"\n ss:Bold=\"1\"/>",
|
||||
"<Font ss:FontName=\"Arial\" x:Family=\"Swiss\" ss:Size=\"8\" ss:Color=\"#000000\"\n",
|
||||
"<Font ss:FontName=\"Arial\" x:Family=\"Swiss\" ss:Size=\"8\" ss:Color=\"#fdfefe\"\n",
|
||||
"<Font ss:FontName=\"Arial\" x:Family=\"Swiss\" ss:Size=\"8\" ss:Color=\"#FFFFFF\"\n",
|
||||
" ss:Bold=\"1\"/>\n",
|
||||
'<Font html:Color=\'#000000\'>',
|
||||
'</Font>'
|
||||
],
|
||||
'',
|
||||
$xmlString
|
||||
);
|
||||
// dd($xmlString);
|
||||
return $xmlString;
|
||||
}
|
||||
|
||||
|
||||
// FO
|
||||
|
||||
public function showPlannings()
|
||||
{
|
||||
/** @var \App\Models\Employee */
|
||||
$employee = auth()->user();
|
||||
$plannings = $employee->getWeekAndNextPlannings();
|
||||
return view('front.employees.plannings', compact('plannings'));
|
||||
}
|
||||
}
|
||||
12
app/Http/Controllers/PolesController.php
Normal file
12
app/Http/Controllers/PolesController.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Pole;
|
||||
|
||||
class PolesController extends CrudController
|
||||
{
|
||||
|
||||
/** @var Pole */
|
||||
protected static $modelClass = Pole::class;
|
||||
}
|
||||
24
app/Http/Controllers/SitesController.php
Normal file
24
app/Http/Controllers/SitesController.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Site;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class SitesController extends CrudController
|
||||
{
|
||||
|
||||
/** @var Site */
|
||||
protected static $modelClass = Site::class;
|
||||
|
||||
// BO
|
||||
|
||||
// Eloquent callbacks
|
||||
|
||||
public function indexQuery(Builder $query): Builder
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
return $query->whereIn('id', $user->sites()->pluck('id'));
|
||||
}
|
||||
}
|
||||
12
app/Http/Controllers/SocietesController.php
Normal file
12
app/Http/Controllers/SocietesController.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Societe;
|
||||
|
||||
class SocietesController extends CrudController
|
||||
{
|
||||
|
||||
/** @var Employee */
|
||||
protected static $modelClass = Societe::class;
|
||||
}
|
||||
156
app/Http/Controllers/SondagesController.php
Normal file
156
app/Http/Controllers/SondagesController.php
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\SondageResponsesRequest;
|
||||
use App\Http\Requests\UpdateCrudModel;
|
||||
use App\Http\Requests\UpdateSondage;
|
||||
use App\Models\ReponseSondage;
|
||||
use App\Models\Sondage;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use League\Csv\Writer;
|
||||
|
||||
class SondagesController extends CrudController
|
||||
{
|
||||
|
||||
/** @var Sondage */
|
||||
protected static $modelClass = Sondage::class;
|
||||
|
||||
// Eloquent callbacks
|
||||
public function indexQuery(Builder $query): Builder
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
return $query->whereIn('site_id', $user->sites()->pluck('id'));
|
||||
}
|
||||
|
||||
public function storeModel(Model &$model)
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
$model->site_id = $user->selected_site_id;
|
||||
}
|
||||
|
||||
public function updateModel(Model &$model)
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
$model->site_id = $user->selected_site_id;
|
||||
}
|
||||
|
||||
// BO
|
||||
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
public function show(Model $model)
|
||||
{
|
||||
return view('crudOverLoad.sondages.show', compact('model'));
|
||||
}
|
||||
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
public function edit(Model $model)
|
||||
{
|
||||
return view('crudOverLoad.sondages.edit', compact('model'));
|
||||
}
|
||||
|
||||
public function updateSondage(UpdateSondage $request, Sondage $model)
|
||||
{
|
||||
$data = $request->validated();
|
||||
$model->fill($data);
|
||||
$model->saveOrFail();
|
||||
$model->reponseSondages()->delete();
|
||||
foreach ($data['reponses'] as $reponse) {
|
||||
$reponse = new ReponseSondage([
|
||||
'value' => $reponse
|
||||
]);
|
||||
$reponse->sondage()->associate($model);
|
||||
$reponse->saveorFail();
|
||||
}
|
||||
return \redirect()->route(sprintf('bo.%s.edit', $model->getTable()), $model)
|
||||
->with('success', trans(':model à bien été enregisté.', ['model' => $model->getModelName()]));
|
||||
}
|
||||
|
||||
public function export(Sondage $model)
|
||||
{
|
||||
$this->authorize('export', $model);
|
||||
$anwsers = $model->reponseSondages->load('employees');
|
||||
|
||||
$header = '"employee_matricule";' . implode(';', $anwsers->map(function ($answer) {
|
||||
return "\"$answer->value\"";
|
||||
})->all());
|
||||
|
||||
$w = Writer::createFromString($header . PHP_EOL);
|
||||
$w->setDelimiter(';');
|
||||
$w->setEnclosure('"');
|
||||
$w->setOutputBOM(Writer::BOM_UTF8);
|
||||
|
||||
$tmpl = [
|
||||
0 => '0',
|
||||
];
|
||||
foreach ($anwsers as $k => $answer) {
|
||||
$tmpl[$k + 1] = '0';
|
||||
}
|
||||
$res = [];
|
||||
foreach ($anwsers as $k => $answer) {
|
||||
$answer->employees->map(function ($employee) use ($answer, $k, &$res) {
|
||||
if (!array_key_exists($employee->id, $res)) {
|
||||
$res[$employee->id] = [
|
||||
'employee' => $employee,
|
||||
'answers' => []
|
||||
];
|
||||
}
|
||||
$res[$employee->id]['answers'][$k + 2] = 1;
|
||||
});
|
||||
}
|
||||
|
||||
foreach ($res as $customerIntel) {
|
||||
$w->insertOne(array_replace(
|
||||
$tmpl,
|
||||
[
|
||||
$customerIntel['employee']->id,
|
||||
],
|
||||
$customerIntel['answers']
|
||||
));
|
||||
}
|
||||
return response((string)$w, 200, [
|
||||
'Content-Encoding' => 'none',
|
||||
'Content-Type' => 'text/csv; charset=UTF-8',
|
||||
'Content-Disposition' => sprintf(
|
||||
'attachment; filename="Résultats Sondage %s - %s.csv',
|
||||
Str::slug($model->question),
|
||||
Str::slug(date('d_m_Y-H_i_s'))
|
||||
),
|
||||
'Content-Description' => 'File Transfer',
|
||||
]);
|
||||
}
|
||||
|
||||
// FO
|
||||
|
||||
public function sondages()
|
||||
{
|
||||
$sondages = $this->getEmployee()->unAnsweredSondages();
|
||||
return view('front.sondages.index', compact('sondages'));
|
||||
}
|
||||
|
||||
//phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
public function sondagesShow(Sondage $sondage)
|
||||
{
|
||||
$employee = $this->getEmployee();
|
||||
if ($employee->hasAnweredToSondage($sondage)) {
|
||||
return view('front.sondages.saved', ['answered' => true]);
|
||||
}
|
||||
return view('front.sondages.show', compact('sondage'));
|
||||
}
|
||||
|
||||
//phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
public function sondagesSubmit(SondageResponsesRequest $request, Sondage $sondage)
|
||||
{
|
||||
$employee = $this->getEmployee();
|
||||
if ($employee->hasAnweredToSondage($sondage)) {
|
||||
return view('front.sondages.saved', ['answered' => true]);
|
||||
}
|
||||
$employee->reponseSondages()->syncWithoutDetaching($request->reponses);
|
||||
return view('front.sondages.saved');
|
||||
}
|
||||
}
|
||||
12
app/Http/Controllers/UsersController.php
Normal file
12
app/Http/Controllers/UsersController.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class UsersController extends CrudController
|
||||
{
|
||||
|
||||
/** @var User */
|
||||
protected static $modelClass = User::class;
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
|||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
|
|
@ -20,6 +21,7 @@ class Kernel extends HttpKernel
|
|||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\App\Http\Middleware\XssSanitizer::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
|
|
@ -33,7 +35,6 @@ class Kernel extends HttpKernel
|
|||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
// \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
|
|
@ -62,5 +63,7 @@ class Kernel extends HttpKernel
|
|||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'userSite' => \App\Http\Middleware\UserSite::class,
|
||||
'employeeOutdatedPassword' => \App\Http\Middleware\EmployeeOutDatedPassword::class,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,20 @@ class Authenticate extends Middleware
|
|||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
$logins = [
|
||||
'web' => route('bo.login'),
|
||||
'employee' => route('employees.login')
|
||||
];
|
||||
if (! $request->expectsJson()) {
|
||||
return route('login');
|
||||
foreach ($request->route()->gatherMiddleware() as $middleware) {
|
||||
if (\is_string($middleware) and strpos($middleware, 'auth:') !== false) {
|
||||
$route = $logins[str_replace('auth:', '', $middleware)] ?? null;
|
||||
if ($route) {
|
||||
return $route;
|
||||
}
|
||||
}
|
||||
}
|
||||
return route('employees.login');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
35
app/Http/Middleware/EmployeeOutDatedPassword.php
Normal file
35
app/Http/Middleware/EmployeeOutDatedPassword.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class EmployeeOutDatedPassword
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
/** @var \App\Models\Employee */
|
||||
$employee = auth('employee')->user();
|
||||
if (
|
||||
$employee->password_date->addMonths(3)->lt(Carbon::now()) and
|
||||
!in_array($request->route()->getName(), [
|
||||
'fo.employees.passwordChange', 'fo.employees.passwordChangeSubmit',
|
||||
'fo.employees.logout'
|
||||
])
|
||||
) {
|
||||
Session::put('required', true);
|
||||
Session::save();
|
||||
return redirect()->route('fo.employees.passwordChange');
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
|||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Mi
|
|||
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
{
|
||||
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,11 +19,17 @@ class RedirectIfAuthenticated
|
|||
*/
|
||||
public function handle(Request $request, Closure $next, ...$guards)
|
||||
{
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
$homes = [
|
||||
'web' => route('bo.home'),
|
||||
'employee' => route('fo.flash.index')
|
||||
];
|
||||
$guards = empty($guards) ? [] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
// Pas de safe route si il manque un gard..
|
||||
return redirect($homes[$guard]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
|||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
|
|
@ -14,6 +15,8 @@ class TrimStrings extends Middleware
|
|||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
'newpassword',
|
||||
'newpasswordConfirm',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use Illuminate\Http\Request;
|
|||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
|
|
|
|||
47
app/Http/Middleware/UserSite.php
Normal file
47
app/Http/Middleware/UserSite.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\Site;
|
||||
use Closure;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class UserSite
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
try {
|
||||
if (!$user->selected_site_id) {
|
||||
$site = $user->sites()->firstOrFail();
|
||||
$user->selected_site_id = $site->id;
|
||||
$user->saveOrFail();
|
||||
}
|
||||
if ($request->query('userSite')) {
|
||||
$site = $user->sites()
|
||||
->where('site_id', $request->query('userSite'))
|
||||
->firstOrFail();
|
||||
$user->selected_site_id = $site->id;
|
||||
$user->saveOrFail();
|
||||
} elseif (!Site::where('id', $user->selected_site_id)->exists()) {
|
||||
$site = $user->sites()
|
||||
->where('site_id', $request->query('userSite'))
|
||||
->firstOrFail();
|
||||
$user->selected_site_id = $site->id;
|
||||
$user->saveOrFail();
|
||||
}
|
||||
} catch (ModelNotFoundException $e) {
|
||||
abort(400, 'Vous n\'avez pas de site administrable');
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
|||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
|
|
|
|||
29
app/Http/Middleware/XssSanitizer.php
Normal file
29
app/Http/Middleware/XssSanitizer.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class XssSanitizer
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next, ...$params)
|
||||
{
|
||||
$inputs = $request->all();
|
||||
array_walk_recursive($inputs, function (&$input, $name) use ($params) {
|
||||
if (in_array($name, $params)) {
|
||||
$input = clean($input);
|
||||
} else {
|
||||
$input = strip_tags($input);
|
||||
}
|
||||
});
|
||||
$request->merge($inputs);
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
79
app/Http/Requests/CrudRequest.php
Normal file
79
app/Http/Requests/CrudRequest.php
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Enums\CrudAction;
|
||||
use App\Enums\CrudType;
|
||||
use App\Exceptions\CrudException;
|
||||
use App\Http\Controllers\CrudController;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Traits\IsCrudModel;
|
||||
|
||||
class CrudRequest extends FormRequest
|
||||
{
|
||||
|
||||
/** @var array */
|
||||
protected $rules = [];
|
||||
|
||||
/**
|
||||
* Get rules for a specific action
|
||||
*
|
||||
* @param CrudAction $action
|
||||
* @return array
|
||||
*/
|
||||
public function getRulesForAction(CrudAction $action): array
|
||||
{
|
||||
$props = $this->getCurrentModel()::getEditableProperties();
|
||||
$propsRules = [];
|
||||
foreach ($this->getCurrentModel()::getRules() as $k => $rules) {
|
||||
$propsRules[$k] = [];
|
||||
$propIsAllowedOnUpdateAction = in_array($action, $props[$k]['actions']);
|
||||
foreach ($rules as $rule) {
|
||||
// dont copy required if prop is not allowed on update
|
||||
if (!$propIsAllowedOnUpdateAction and is_string($rule) and $rule == 'required') {
|
||||
continue;
|
||||
}
|
||||
if (!in_array($rule, $propsRules[$k])) {
|
||||
$propsRules[$k][] = $rule;
|
||||
}
|
||||
// handle password
|
||||
if (
|
||||
$props[$k]['type']->equals(CrudType::password()) and
|
||||
!$this->{$k} or (is_string($this->{$k}) and !\strlen($this->{$k}))
|
||||
) {
|
||||
$this->offsetUnset($k);
|
||||
}
|
||||
// handle boolean
|
||||
if ($props[$k]['type']->equals(CrudType::boolean())) {
|
||||
$this->merge([$k => $this->{$k} ? 1 : 0]);
|
||||
}
|
||||
// handle belongsToMany
|
||||
if ($props[$k]['type']->equals(CrudType::belongsToMany())) {
|
||||
$propsRules["$k.*"][0] = 'exists:' .
|
||||
(new $props[$k]['belongsToMany']())->getTable() . ',id';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $propsRules;
|
||||
}
|
||||
/**
|
||||
* Returns the first parameter that is a crud model
|
||||
*
|
||||
* @return string \Illuminate\Database\Eloquent\Model class name
|
||||
* @throws \App\Exceptions\CrudException if the request does not have a crud model parameter
|
||||
*/
|
||||
protected function getCurrentModel(): string
|
||||
{
|
||||
if (
|
||||
!is_object($this->route()->controller) or
|
||||
!$this->route()->controller instanceof CrudController
|
||||
) {
|
||||
throw new CrudException(sprintf(
|
||||
'Request `%s` needs to be bound on route that use a CrudController',
|
||||
get_class($this)
|
||||
));
|
||||
}
|
||||
return $this->route()->controller->getModelClass();
|
||||
}
|
||||
}
|
||||
34
app/Http/Requests/EmployeeAddressUpdateRequest.php
Normal file
34
app/Http/Requests/EmployeeAddressUpdateRequest.php
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class EmployeeAddressUpdateRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('employee')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'address' => 'required|string|min:5',
|
||||
'city' => 'required|string|min:2',
|
||||
'postcode' => 'required|digits_between:5,7',
|
||||
'phone' => 'required|numeric|digits_between:10,12',
|
||||
'mobile' => 'required|numeric|digits_between:10,12',
|
||||
];
|
||||
}
|
||||
}
|
||||
30
app/Http/Requests/EmployeeBankUpdateRequest.php
Normal file
30
app/Http/Requests/EmployeeBankUpdateRequest.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class EmployeeBankUpdateRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('employee')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'file' => 'required|file|mimes:jpeg,png,jpg,pdf|max:2048'
|
||||
];
|
||||
}
|
||||
}
|
||||
31
app/Http/Requests/EmployeeFamilyUpdateRequest.php
Normal file
31
app/Http/Requests/EmployeeFamilyUpdateRequest.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class EmployeeFamilyUpdateRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('employee')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'message' => 'required|string|min:20',
|
||||
'file' => 'required|file|mimes:jpeg,png,jpg,pdf|max:2048'
|
||||
];
|
||||
}
|
||||
}
|
||||
30
app/Http/Requests/EmployeeForgottenPasswordRequest.php
Normal file
30
app/Http/Requests/EmployeeForgottenPasswordRequest.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class EmployeeForgottenPasswordRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'matricule' => 'required|string|exists:employees,matricule'
|
||||
];
|
||||
}
|
||||
}
|
||||
30
app/Http/Requests/EmployeeFormationQuestionRequest.php
Normal file
30
app/Http/Requests/EmployeeFormationQuestionRequest.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class EmployeeFormationQuestionRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('employee')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'message' => 'required|string|min:20'
|
||||
];
|
||||
}
|
||||
}
|
||||
35
app/Http/Requests/EmployeeLoginRequest.php
Normal file
35
app/Http/Requests/EmployeeLoginRequest.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class EmployeeLoginRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
$this->merge([
|
||||
'rememberMe' => $this->rememberMe ? true : false
|
||||
]);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'login' => 'required|string',
|
||||
'password' => 'required|string',
|
||||
'rememberMe' => 'required|boolean'
|
||||
];
|
||||
}
|
||||
}
|
||||
31
app/Http/Requests/EmployeeMailChangeRequest.php
Normal file
31
app/Http/Requests/EmployeeMailChangeRequest.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class EmployeeMailChangeRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('employee')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'email' => 'required|email:rfc,dns|unique:employees,email,' . auth('employee')->user()->id,
|
||||
'emailConfirm' => 'required|same:email'
|
||||
];
|
||||
}
|
||||
}
|
||||
69
app/Http/Requests/EmployeePasswordChangeRequest.php
Normal file
69
app/Http/Requests/EmployeePasswordChangeRequest.php
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class EmployeePasswordChangeRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('employee')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
/** @var \App\Models\Employee */
|
||||
$employee = auth('employee')->user();
|
||||
return [
|
||||
'password' => [
|
||||
'required',
|
||||
'string',
|
||||
//phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) use ($employee) {
|
||||
if (
|
||||
!auth('employee')->validate([
|
||||
'matricule' => $employee->matricule,
|
||||
'password' => $value
|
||||
])
|
||||
) {
|
||||
$fail(trans('Votre ancien mot de passe est invalide'));
|
||||
}
|
||||
}
|
||||
],
|
||||
'newpassword' => [
|
||||
'required',
|
||||
'string',
|
||||
'regex:/^(?=.*[A-Z])(?=.*[²&~"#\'\{\(\[\-|`_\\^@\)\°=+\}¨^$£¤%?,;.:\/!§*<>])(?=.*[0-9].*)(?=.*[a-z]).{8,}$/'
|
||||
],
|
||||
'newpasswordConfirm' => 'required|same:newpassword'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error messages for the defined validation rules.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
'newpassword.regex' => trans("
|
||||
Votre mot de passe doit être d'au moins 8 charactères,
|
||||
il doit comporter au moins un caractère en majuscule,
|
||||
un caractère en minuscule,
|
||||
un nombre et
|
||||
un caractère spécial parmis les suivants : ²&~\"#'{([-|`_\^@)°=+}¨^\$£¤%?,;.:\/!§*<>"),
|
||||
];
|
||||
}
|
||||
}
|
||||
30
app/Http/Requests/EmployeeRdvQuestionRequest.php
Normal file
30
app/Http/Requests/EmployeeRdvQuestionRequest.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class EmployeeRdvQuestionRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('employee')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'message' => 'required|string|min:20'
|
||||
];
|
||||
}
|
||||
}
|
||||
36
app/Http/Requests/EmployeeResetPasswordRequest.php
Normal file
36
app/Http/Requests/EmployeeResetPasswordRequest.php
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class EmployeeResetPasswordRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return Session::has('resetMail');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'newpassword' => [
|
||||
'required',
|
||||
'string',
|
||||
'regex:/^(?=.*[A-Z])(?=.*[²&~"#\'\{\(\[\-|`_\\^@\)\°=+\}¨^$£¤%?,;.:\/!§*<>])(?=.*[0-9].*)(?=.*[a-z]).{8,}$/'
|
||||
],
|
||||
'newpasswordConfirm' => 'required|same:newpassword'
|
||||
];
|
||||
}
|
||||
}
|
||||
42
app/Http/Requests/ImportEmployeesCsvFile.php
Normal file
42
app/Http/Requests/ImportEmployeesCsvFile.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ImportEmployeesCsvFile extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
// max 50 Mo
|
||||
'file' => [
|
||||
'required',
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'mimetypes:text/csv,text/plain,application/csv,text/comma-separated-values,text/anytext,application/octet-stream,application/txt',
|
||||
'max:51200',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->file->getClientMimeType() !== 'application/vnd.ms-excel') {
|
||||
$fail(__('Le fichier doit être d\'un mime type application/vnd.ms-excel'));
|
||||
}
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
42
app/Http/Requests/ImportPlanningXlsFile.php
Normal file
42
app/Http/Requests/ImportPlanningXlsFile.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ImportPlanningXlsFile extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
// max 50 Mo
|
||||
'file' => [
|
||||
'required',
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'mimetypes:application/vnd.ms-excel,application/vnd.ms-office,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,text/xml',
|
||||
'max:51200',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->file->getClientMimeType() !== 'application/vnd.ms-excel') {
|
||||
$fail(__('Le fichier doit être d\'un mime type application/vnd.ms-excel'));
|
||||
}
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
49
app/Http/Requests/SondageResponsesRequest.php
Normal file
49
app/Http/Requests/SondageResponsesRequest.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Enums\TypeSondage;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SondageResponsesRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('employee')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$responsesIds = $this->sondage->reponseSondages()->pluck('id')->all();
|
||||
switch ($this->sondage->type) {
|
||||
case TypeSondage::radio():
|
||||
case TypeSondage::checkbox():
|
||||
return [
|
||||
'reponses' => 'required|array',
|
||||
'reponses.*' => [
|
||||
'required',
|
||||
'numeric',
|
||||
'exists:reponse_sondages,id',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) use ($responsesIds) {
|
||||
if (!in_array($value, $responsesIds)) {
|
||||
$fail(trans('Une des réponses fournis ne fait pas partie du sondage'));
|
||||
}
|
||||
}
|
||||
]
|
||||
];
|
||||
default:
|
||||
abort(500, 'Type de sondage non géré');
|
||||
}
|
||||
}
|
||||
}
|
||||
36
app/Http/Requests/StoreCrudModel.php
Normal file
36
app/Http/Requests/StoreCrudModel.php
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Enums\CrudAction;
|
||||
|
||||
class StoreCrudModel extends CrudRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
$model = $this->getCurrentModel();
|
||||
/** @var \App\Models\User|null $user */
|
||||
// $user = auth()->user();
|
||||
// return auth()->check() and $user->can('update', $model);
|
||||
$authorized = true;
|
||||
if ($authorized) {
|
||||
$this->rules = $this->getRulesForAction(CrudAction::create());
|
||||
}
|
||||
return $authorized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return $this->rules;
|
||||
}
|
||||
}
|
||||
36
app/Http/Requests/UpdateCrudModel.php
Normal file
36
app/Http/Requests/UpdateCrudModel.php
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Enums\CrudAction;
|
||||
|
||||
class UpdateCrudModel extends CrudRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
$model = $this->getCurrentModel();
|
||||
/** @var \App\Models\User|null $user */
|
||||
// $user = auth()->user();
|
||||
// return auth()->check() and $user->can('update', $model);
|
||||
$authorized = true;
|
||||
if ($authorized) {
|
||||
$this->rules = $this->getRulesForAction(CrudAction::update());
|
||||
}
|
||||
return $authorized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return $this->rules;
|
||||
}
|
||||
}
|
||||
19
app/Http/Requests/UpdateSondage.php
Normal file
19
app/Http/Requests/UpdateSondage.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
class UpdateSondage extends UpdateCrudModel
|
||||
{
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return array_merge($this->rules, [
|
||||
'reponses' => 'required|array',
|
||||
'reponses.*' => 'required|string|min:10',
|
||||
]);
|
||||
}
|
||||
}
|
||||
22
app/Http/Resources/CrudResource.php
Normal file
22
app/Http/Resources/CrudResource.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class CrudResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'label' => $this->crudLabel,
|
||||
'value' => $this->crudValue
|
||||
];
|
||||
}
|
||||
}
|
||||
177
app/Imports/EmployeeImport.php
Normal file
177
app/Imports/EmployeeImport.php
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
<?php
|
||||
|
||||
namespace App\Imports;
|
||||
|
||||
use App\Jobs\SendEmployeeCreatedAccountMail;
|
||||
use App\Models\Employee;
|
||||
use App\Models\EmployeeMailToken;
|
||||
use App\Models\Site;
|
||||
use Exception;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
use Maatwebsite\Excel\Concerns\Importable;
|
||||
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
|
||||
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
|
||||
|
||||
class EmployeeImport implements
|
||||
ToCollection,
|
||||
WithCustomCsvSettings,
|
||||
SkipsEmptyRows
|
||||
{
|
||||
use Importable;
|
||||
|
||||
/** @var \App\Models\Site */
|
||||
private $site;
|
||||
|
||||
/** @var array */
|
||||
private $headers;
|
||||
|
||||
public $updatedCount = 0;
|
||||
|
||||
public $importedCount = 0;
|
||||
|
||||
public $errorMessages = [];
|
||||
|
||||
public $importedFailed = [];
|
||||
|
||||
public function __construct(Site $site)
|
||||
{
|
||||
$this->site = $site;
|
||||
}
|
||||
|
||||
public function collection(Collection $rows)
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
/** @var \App\Models\Site */
|
||||
$site = Site::where('id', $user->selected_site_id)->firstOrFail();
|
||||
$cMAT = 0;
|
||||
$cNOM = 1;
|
||||
$cPRENOM = 2;
|
||||
$cMAIL = 3;
|
||||
|
||||
foreach ($rows as $k => $row) {
|
||||
$employee = Employee::where('matricule', $row[$cMAT])->firstOrNew();
|
||||
|
||||
if (!$this->validateRow($k, $row, $employee)) {
|
||||
$this->importedFailed[$k] = $row;
|
||||
continue;
|
||||
}
|
||||
$createdAccount = false;
|
||||
|
||||
// If employee exists but is in a different Site
|
||||
if (!is_null($employee->site) and $employee->site_id !== $site->id) {
|
||||
$this->setErrorMessages($k, [sprintf(
|
||||
'Le salariée %s %s %s existe déjà dans le site %s',
|
||||
$row[$cMAT],
|
||||
$row[$cNOM],
|
||||
$row[$cPRENOM],
|
||||
$site->name
|
||||
)]);
|
||||
$this->importedFailed[$k] = $row;
|
||||
}
|
||||
|
||||
// set fields
|
||||
$employee->fill([
|
||||
'matricule' => $row[$cMAT],
|
||||
'firstname' => $row[$cPRENOM],
|
||||
'lastname' => $row[$cNOM],
|
||||
'site_id' => $site->id,
|
||||
]);
|
||||
|
||||
if (!$employee->exists) {
|
||||
$createdAccount = true;
|
||||
}
|
||||
|
||||
$employee->email = $row[$cMAIL];
|
||||
// Anti date mdp
|
||||
$employee->password_date = Carbon::now()->subDay();
|
||||
$employee->password_attempts = 0;
|
||||
|
||||
try {
|
||||
$employee->saveOrFail();
|
||||
} catch (Exception $e) {
|
||||
$this->setErrorMessages($k, [sprintf(
|
||||
'Erreur %s',
|
||||
$e->getMessage()
|
||||
)]);
|
||||
$this->importedFailed[$k] = $row;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($createdAccount) {
|
||||
$this->importedCount += 1;
|
||||
if ($employee->hashcode) {
|
||||
$employee->hashcode->delete();
|
||||
}
|
||||
$employee->hashcode = new EmployeeMailToken([
|
||||
'email' => $employee->email,
|
||||
'employee_id' => $employee->id
|
||||
]);
|
||||
$employee->hashcode->saveOrFail();
|
||||
dispatch(new SendEmployeeCreatedAccountMail($employee))
|
||||
->onConnection('database');
|
||||
} else {
|
||||
$this->updatedCount += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getCsvSettings(): array
|
||||
{
|
||||
return [
|
||||
'input_encoding' => 'UTF-8',
|
||||
'delimiter' => ';'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate row
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $key
|
||||
* @param array $row
|
||||
* @return boolean
|
||||
*/
|
||||
private function validateRow(int $key, Collection $row, Employee $employee = null): bool
|
||||
{
|
||||
try {
|
||||
$unique = 'unique:employees,email';
|
||||
if ($employee->id) {
|
||||
$unique .= ",$employee->id";
|
||||
}
|
||||
Validator::make($row->all(), [
|
||||
'0' => 'required|digits_between:7,8',
|
||||
'1' => 'required|string',
|
||||
'2' => 'required|string',
|
||||
'3' => "required|$unique|email:rfc"
|
||||
], [], ['matricule', 'prénom', 'nom', 'email'])->validate();
|
||||
} catch (ValidationException $e) {
|
||||
$this->setErrorMessages($key, $e->errors());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set import error messages
|
||||
*
|
||||
* @param integer $row
|
||||
* @param array $messages
|
||||
* @return void
|
||||
*/
|
||||
public function setErrorMessages(int $row, array $messages): void
|
||||
{
|
||||
if (!isset($this->errorMessages[$row])) {
|
||||
$this->errorMessages[$row] = [];
|
||||
}
|
||||
$m1 = $this->errorMessages[$row];
|
||||
$m2 = collect($messages)->flatten()->all();
|
||||
array_merge_recursive_distinct($m1, $m2);
|
||||
$this->errorMessages[$row] = array_merge_recursive_distinct($m1, $m2);
|
||||
}
|
||||
}
|
||||
100
app/Imports/EmployeeSortie.php
Normal file
100
app/Imports/EmployeeSortie.php
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
namespace App\Imports;
|
||||
|
||||
use App\Models\Employee;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
use Maatwebsite\Excel\Concerns\Importable;
|
||||
use Maatwebsite\Excel\Concerns\SkipsOnFailure;
|
||||
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||
use Maatwebsite\Excel\Concerns\WithValidation;
|
||||
use Maatwebsite\Excel\Validators\Failure;
|
||||
|
||||
class EmployeeSortie implements ToCollection, WithCustomCsvSettings, WithValidation, WithHeadingRow, SkipsOnFailure
|
||||
{
|
||||
use Importable;
|
||||
|
||||
/** @var \App\Models\Site */
|
||||
private $site;
|
||||
|
||||
/** @var array */
|
||||
private $headers;
|
||||
|
||||
public $removedCount = 0;
|
||||
|
||||
public $importedFailed = [];
|
||||
|
||||
public $errorMessages = [];
|
||||
|
||||
public function __construct(Site $site)
|
||||
{
|
||||
$this->site = $site;
|
||||
}
|
||||
|
||||
public function collection(Collection $rows)
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
/** @var \App\Models\Site */
|
||||
$site = Site::where('id', $user->selected_site_id)->firstOrFail();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$employee = Employee::where('matricule', $row->get('matricule_sirh'))->first();
|
||||
if (!$employee) {
|
||||
$this->importedFailed[] = $row;
|
||||
Log::debug(sprintf('Employee Import Remove, skipped (Employee not found) %s', $row->implode(' | ')));
|
||||
continue;
|
||||
}
|
||||
if (!$row->get('date_fin_sirh')) {
|
||||
$this->importedFailed[] = $row;
|
||||
continue;
|
||||
}
|
||||
if (Carbon::createFromFormat('d/m/Y', $row->get('date_fin_sirh')) < Carbon::now()) {
|
||||
$employee->delete();
|
||||
$this->removedCount += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'matricule_sirh' => 'required|digits_between:7,8',
|
||||
'nom_sirh' => 'required|string',
|
||||
'prenom_sirh' => 'required|string',
|
||||
'date_fin_sirh' => 'required|string|date_format:d/m/Y',
|
||||
'societe_groupe' => 'required|integer',
|
||||
'libelle_societe_groupe' => 'required|string',
|
||||
'site_groupe' => 'required|integer',
|
||||
'libelle_site_groupe' => 'required|string'
|
||||
];
|
||||
}
|
||||
|
||||
public function getCsvSettings(): array
|
||||
{
|
||||
return [
|
||||
'input_encoding' => 'UTF-8',
|
||||
'delimiter' => ';'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Failure[] $failures
|
||||
*/
|
||||
public function onFailure(Failure ...$failures)
|
||||
{
|
||||
foreach ($failures as $failure) {
|
||||
$this->errorMessages[] = sprintf(
|
||||
"\nLigne %d :\n%s\nDonnée:\n%s\n",
|
||||
$failure->row(),
|
||||
\implode("\n", $failure->errors()),
|
||||
\implode(", ", $failure->values())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
139
app/Imports/PlanningImport.php
Normal file
139
app/Imports/PlanningImport.php
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
namespace App\Imports;
|
||||
|
||||
use App\Models\Employee;
|
||||
use App\Models\Planning as ModelsPlanning;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
use Maatwebsite\Excel\Concerns\Importable;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||
|
||||
class PlanningImport implements ToCollection, WithHeadingRow
|
||||
{
|
||||
use Importable;
|
||||
|
||||
/** @var \App\Models\Site */
|
||||
private $site;
|
||||
|
||||
/** @var string */
|
||||
private $title;
|
||||
|
||||
public $importedCount = 0;
|
||||
|
||||
public $importedFailed = [];
|
||||
|
||||
public function __construct(Site $site, array $headers)
|
||||
{
|
||||
$this->site = $site;
|
||||
$this->title = implode(collect($headers)->flatten()->all());
|
||||
}
|
||||
|
||||
public function collection(Collection $rows)
|
||||
{
|
||||
$dates = null;
|
||||
$planningLines = [];
|
||||
$k = -1;
|
||||
foreach ($rows as $row) {
|
||||
// concatenate all merged rows where 'nom_prenom' is null
|
||||
if (!is_null($row['nom_prenom'])) {
|
||||
$planningLines[++$k] = $row;
|
||||
} else {
|
||||
$planningLines[$k] = $planningLines[$k]->map(function ($item, $key) use ($row) {
|
||||
// ignore empty row titles
|
||||
if (!strlen($key)) {
|
||||
return false;
|
||||
}
|
||||
$d = $row->get($key);
|
||||
if ($d and is_string($d) and strlen($d)) {
|
||||
$item = strlen($item) ? sprintf('%s \n %s', $item, $d) : $d;
|
||||
}
|
||||
return $item;
|
||||
})->reject(function ($value) {
|
||||
return $value === false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$planningLines = collect($planningLines);
|
||||
|
||||
// Get Start and End dates
|
||||
$keys = collect(array_keys($planningLines->first()->all()));
|
||||
$startDate = collect(explode('_', $keys->get(1)));
|
||||
$endDate = collect(explode('_', $keys->last()));
|
||||
$validator = Validator::make([
|
||||
'startDay' => $startDate->first(),
|
||||
'start' => Carbon::createFromFormat('dmY', $startDate->last()),
|
||||
'endDay' => $endDate->first(),
|
||||
'end' => Carbon::createFromFormat('dmY', $endDate->last()),
|
||||
], [
|
||||
'startDay' => 'required|in:lundi,mardi,mercredi,jeudi,vendredi,samedi,dimanche',
|
||||
'start' => 'required|date',
|
||||
'endDay' => 'required|in:lundi,mardi,mercredi,jeudi,vendredi,samedi,dimanche',
|
||||
'end' => 'required|date',
|
||||
]);
|
||||
$validator->validate();
|
||||
$dates = (object)$validator->validated();
|
||||
|
||||
/**
|
||||
* Non mais bordel, déjà parser un xsls c'est de la merde
|
||||
* mais en plus de pas fournir de clé et en plus ne pas séparer
|
||||
* le nom et prénom, c'est vraiment WTF
|
||||
*/
|
||||
foreach ($planningLines as $line) {
|
||||
// Try to find employee with "nom_prenom", pfff
|
||||
$np = trim(preg_replace('/SST$/', '', $line['nom_prenom']));
|
||||
$ns = explode(' ', $np);
|
||||
$firstName = '';
|
||||
$lastName = '';
|
||||
$employee = null;
|
||||
do {
|
||||
$lastName = strlen($lastName) ?
|
||||
sprintf('%s %s', $lastName, \array_shift($ns)) : \array_shift($ns);
|
||||
$firstName = trim(implode(' ', $ns));
|
||||
$employee = Employee::where('site_id', $this->site->id)
|
||||
->whereRaw("UPPER(`lastname`) = '" . strtoupper($lastName) . "'")
|
||||
->whereRaw("UPPER(`firstname`) = '" . strtoupper($firstName) . "'")
|
||||
->get();
|
||||
// phpcs:ignore Squiz.PHP.DisallowSizeFunctionsInLoops.Found
|
||||
} while (strlen($firstName) and !count($employee) and count($ns) > 1);
|
||||
|
||||
if (!count($employee)) {
|
||||
$this->importedFailed[] = $line;
|
||||
Log::debug(sprintf('Planning Import, skipped (Employee not found) %s', $line->implode(' | ')));
|
||||
continue;
|
||||
}
|
||||
$line->forget('nom_prenom');
|
||||
$this->parsePlanningData($line);
|
||||
|
||||
// Get existing planning using start date or create a new one
|
||||
$planning = ModelsPlanning::whereDate('start', $dates->start->format('Y/m/d'))
|
||||
->where('employee_id', $employee->first()->id)->firstOrNew();
|
||||
$planning->fill([
|
||||
'start' => $dates->start,
|
||||
'end' => $dates->end,
|
||||
'data' => $line->all()
|
||||
]);
|
||||
$planning->employee_id = $employee->first()->id;
|
||||
$planning->saveOrFail();
|
||||
$this->importedCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
private function parsePlanningData(Collection &$data)
|
||||
{
|
||||
$data = $data->mapWithKeys(function ($day, $key) {
|
||||
$key = substr($key, strpos($key, '_') + 1);
|
||||
return ["$key" => $day];
|
||||
});
|
||||
}
|
||||
|
||||
public function headingRow(): int
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
48
app/Jobs/SendEmployeeCreatedAccountMail.php
Normal file
48
app/Jobs/SendEmployeeCreatedAccountMail.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Mail\EmployeeCreatedMail;
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class SendEmployeeCreatedAccountMail implements ShouldQueue
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var Employee */
|
||||
protected $employee;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Employee $employee)
|
||||
{
|
||||
$this->employee = $employee->withoutRelations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Mail::to(['email' => $this->employee->email])
|
||||
->send(new EmployeeCreatedMail($this->employee));
|
||||
Log::debug(sprintf('Sent %s to %s', EmployeeCreatedMail::class, $this->employee->email));
|
||||
}
|
||||
}
|
||||
50
app/Jobs/SendEmployeeInfoMailToSiteRH.php
Normal file
50
app/Jobs/SendEmployeeInfoMailToSiteRH.php
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class SendEmployeeInfoMailToSiteRH implements ShouldQueue
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var Mailable */
|
||||
protected $mail;
|
||||
|
||||
/** @var Employee */
|
||||
protected $employee;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Mailable $mail, Employee $employee)
|
||||
{
|
||||
$this->mail = $mail;
|
||||
$this->employee = $employee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Mail::to(['email' => $this->employee->site->email_contact])->send($this->mail);
|
||||
Log::debug(sprintf('Sent %s to %s', get_class($this->mail), $this->employee->site->email_contact));
|
||||
}
|
||||
}
|
||||
50
app/Jobs/SendEmployeeLockedDownMailToEmployee.php
Normal file
50
app/Jobs/SendEmployeeLockedDownMailToEmployee.php
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class SendEmployeeLockedDownMailToEmployee implements ShouldQueue
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var Mailable */
|
||||
protected $mail;
|
||||
|
||||
/** @var Employee */
|
||||
protected $employee;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Mailable $mail, Employee $employee)
|
||||
{
|
||||
$this->mail = $mail;
|
||||
$this->employee = $employee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Mail::to(['email' => $this->employee->email])->send($this->mail);
|
||||
Log::debug(sprintf('Sent %s to %s', get_class($this->mail), $this->employee->email));
|
||||
}
|
||||
}
|
||||
50
app/Jobs/SendEmployeeLockedDownMailToSiteRH.php
Normal file
50
app/Jobs/SendEmployeeLockedDownMailToSiteRH.php
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class SendEmployeeLockedDownMailToSiteRH implements ShouldQueue
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var Mailable */
|
||||
protected $mail;
|
||||
|
||||
/** @var Employee */
|
||||
protected $employee;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Mailable $mail, Employee $employee)
|
||||
{
|
||||
$this->mail = $mail;
|
||||
$this->employee = $employee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Mail::to(['email' => $this->employee->site->email_contact])->send($this->mail);
|
||||
Log::debug(sprintf('Sent %s to %s', get_class($this->mail), $this->employee->site->email_contact));
|
||||
}
|
||||
}
|
||||
45
app/Jobs/SendMailConfirmToEmployee.php
Normal file
45
app/Jobs/SendMailConfirmToEmployee.php
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Mail\EmployeeConfirmMail;
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class SendMailConfirmToEmployee implements ShouldQueue
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
protected $employee;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Employee $employee)
|
||||
{
|
||||
$this->employee = $employee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Mail::to(['email' => $this->employee->token->email])->send(new EmployeeConfirmMail($this->employee));
|
||||
Log::debug(sprintf('Sent %s to %s', EmployeeConfirmMail::class, config('mail.contactsList.contact')));
|
||||
}
|
||||
}
|
||||
45
app/Jobs/SendMailResetPasswordToEmployee.php
Normal file
45
app/Jobs/SendMailResetPasswordToEmployee.php
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Mail\EmployeePasswordResetMail;
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class SendMailResetPasswordToEmployee implements ShouldQueue
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
protected $employee;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Employee $employee)
|
||||
{
|
||||
$this->employee = $employee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Mail::to(['email' => $this->employee->token->email])->send(new EmployeePasswordResetMail($this->employee));
|
||||
Log::debug(sprintf('Sent %s to %s', EmployeePasswordResetMail::class, config('mail.contactsList.contact')));
|
||||
}
|
||||
}
|
||||
193
app/Jobs/XArcadiaFlux.php
Normal file
193
app/Jobs/XArcadiaFlux.php
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Enums\LogType;
|
||||
use Exception;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Filesystem\Filesystem;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
abstract class XArcadiaFlux implements ShouldQueue
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* The Laravel disk name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $disk = null;
|
||||
|
||||
/**
|
||||
* This is for Laravel Console usage
|
||||
*/
|
||||
public $console = null;
|
||||
|
||||
/**
|
||||
* The relative folder where to archive data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $archiveFolderName = 'archives';
|
||||
|
||||
/**
|
||||
* The files to ignore
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $ignoreFiles = [
|
||||
'.gitignore', '.gitkeep'
|
||||
];
|
||||
|
||||
/**
|
||||
* Check if the file extension
|
||||
*
|
||||
* @param string $filename
|
||||
* @return boolean
|
||||
*/
|
||||
protected function checkExtension(string $filename, string $extension): bool
|
||||
{
|
||||
$isExtension = strtolower(pathinfo($filename, \PATHINFO_EXTENSION)) === $extension;
|
||||
if (!$isExtension) {
|
||||
Log::warning(sprintf(
|
||||
'%s : unwanted file type in %s wanted %s',
|
||||
get_class($this),
|
||||
$filename,
|
||||
$extension
|
||||
));
|
||||
}
|
||||
return $isExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the file to archives
|
||||
*
|
||||
* @param string $filename
|
||||
* @return void
|
||||
*/
|
||||
protected function moveToArchives(string $filename): void
|
||||
{
|
||||
if (!$this->getDisk()->move($filename, sprintf('%s/%s', $this->archiveFolderName, $filename))) {
|
||||
$this->log(
|
||||
sprintf(
|
||||
'File %s could not be moved to archives',
|
||||
$filename
|
||||
),
|
||||
LogType::warning()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression des fichiers dans
|
||||
* archives qui ont plus de 2j
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function clearOldArchives(): void
|
||||
{
|
||||
$disk = $this->getDisk();
|
||||
$archives = $disk->files($this->archiveFolderName);
|
||||
|
||||
// /** @var File */
|
||||
foreach ($archives as $archive) {
|
||||
$pi = \pathinfo($archive, \PATHINFO_BASENAME);
|
||||
if (in_array($pi, $this->ignoreFiles)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($disk->lastModified($archive) < strtotime(Carbon::now()->subDays(2))) {
|
||||
if (!$disk->delete($archive)) {
|
||||
Log::critical(sprintf('%s : Could not delete file %s', get_class($this), $archive));
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the concerned disk
|
||||
*
|
||||
* @return Filesystem
|
||||
*/
|
||||
protected function getDisk(): Filesystem
|
||||
{
|
||||
return Storage::disk($this->disk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs data
|
||||
*
|
||||
* @param string $message
|
||||
* @param LogType $logtype
|
||||
* @return void
|
||||
*/
|
||||
protected function log(string $message, LogType $logtype = null): void
|
||||
{
|
||||
if (!$logtype) {
|
||||
$logtype = LogType::debug();
|
||||
}
|
||||
$message = sprintf('%s : %s', get_class($this), $message);
|
||||
switch ($logtype->value) {
|
||||
case LogType::debug()->value:
|
||||
Log::debug($message);
|
||||
break;
|
||||
case LogType::info()->value:
|
||||
Log::info($message);
|
||||
break;
|
||||
case LogType::log()->value:
|
||||
Log::log($message);
|
||||
break;
|
||||
case LogType::warning()->value:
|
||||
Log::warning($message);
|
||||
break;
|
||||
case LogType::error()->value:
|
||||
Log::error($message);
|
||||
break;
|
||||
case LogType::critical()->value:
|
||||
Log::critical($message);
|
||||
break;
|
||||
default:
|
||||
throw new Exception(sprintf('%s : unhandled log type %s', get_class($this), $logtype->label));
|
||||
}
|
||||
$this->consolePrint($message, $logtype);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints to the console
|
||||
*
|
||||
* @param string $message
|
||||
* @param LogType $logtype
|
||||
* @return void
|
||||
*/
|
||||
protected function consolePrint(string $message, LogType $logtype): void
|
||||
{
|
||||
if ($this->console) {
|
||||
switch ($logtype->value) {
|
||||
case LogType::debug()->value:
|
||||
case LogType::info()->value:
|
||||
case LogType::log()->value:
|
||||
$this->console->info($message);
|
||||
break;
|
||||
case LogType::warning()->value:
|
||||
$this->console->comment($message);
|
||||
break;
|
||||
case LogType::error()->value:
|
||||
case LogType::critical()->value:
|
||||
$this->console->error($message);
|
||||
break;
|
||||
default:
|
||||
throw new Exception(sprintf('%s : unhandled log type %s', get_class($this), $logtype->label));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
160
app/Jobs/XSCVMepReader.php
Normal file
160
app/Jobs/XSCVMepReader.php
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Enums\LogType;
|
||||
use App\Exceptions\AbortCsvImportException;
|
||||
use App\Exceptions\AbortRowImportException;
|
||||
use App\Mail\OcbMissingBreederReminder;
|
||||
use App\Models\OCBBreeder;
|
||||
use App\Models\OCBWaitingList;
|
||||
use App\Models\XmlBreeder;
|
||||
use ErrorException;
|
||||
use Illuminate\Support\Carbon;
|
||||
use League\Csv\Reader;
|
||||
use TypeError;
|
||||
|
||||
class XSCVMepReader extends XArcadiaFlux
|
||||
{
|
||||
|
||||
/**
|
||||
* The Laravel disk name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $disk = 'mise_en_place';
|
||||
|
||||
protected $expectedArray = [
|
||||
"No Eleveur",
|
||||
"Code mise en place LDC",
|
||||
"Opa",
|
||||
"Vivant",
|
||||
"Numero semaine de sortie",
|
||||
"Quantite Initiale",
|
||||
"Date mise en place",
|
||||
"Couvoir",
|
||||
"Code Lot OPA",
|
||||
"Nombre de volaille mises en place",
|
||||
"Quantite Nouvelle",
|
||||
"Libelle Opa",
|
||||
"Libelle Vivant",
|
||||
"Nom Prenom Eleveur",
|
||||
"Code Société",
|
||||
"Nom Société"
|
||||
];
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
/** @var Filesystem */
|
||||
$disk = $this->getDisk();
|
||||
$this->log('Démarrage du traitement');
|
||||
$files = $disk->files();
|
||||
|
||||
$progress = 1;
|
||||
$total = count(array_filter($files, function ($filename) {
|
||||
if ($this->fileHasToBeIgnored($filename)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
|
||||
foreach ($files as $filename) {
|
||||
if ($this->fileHasToBeIgnored($filename)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->log(sprintf(' traitement %d sur %s ', $progress++, $total));
|
||||
|
||||
/** @var string $data */
|
||||
$data = $disk->get($filename);
|
||||
|
||||
//load the CSV document from a file path
|
||||
$csv = Reader::createFromString($data);
|
||||
$csv->setDelimiter(';');
|
||||
$csv->setHeaderOffset(0);
|
||||
|
||||
$header = $csv->getHeader();
|
||||
$records = $csv->getRecords();
|
||||
|
||||
try {
|
||||
$this->assertHeaderIsAsExpected($header);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$noElev = $record['No Eleveur'];
|
||||
$inuav = substr($noElev, strlen($noElev) - 7, strlen($noElev));
|
||||
// Check if inuav exists
|
||||
if (!OCBBreeder::where('inuavs', 'LIKE', sprintf('%%s%', $inuav))->count()) {
|
||||
$iWL = OCBWaitingList::where('inuav_code', $inuav)->firstOrNew();
|
||||
$iWL->inuav_code = $inuav;
|
||||
|
||||
$NP = explode(' ', $record['Nom Prenom Eleveur'], 2);
|
||||
|
||||
// try to find more info with xml_breeders
|
||||
$xmlBreeder = XmlBreeder::where('inuav_code', $inuav)->first();
|
||||
|
||||
$iWL->fill([
|
||||
'date_mep' => Carbon::createFromFormat('d/m/Y', $record['Date mise en place'])
|
||||
->toDateTimeString(),
|
||||
'last_name' => $NP[0],
|
||||
'first_name' => $NP[1],
|
||||
'cp' => $xmlBreeder->postal_code ?? '',
|
||||
'city' => $xmlBreeder->city ?? '',
|
||||
'inuav' => $inuav
|
||||
]);
|
||||
$iWL->save();
|
||||
}
|
||||
}
|
||||
} catch (ErrorException | TypeError $e) {
|
||||
$this->log(
|
||||
sprintf(
|
||||
'File %s could not be parsed => %s on line %d',
|
||||
$filename,
|
||||
$e->getMessage(),
|
||||
$e->getLine()
|
||||
),
|
||||
LogType::critical()
|
||||
);
|
||||
continue; // ignore the file
|
||||
} catch (AbortCsvImportException $e) {
|
||||
$this->log(
|
||||
sprintf(
|
||||
'File %s could not be parsed => %s on line %d',
|
||||
$filename,
|
||||
$e->getMessage(),
|
||||
$e->getLine()
|
||||
),
|
||||
LogType::error()
|
||||
);
|
||||
continue; // ignore the file
|
||||
}
|
||||
|
||||
$this->moveToArchives($filename);
|
||||
}
|
||||
|
||||
// Clear old archives
|
||||
$this->clearOldArchives();
|
||||
}
|
||||
|
||||
protected function assertHeaderIsAsExpected(array $header)
|
||||
{
|
||||
if ($this->expectedArray !== $header) {
|
||||
throw new AbortRowImportException(trans('CSV Header does not match expected'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the file to be ignored
|
||||
*
|
||||
* @param string $filename
|
||||
* @return boolean
|
||||
*/
|
||||
protected function fileHasToBeIgnored(string $filename): bool
|
||||
{
|
||||
return in_array($filename, $this->ignoreFiles) or !$this->checkExtension($filename, 'csv');
|
||||
}
|
||||
}
|
||||
33
app/Jobs/XmlEleveursReader.php
Normal file
33
app/Jobs/XmlEleveursReader.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\XmlBreeder;
|
||||
|
||||
class XmlEleveursReader extends XmlJobs
|
||||
{
|
||||
|
||||
protected $disk = 'eleveurs';
|
||||
|
||||
protected $takeColumns = [
|
||||
'codeopa.Nom' => 'opa_nom',
|
||||
'codeopa.code' => 'opa_code',
|
||||
'NomEleveur' => 'last_name',
|
||||
'CodeEleveur' => 'inuav_code',
|
||||
'Prenom' => 'first_name',
|
||||
'code' => 'unique_key',
|
||||
'codePostal' => 'postal_code',
|
||||
'Ville' => 'city',
|
||||
'LongitudeGps' => 'longitude',
|
||||
'LatitudeGps' => 'latitude'
|
||||
];
|
||||
|
||||
protected $nullableFields = ['longitude', 'latitude'];
|
||||
|
||||
protected $uniqueKeyField = ['unique_key', 'inuav_code'];
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$this->parseData('ELEVEURS', XmlBreeder::class);
|
||||
}
|
||||
}
|
||||
280
app/Jobs/XmlJobs.php
Normal file
280
app/Jobs/XmlJobs.php
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Enums\LogType;
|
||||
use App\Exceptions\AbortXmlImportException;
|
||||
use ErrorException;
|
||||
use Illuminate\Contracts\Filesystem\Filesystem;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Str;
|
||||
use RecursiveArrayIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use SimpleXMLElement;
|
||||
use TypeError;
|
||||
|
||||
abstract class XmlJobs extends XArcadiaFlux
|
||||
{
|
||||
|
||||
/**
|
||||
* The columns to take from the XML
|
||||
* subcolumns can be added with a dot
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $takeColumns = [];
|
||||
|
||||
/**
|
||||
* The columns allowed to be null
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $nullableFields = [];
|
||||
|
||||
/**
|
||||
* Need to encapsulate the freeking XML
|
||||
* Because provided one is dirty
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $encapsulate = false;
|
||||
|
||||
/**
|
||||
* Parse Data from the XML and gives it to the callback
|
||||
*
|
||||
* @param string $entityName
|
||||
* @param string $modelClass
|
||||
* @return void
|
||||
*/
|
||||
// phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
protected function parseData(string $entityName, string $modelClass, callable $callback = null): void
|
||||
{
|
||||
/** @var Filesystem */
|
||||
$disk = $this->getDisk();
|
||||
$this->log('Démarrage du traitement');
|
||||
$files = $disk->files();
|
||||
|
||||
$progress = 1;
|
||||
$total = count(array_filter($files, function ($filename) {
|
||||
if ($this->fileHasToBeIgnored($filename)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
|
||||
foreach ($files as $filename) {
|
||||
if ($this->fileHasToBeIgnored($filename)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->log(sprintf(' traitement %d sur %s ', $progress++, $total));
|
||||
|
||||
/** @var string $data */
|
||||
$data = $disk->get($filename);
|
||||
|
||||
try {
|
||||
if ($this->encapsulate) {
|
||||
$data = sprintf('<Root>%s</Root>', $data);
|
||||
/** @var SimpleXMLElement|false */
|
||||
$xmlContent = simplexml_load_string($data);
|
||||
} else {
|
||||
/** @var SimpleXMLElement|false */
|
||||
$xmlContent = simplexml_load_string($data, null, LIBXML_NOCDATA | LIBXML_PARSEHUGE);
|
||||
}
|
||||
|
||||
if ($xmlContent === false) {
|
||||
$this->log(
|
||||
sprintf('File %s could not be parsed (simplexml_load_string)', $filename),
|
||||
LogType::critical()
|
||||
);
|
||||
continue; // ignore the file
|
||||
}
|
||||
|
||||
$data = $this->extract($xmlContent);
|
||||
|
||||
|
||||
$lines = [];
|
||||
|
||||
foreach ($data[$entityName] as $traca) {
|
||||
$line = $this->processFields($traca);
|
||||
if ($callback) {
|
||||
$callback($xmlContent, $line);
|
||||
}
|
||||
$lines[] = $line;
|
||||
}
|
||||
|
||||
// Mise en base des données
|
||||
foreach ($lines as $line) {
|
||||
/** @var array Unique Key columns */
|
||||
$uniqueColumnsKey = [];
|
||||
foreach ($this->uniqueKeyField as $uField) {
|
||||
$uniqueColumnsKey[$uField] = $line[$uField];
|
||||
}
|
||||
forward_static_call_array(
|
||||
[$modelClass, 'updateOrCreate'],
|
||||
[$uniqueColumnsKey, $line]
|
||||
);
|
||||
}
|
||||
} catch (ErrorException | TypeError | QueryException $e) {
|
||||
$message = $e->getMessage();
|
||||
if (get_class($e) === QueryException::class) {
|
||||
$message = implode(' ', $e->errorInfo);
|
||||
}
|
||||
$this->log(
|
||||
sprintf(
|
||||
'File %s could not be parsed => %s on line %d',
|
||||
$filename,
|
||||
$message,
|
||||
$e->getLine()
|
||||
),
|
||||
LogType::critical()
|
||||
);
|
||||
continue; // ignore the file
|
||||
} catch (AbortXmlImportException $e) {
|
||||
$this->log(
|
||||
sprintf(
|
||||
'File %s could not be parsed => %s on line %d',
|
||||
$filename,
|
||||
$e->getMessage(),
|
||||
$e->getLine()
|
||||
),
|
||||
LogType::error()
|
||||
);
|
||||
continue; // ignore the file
|
||||
}
|
||||
|
||||
$this->moveToArchives($filename);
|
||||
}
|
||||
|
||||
// Clear old archives
|
||||
$this->clearOldArchives();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive extract to array
|
||||
*
|
||||
* @param \SimpleXMLElement|false $sxe
|
||||
* @return array
|
||||
*/
|
||||
protected function extract($sxe = null): array
|
||||
{
|
||||
if (!$sxe instanceof SimpleXMLElement) {
|
||||
return array();
|
||||
}
|
||||
$extract = array();
|
||||
foreach ($sxe->children() as $key => $value) {
|
||||
if ($value->count()) {
|
||||
$extract[$key][] = $this->extract($value);
|
||||
continue;
|
||||
}
|
||||
$value = strval($value);
|
||||
if (array_key_exists($key, $extract) and is_array($extract[$key])) {
|
||||
$extract[$key][] = strlen($value) ? $value : null;
|
||||
} else {
|
||||
$extract[$key] = strlen($value) ? $value : null;
|
||||
}
|
||||
}
|
||||
return $extract;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process fields to gather data
|
||||
*
|
||||
* @param array $fields
|
||||
* @return array
|
||||
* @throws AbortXmlImportException
|
||||
*/
|
||||
protected function processFields(array $fields): array
|
||||
{
|
||||
$result = [];
|
||||
foreach ($fields as $key => $field) {
|
||||
if (!($key = $this->shouldFieldBeConsidered($key))) {
|
||||
continue;
|
||||
}
|
||||
if (!$this->isFieldNullable($key) && is_null($field)) {
|
||||
throw new AbortXmlImportException(sprintf('The field %s is not allowed to be null', $key));
|
||||
}
|
||||
if (is_array($field)) {
|
||||
// Flatten data
|
||||
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($field));
|
||||
foreach ($it as $k => $f) {
|
||||
$ko = strtolower(sprintf('%s.%s', $key, $k));
|
||||
if (!$this->isFieldNullable($ko) && is_null($f)) {
|
||||
throw new AbortXmlImportException(sprintf(
|
||||
'%s : The field %s is not allowed to be null',
|
||||
get_class($this),
|
||||
$ko
|
||||
));
|
||||
}
|
||||
if (!($k = $this->shouldFieldBeConsidered($ko))) {
|
||||
continue;
|
||||
}
|
||||
$result[$k] = $f;
|
||||
}
|
||||
} else {
|
||||
$result[$key] = $field;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the filed nullable
|
||||
*
|
||||
* @param string $key
|
||||
* @return boolean
|
||||
*/
|
||||
private function isFieldNullable(string $key): bool
|
||||
{
|
||||
if (in_array($key, $this->nullableFields)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* - replace key name with the corresponding alias
|
||||
* - strtolower the key
|
||||
* - snake_case the key
|
||||
*
|
||||
* @param string $key
|
||||
* @return string|false
|
||||
*/
|
||||
private function shouldFieldBeConsidered(string $key)
|
||||
{
|
||||
$key = strtolower($key);
|
||||
foreach ($this->takeColumns as $k => $alias) {
|
||||
if (strtolower($k) === $key) {
|
||||
return Str::snake(strtolower($alias));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the file to be ignored
|
||||
*
|
||||
* @param string $filename
|
||||
* @return boolean
|
||||
*/
|
||||
protected function fileHasToBeIgnored(string $filename): bool
|
||||
{
|
||||
return in_array($filename, $this->ignoreFiles) or !$this->checkExtension($filename, 'xml');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the file is an xml file
|
||||
*
|
||||
* @param string $filename
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isFileXml(string $filename): bool
|
||||
{
|
||||
$isXml = strtolower(pathinfo($filename, \PATHINFO_EXTENSION)) === 'xml';
|
||||
if (!$isXml) {
|
||||
Log::warning(sprintf('%s : unwanted file type in %s', get_class($this), $filename));
|
||||
}
|
||||
return $isXml;
|
||||
}
|
||||
}
|
||||
104
app/Lib/PolicySystem/RootPolicy.php
Normal file
104
app/Lib/PolicySystem/RootPolicy.php
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace App\Lib\PolicySystem;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Lib\PolicySystem\StaticRules as SR;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class RootPolicy
|
||||
{
|
||||
|
||||
protected $policy = null;
|
||||
|
||||
protected $policies = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$cls = \explode('\\', \get_called_class());
|
||||
$this->policy = \strtolower(\str_replace('Policy', '', \end($cls)));
|
||||
}
|
||||
|
||||
protected function actionPolicy(string $method, string $policy, User $user, Model $model = null)
|
||||
{
|
||||
$this->setPolicies($user, $model);
|
||||
$ctx = [$policy, $user, $model];
|
||||
|
||||
if (!$this->hasPolicy($policy)) {
|
||||
$m = __('Unhandled policy ":policy"', ['policy' => $policy]);
|
||||
Log::critical($m, $ctx);
|
||||
return $this->deny($m);
|
||||
}
|
||||
|
||||
if (!is_array($this->policies[$policy])) {
|
||||
$m = __('Policy ":policy" has to be array', ['policy' => $policy]);
|
||||
Log::critical($m, $ctx);
|
||||
return $this->deny($m);
|
||||
}
|
||||
|
||||
// Policy method exists
|
||||
if (!array_key_exists($method, $this->policies[$policy])) {
|
||||
$m = __('Unhandled policy ":policy" for action ":action"', ['policy' => $policy, 'action' => $method]);
|
||||
Log::critical($m, $ctx);
|
||||
return $this->deny($m);
|
||||
}
|
||||
|
||||
// Call policy method
|
||||
if (Sr::handle($this->policies[$policy][$method], $user, $model)) {
|
||||
return $this->allow();
|
||||
} else {
|
||||
$m = __('Policy ":policy" for action ":action" denied :onmodel', [
|
||||
'policy' => $policy,
|
||||
'action' => $method,
|
||||
'onmodel' => $model ? get_class($model) : ''
|
||||
]);
|
||||
Log::debug(sprintf("%s user => %s model => %s", $m, $user, $model), $ctx);
|
||||
return $this->deny($m);
|
||||
}
|
||||
|
||||
$m = __('Unhandled policy case on resource ":method"', ['method' => $method]);
|
||||
Log::critical($m, $ctx);
|
||||
return $this->deny();
|
||||
}
|
||||
|
||||
/**
|
||||
** Do the magic calling Root policy from any policy
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
return call_user_func_array([$this, 'actionPolicy'], array_merge([$method, $this->policy], $args));
|
||||
}
|
||||
|
||||
private function hasPolicy(string $policy)
|
||||
{
|
||||
return array_key_exists($policy, $this->policies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow action for the user
|
||||
*
|
||||
* @param string|null $message
|
||||
* @return \Illuminate\Auth\Access\Response
|
||||
*/
|
||||
protected function allow(?string $message = null)
|
||||
{
|
||||
return Response::allow($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deny action for the user
|
||||
*
|
||||
* @param string|null $message
|
||||
* @param mixed $code
|
||||
* @return \Illuminate\Auth\Access\Response
|
||||
*/
|
||||
protected function deny(?string $message = null, $code = null)
|
||||
{
|
||||
if (!$message) {
|
||||
$message = __('This action is not allowed to you for this resource.');
|
||||
}
|
||||
return Response::deny($message, $code);
|
||||
}
|
||||
}
|
||||
86
app/Lib/PolicySystem/StaticRules.php
Normal file
86
app/Lib/PolicySystem/StaticRules.php
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
namespace App\Lib\PolicySystem;
|
||||
|
||||
use App\Models\User;
|
||||
use Exception;
|
||||
use Closure;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Generic Policiy Static Rules
|
||||
*! Rules has to return boolean value
|
||||
*/
|
||||
abstract class StaticRules
|
||||
{
|
||||
/**
|
||||
* Make a rule closure
|
||||
*
|
||||
* @param string $rulename
|
||||
* @param mixed ...$args
|
||||
* @return Closure
|
||||
*/
|
||||
public static function make(string $rulename, ...$args)
|
||||
{
|
||||
if (!method_exists(static::class, $rulename)) {
|
||||
throw new Exception(sprintf('Unknown rule %s in Policies StaticRules', $rulename));
|
||||
}
|
||||
return function () use ($rulename, $args) {
|
||||
return call_user_func_array([static::class, $rulename], $args);
|
||||
};
|
||||
}
|
||||
|
||||
public static function and(array $ruleClosures)
|
||||
{
|
||||
return function (User $user, Model $model = null) use ($ruleClosures) {
|
||||
$nbRules = count($ruleClosures);
|
||||
$out = true;
|
||||
$i = 0;
|
||||
do {
|
||||
if (!($out = (self::handle($ruleClosures[$i++], $user, $model) && $out))) {
|
||||
break;
|
||||
}
|
||||
} while ($i < $nbRules);
|
||||
return $out;
|
||||
};
|
||||
}
|
||||
|
||||
public static function or(array $ruleClosures)
|
||||
{
|
||||
return function (User $user, Model $model = null) use ($ruleClosures) {
|
||||
$nbRules = count($ruleClosures);
|
||||
$out = false;
|
||||
$i = 0;
|
||||
do {
|
||||
if ($out = (self::handle($ruleClosures[$i++], $user, $model) || $out)) {
|
||||
break;
|
||||
}
|
||||
} while ($i < $nbRules);
|
||||
return $out;
|
||||
};
|
||||
}
|
||||
|
||||
public static function handle($rule, User $user, Model $model = null)
|
||||
{
|
||||
if (is_array($rule)) {
|
||||
$nbRule = count($rule);
|
||||
$out = false;
|
||||
$i = 0;
|
||||
while ($i < $nbRule) {
|
||||
if ($out = self::handle($rule[$i++], $user, $model)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
if (!is_callable($rule)) {
|
||||
throw new Exception('Rule has to ba callable.');
|
||||
}
|
||||
return (bool)$rule($user, $model);
|
||||
}
|
||||
|
||||
protected static function anyone()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
104
app/Lib/Utils.php
Normal file
104
app/Lib/Utils.php
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace App\Lib;
|
||||
|
||||
// phpcs:disable Generic.Files.LineLength.TooLong
|
||||
class Utils
|
||||
{
|
||||
/**
|
||||
* Replace stange accents
|
||||
*
|
||||
* https://stackoverflow.com/questions/3371697/replacing-accented-characters-php
|
||||
* @author Jérémy Munsch <jeremy.munsch@jeremydev.ovh>
|
||||
* @param string $subject
|
||||
* @return string
|
||||
*/
|
||||
public static function replaceSpecChar(string $subject): string
|
||||
{
|
||||
$char_map = array(
|
||||
"ъ" => "-", "ь" => "-", "Ъ" => "-", "Ь" => "-",
|
||||
"А" => "A", "Ă" => "A", "Ǎ" => "A", "Ą" => "A", "À" => "A", "Ã" => "A", "Á" => "A", "Æ" => "A", "Â" => "A", "Å" => "A", "Ǻ" => "A", "Ā" => "A", "א" => "A",
|
||||
"Б" => "B", "ב" => "B", "Þ" => "B",
|
||||
"Ĉ" => "C", "Ć" => "C", "Ç" => "C", "Ц" => "C", "צ" => "C", "Ċ" => "C", "Č" => "C", "©" => "C", "ץ" => "C",
|
||||
"Д" => "D", "Ď" => "D", "Đ" => "D", "ד" => "D", "Ð" => "D",
|
||||
"È" => "E", "Ę" => "E", "É" => "E", "Ë" => "E", "Ê" => "E", "Е" => "E", "Ē" => "E", "Ė" => "E", "Ě" => "E", "Ĕ" => "E", "Є" => "E", "Ə" => "E", "ע" => "E",
|
||||
"Ф" => "F", "Ƒ" => "F",
|
||||
"Ğ" => "G", "Ġ" => "G", "Ģ" => "G", "Ĝ" => "G", "Г" => "G", "ג" => "G", "Ґ" => "G",
|
||||
"ח" => "H", "Ħ" => "H", "Х" => "H", "Ĥ" => "H", "ה" => "H",
|
||||
"I" => "I", "Ï" => "I", "Î" => "I", "Í" => "I", "Ì" => "I", "Į" => "I", "Ĭ" => "I", "I" => "I", "И" => "I", "Ĩ" => "I", "Ǐ" => "I", "י" => "I", "Ї" => "I", "Ī" => "I", "І" => "I",
|
||||
"Й" => "J", "Ĵ" => "J",
|
||||
"ĸ" => "K", "כ" => "K", "Ķ" => "K", "К" => "K", "ך" => "K",
|
||||
"Ł" => "L", "Ŀ" => "L", "Л" => "L", "Ļ" => "L", "Ĺ" => "L", "Ľ" => "L", "ל" => "L",
|
||||
"מ" => "M", "М" => "M", "ם" => "M",
|
||||
"Ñ" => "N", "Ń" => "N", "Н" => "N", "Ņ" => "N", "ן" => "N", "Ŋ" => "N", "נ" => "N", "ʼn" => "N", "Ň" => "N",
|
||||
"Ø" => "O", "Ó" => "O", "Ò" => "O", "Ô" => "O", "Õ" => "O", "О" => "O", "Ő" => "O", "Ŏ" => "O", "Ō" => "O", "Ǿ" => "O", "Ǒ" => "O", "Ơ" => "O",
|
||||
"פ" => "P", "ף" => "P", "П" => "P",
|
||||
"ק" => "Q",
|
||||
"Ŕ" => "R", "Ř" => "R", "Ŗ" => "R", "ר" => "R", "Р" => "R", "®" => "R",
|
||||
"Ş" => "S", "Ś" => "S", "Ș" => "S", "Š" => "S", "С" => "S", "Ŝ" => "S", "ס" => "S",
|
||||
"Т" => "T", "Ț" => "T", "ט" => "T", "Ŧ" => "T", "ת" => "T", "Ť" => "T", "Ţ" => "T",
|
||||
"Ù" => "U", "Û" => "U", "Ú" => "U", "Ū" => "U", "У" => "U", "Ũ" => "U", "Ư" => "U", "Ǔ" => "U", "Ų" => "U", "Ŭ" => "U", "Ů" => "U", "Ű" => "U", "Ǖ" => "U", "Ǜ" => "U", "Ǚ" => "U", "Ǘ" => "U",
|
||||
"В" => "V", "ו" => "V",
|
||||
"Ý" => "Y", "Ы" => "Y", "Ŷ" => "Y", "Ÿ" => "Y",
|
||||
"Ź" => "Z", "Ž" => "Z", "Ż" => "Z", "З" => "Z", "ז" => "Z",
|
||||
"а" => "a", "ă" => "a", "ǎ" => "a", "ą" => "a", "à" => "a", "ã" => "a", "á" => "a", "æ" => "a", "â" => "a", "å" => "a", "ǻ" => "a", "ā" => "a", "א" => "a",
|
||||
"б" => "b", "ב" => "b", "þ" => "b",
|
||||
"ĉ" => "c", "ć" => "c", "ç" => "c", "ц" => "c", "צ" => "c", "ċ" => "c", "č" => "c", "©" => "c", "ץ" => "c",
|
||||
"Ч" => "ch", "ч" => "ch",
|
||||
"д" => "d", "ď" => "d", "đ" => "d", "ד" => "d", "ð" => "d",
|
||||
"è" => "e", "ę" => "e", "é" => "e", "ë" => "e", "ê" => "e", "е" => "e", "ē" => "e", "ė" => "e", "ě" => "e", "ĕ" => "e", "є" => "e", "ə" => "e", "ע" => "e",
|
||||
"ф" => "f", "ƒ" => "f",
|
||||
"ğ" => "g", "ġ" => "g", "ģ" => "g", "ĝ" => "g", "г" => "g", "ג" => "g", "ґ" => "g",
|
||||
"ח" => "h", "ħ" => "h", "х" => "h", "ĥ" => "h", "ה" => "h",
|
||||
"i" => "i", "ï" => "i", "î" => "i", "í" => "i", "ì" => "i", "į" => "i", "ĭ" => "i", "ı" => "i", "и" => "i", "ĩ" => "i", "ǐ" => "i", "י" => "i", "ї" => "i", "ī" => "i", "і" => "i",
|
||||
"й" => "j", "Й" => "j", "Ĵ" => "j", "ĵ" => "j",
|
||||
"ĸ" => "k", "כ" => "k", "ķ" => "k", "к" => "k", "ך" => "k",
|
||||
"ł" => "l", "ŀ" => "l", "л" => "l", "ļ" => "l", "ĺ" => "l", "ľ" => "l", "ל" => "l",
|
||||
"מ" => "m", "м" => "m", "ם" => "m",
|
||||
"ñ" => "n", "ń" => "n", "н" => "n", "ņ" => "n", "ן" => "n", "ŋ" => "n", "נ" => "n", "ʼn" => "n", "ň" => "n",
|
||||
"ø" => "o", "ó" => "o", "ò" => "o", "ô" => "o", "õ" => "o", "о" => "o", "ő" => "o", "ŏ" => "o", "ō" => "o", "ǿ" => "o", "ǒ" => "o", "ơ" => "o",
|
||||
"פ" => "p", "ף" => "p", "п" => "p",
|
||||
"ק" => "q",
|
||||
"ŕ" => "r", "ř" => "r", "ŗ" => "r", "ר" => "r", "р" => "r", "®" => "r",
|
||||
"ş" => "s", "ś" => "s", "ș" => "s", "š" => "s", "с" => "s", "ŝ" => "s", "ס" => "s",
|
||||
"т" => "t", "ț" => "t", "ט" => "t", "ŧ" => "t", "ת" => "t", "ť" => "t", "ţ" => "t",
|
||||
"ù" => "u", "û" => "u", "ú" => "u", "ū" => "u", "у" => "u", "ũ" => "u", "ư" => "u", "ǔ" => "u", "ų" => "u", "ŭ" => "u", "ů" => "u", "ű" => "u", "ǖ" => "u", "ǜ" => "u", "ǚ" => "u", "ǘ" => "u",
|
||||
"в" => "v", "ו" => "v",
|
||||
"ý" => "y", "ы" => "y", "ŷ" => "y", "ÿ" => "y",
|
||||
"ź" => "z", "ž" => "z", "ż" => "z", "з" => "z", "ז" => "z", "ſ" => "z",
|
||||
"™" => "tm",
|
||||
"@" => "at",
|
||||
"Ä" => "ae", "Ǽ" => "ae", "ä" => "ae", "æ" => "ae", "ǽ" => "ae",
|
||||
"ij" => "ij", "IJ" => "ij",
|
||||
"я" => "ja", "Я" => "ja",
|
||||
"Э" => "je", "э" => "je",
|
||||
"ё" => "jo", "Ё" => "jo",
|
||||
"ю" => "ju", "Ю" => "ju",
|
||||
"œ" => "oe", "Œ" => "oe", "ö" => "oe", "Ö" => "oe",
|
||||
"щ" => "sch", "Щ" => "sch",
|
||||
"ш" => "sh", "Ш" => "sh",
|
||||
"ß" => "ss",
|
||||
"Ü" => "ue",
|
||||
"Ж" => "zh", "ж" => "zh",
|
||||
);
|
||||
return self::mbStrtr($subject, $char_map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multibyte strtr
|
||||
*
|
||||
* @param string $str
|
||||
* @param string|array $from
|
||||
* @param string|null $to
|
||||
* @return void
|
||||
*/
|
||||
public static function mbStrtr($str, $from, $to = null)
|
||||
{
|
||||
if (is_array($from)) {
|
||||
$from = array_map('utf8_decode', $from);
|
||||
$from = array_map('utf8_decode', array_flip($from));
|
||||
return utf8_encode(strtr(utf8_decode($str), array_flip($from)));
|
||||
}
|
||||
return utf8_encode(strtr(utf8_decode($str), utf8_decode($from), utf8_decode($to)));
|
||||
}
|
||||
}
|
||||
40
app/Mail/EmployeeConfirmMail.php
Normal file
40
app/Mail/EmployeeConfirmMail.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class EmployeeConfirmMail extends Mailable
|
||||
{
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
protected $employee;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Employee $employee)
|
||||
{
|
||||
$this->employee = $employee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this
|
||||
->subject(sprintf('%s : Veuillez confirmer votre adresse email', config('app.name')))
|
||||
->view('emails.mail-confirm')
|
||||
->text('emails.mail-confirm-plain')
|
||||
->with('employee', $this->employee);
|
||||
}
|
||||
}
|
||||
36
app/Mail/EmployeeCreatedMail.php
Normal file
36
app/Mail/EmployeeCreatedMail.php
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Mail\Mailable;
|
||||
|
||||
class EmployeeCreatedMail extends Mailable
|
||||
{
|
||||
|
||||
protected $employee;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Employee $employee)
|
||||
{
|
||||
$this->employee = $employee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this
|
||||
->subject(sprintf('%s : Un compte viens de vous être créé', config('app.name')))
|
||||
->view('emails.mail-created')
|
||||
->text('emails.mail-created-plain')
|
||||
->with('employee', $this->employee);
|
||||
}
|
||||
}
|
||||
53
app/Mail/EmployeeInfo.php
Normal file
53
app/Mail/EmployeeInfo.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
abstract class EmployeeInfo extends Mailable
|
||||
{
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
abstract public function build();
|
||||
|
||||
/**
|
||||
* Attach a joined file if given in data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function joinFileIfProvided(): void
|
||||
{
|
||||
if (isset($this->data['file'])) {
|
||||
$joinedFileName = sprintf(
|
||||
'PortEmployee-PJ-%s.%s',
|
||||
date("YmdHis"),
|
||||
$this->data['file']->extension()
|
||||
);
|
||||
$this->attach($this->data['file'], [
|
||||
'as' => $joinedFileName,
|
||||
'mime' => $this->data['file']->getMimeType()
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
app/Mail/EmployeeInfoAddress.php
Normal file
22
app/Mail/EmployeeInfoAddress.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
class EmployeeInfoAddress extends EmployeeInfo
|
||||
{
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$this->joinFileIfProvided();
|
||||
return $this
|
||||
->subject(sprintf('%s : Un salarié à mis à jour ses infos', config('app.name')))
|
||||
->view('emails.employee-address')
|
||||
->text('emails.employee-address-plain')
|
||||
->with('employee', $this->data['employee'])
|
||||
->with('data', $this->data);
|
||||
}
|
||||
}
|
||||
22
app/Mail/EmployeeInfoBank.php
Normal file
22
app/Mail/EmployeeInfoBank.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
class EmployeeInfoBank extends EmployeeInfo
|
||||
{
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$this->joinFileIfProvided();
|
||||
return $this
|
||||
->subject(sprintf('%s : Un salarié à mis à jour ses infos', config('app.name')))
|
||||
->view('emails.employee-bank')
|
||||
->text('emails.employee-bank-plain')
|
||||
->with('employee', $this->data['employee'])
|
||||
->with('data', $this->data);
|
||||
}
|
||||
}
|
||||
22
app/Mail/EmployeeInfoFamily.php
Normal file
22
app/Mail/EmployeeInfoFamily.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
class EmployeeInfoFamily extends EmployeeInfo
|
||||
{
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$this->joinFileIfProvided();
|
||||
return $this
|
||||
->subject(sprintf('%s : Un salarié à mis à jour ses infos', config('app.name')))
|
||||
->view('emails.employee-family')
|
||||
->text('emails.employee-family-plain')
|
||||
->with('employee', $this->data['employee'])
|
||||
->with('data', $this->data);
|
||||
}
|
||||
}
|
||||
41
app/Mail/EmployeeLockedDown.php
Normal file
41
app/Mail/EmployeeLockedDown.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class EmployeeLockedDown extends Mailable
|
||||
{
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var Employee */
|
||||
protected $employee;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Employee $employee)
|
||||
{
|
||||
$this->employee = $employee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this
|
||||
->subject(sprintf('%s : Un compte salarié viens d\'être verrouillé', config('app.name')))
|
||||
->view('emails.employee-lockedDown')
|
||||
->text('emails.employee-lockedDown-plain')
|
||||
->with('employee', $this->employee);
|
||||
}
|
||||
}
|
||||
40
app/Mail/EmployeePasswordResetMail.php
Normal file
40
app/Mail/EmployeePasswordResetMail.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class EmployeePasswordResetMail extends Mailable
|
||||
{
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
protected $employee;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Employee $employee)
|
||||
{
|
||||
$this->employee = $employee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this
|
||||
->subject(sprintf('%s : Voici un lien pour réinitialiser votre mot de passe', config('app.name')))
|
||||
->view('emails.password-reset')
|
||||
->text('emails.password-reset-plain')
|
||||
->with('employee', $this->employee);
|
||||
}
|
||||
}
|
||||
21
app/Mail/EmployeeQuestionFormation.php
Normal file
21
app/Mail/EmployeeQuestionFormation.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
class EmployeeQuestionFormation extends EmployeeInfo
|
||||
{
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this
|
||||
->subject(sprintf('%s : Un salarié a une question', config('app.name')))
|
||||
->view('emails.employee-question-formation')
|
||||
->text('emails.employee-question-formation-plain')
|
||||
->with('employee', $this->data['employee'])
|
||||
->with('data', $this->data);
|
||||
}
|
||||
}
|
||||
21
app/Mail/EmployeeQuestionRdv.php
Normal file
21
app/Mail/EmployeeQuestionRdv.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
class EmployeeQuestionRdv extends EmployeeInfo
|
||||
{
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this
|
||||
->subject(sprintf('%s : Un salarié vousdrais prendre rendez-vous', config('app.name')))
|
||||
->view('emails.employee-question-rdv')
|
||||
->text('emails.employee-question-rdv-plain')
|
||||
->with('employee', $this->data['employee'])
|
||||
->with('data', $this->data);
|
||||
}
|
||||
}
|
||||
41
app/Mail/EmployeeYourAccountIsLockedDown.php
Normal file
41
app/Mail/EmployeeYourAccountIsLockedDown.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class EmployeeYourAccountIsLockedDown extends Mailable
|
||||
{
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var Employee */
|
||||
protected $employee;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Employee $employee)
|
||||
{
|
||||
$this->employee = $employee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this
|
||||
->subject(sprintf('%s : Votre compte salarié viens d\'être verrouillé', config('app.name')))
|
||||
->view('emails.employee-own-lockedDown')
|
||||
->text('emails.employee-own-lockedDown-plain')
|
||||
->with('employee', $this->employee);
|
||||
}
|
||||
}
|
||||
277
app/Models/Employee.php
Normal file
277
app/Models/Employee.php
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\CrudAction;
|
||||
use App\Enums\CrudType;
|
||||
use App\Traits\IsCrudModel;
|
||||
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;
|
||||
|
||||
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' => [
|
||||
'string',
|
||||
'min:10',
|
||||
'max:50'
|
||||
],
|
||||
'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'
|
||||
],
|
||||
'rules' => [
|
||||
'min' => 5,
|
||||
'max' => 10,
|
||||
'step' => 2
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'email' => [
|
||||
'label' => trans('Email'),
|
||||
'type' => CrudType::email(),
|
||||
'nullable' => false,
|
||||
'validate' => [
|
||||
'max:150'
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'password' => [
|
||||
'label' => trans('Mot de passe'),
|
||||
'placeholder' => '#M1s3Cure.P4ss0rd!',
|
||||
'type' => CrudType::password(),
|
||||
'nullable' => false,
|
||||
'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 () {
|
||||
return $this->getAttribute('password_attempts') >= 3;
|
||||
},
|
||||
'setAttribute' => function ($value) {
|
||||
$this->setAttribute('password_attempts', $value ? 3 : 0);
|
||||
return $this->getAttribute('password_attempts');
|
||||
},
|
||||
]
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::creating(function ($employee) {
|
||||
$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()
|
||||
]);
|
||||
}
|
||||
}
|
||||
34
app/Models/EmployeeMailToken.php
Normal file
34
app/Models/EmployeeMailToken.php
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class EmployeeMailToken extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'email',
|
||||
'hashcode',
|
||||
'employee_id'
|
||||
];
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::creating(function ($employee) {
|
||||
$employee->hashcode = Str::uuid();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Has one Employee
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function employee()
|
||||
{
|
||||
return $this->belongsTo(Employee::class);
|
||||
}
|
||||
}
|
||||
75
app/Models/Flash.php
Normal file
75
app/Models/Flash.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Casts\NiceDate;
|
||||
use App\Enums\CrudAction;
|
||||
use App\Enums\CrudType;
|
||||
use App\Traits\IsCrudModel;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Flash extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use IsCrudModel;
|
||||
|
||||
protected $crudLabelColumn = 'title';
|
||||
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
protected $fillable = [
|
||||
'title',
|
||||
'content',
|
||||
'status'
|
||||
];
|
||||
|
||||
public function __construct($attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'title' => [
|
||||
'label' => trans('Titre'),
|
||||
'type' => CrudType::string(),
|
||||
'rule' => [
|
||||
'max' => 255
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'content' => [
|
||||
'label' => trans('Contenu'),
|
||||
'type' => CrudType::text(),
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'status' => [
|
||||
'label' => trans('Publié'),
|
||||
'type' => CrudType::boolean(),
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
]
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has one Site
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function site()
|
||||
{
|
||||
return $this->belongsTo(Site::class);
|
||||
}
|
||||
}
|
||||
38
app/Models/Planning.php
Normal file
38
app/Models/Planning.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Planning extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'start',
|
||||
'end',
|
||||
'data'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'start' => 'datetime',
|
||||
'end' => 'datetime',
|
||||
'data' => 'array'
|
||||
];
|
||||
|
||||
/**
|
||||
* Has one Employee
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function employee()
|
||||
{
|
||||
return $this->belongsTo(Employee::class);
|
||||
}
|
||||
}
|
||||
54
app/Models/Pole.php
Normal file
54
app/Models/Pole.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\CrudAction;
|
||||
use App\Enums\CrudType;
|
||||
use App\Traits\IsCrudModel;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Pole extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use IsCrudModel;
|
||||
|
||||
protected $crudLabelColumn = 'name';
|
||||
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
protected $fillable = [
|
||||
'name'
|
||||
];
|
||||
|
||||
public function __construct($attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'name' => [
|
||||
'label' => trans('Nom'),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
]
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has many Societe
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function societes()
|
||||
{
|
||||
return $this->hasMany(Societe::class);
|
||||
}
|
||||
}
|
||||
37
app/Models/ReponseSondage.php
Normal file
37
app/Models/ReponseSondage.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Concerns\HasTimestamps;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ReponseSondage extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasTimestamps;
|
||||
|
||||
protected $fillable = [
|
||||
'value'
|
||||
];
|
||||
|
||||
/**
|
||||
* Has one Sondage
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function sondage()
|
||||
{
|
||||
return $this->belongsTo(Sondage::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* BelongsToMany
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function employees()
|
||||
{
|
||||
return $this->belongsToMany(Employee::class)->withTimestamps();
|
||||
}
|
||||
}
|
||||
10
app/Models/ReponseSondageEmployee.php
Normal file
10
app/Models/ReponseSondageEmployee.php
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
|
||||
class ReponseSondageEmployee extends Pivot
|
||||
{
|
||||
//
|
||||
}
|
||||
227
app/Models/Site.php
Normal file
227
app/Models/Site.php
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\CrudAction;
|
||||
use App\Enums\CrudType;
|
||||
use App\Traits\IsCrudModel;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Site extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use IsCrudModel;
|
||||
|
||||
protected $crudLabelColumn = 'name';
|
||||
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
protected $fillable = [
|
||||
'url',
|
||||
'name',
|
||||
'email_contact',
|
||||
'address',
|
||||
'city',
|
||||
'postcode',
|
||||
'latitude',
|
||||
'longitude'
|
||||
];
|
||||
|
||||
public function __construct($attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'url' => [
|
||||
'label' => trans('Url'),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'url',
|
||||
'max:255'
|
||||
],
|
||||
'required' => true,
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'name' => [
|
||||
'label' => trans('Nom'),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
'required' => true,
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'email_contact' => [
|
||||
'label' => trans('Email de contact'),
|
||||
'type' => CrudType::email(),
|
||||
'required' => true,
|
||||
'nullable' => false,
|
||||
'validate' => [
|
||||
'max:255'
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'address' => [
|
||||
'label' => trans('Adresse'),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
'required' => true,
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'city' => [
|
||||
'label' => trans('Ville'),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'string',
|
||||
'max:70'
|
||||
],
|
||||
'required' => true,
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'postcode' => [
|
||||
'label' => trans('Code postal'),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'string',
|
||||
'max:10'
|
||||
],
|
||||
'required' => true,
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'latitude' => [
|
||||
'label' => trans('Latitude'),
|
||||
'type' => CrudType::float(),
|
||||
'validate' => [
|
||||
'numeric',
|
||||
'between:-89.99,90'
|
||||
],
|
||||
'rules' => [
|
||||
'min' => -89.99,
|
||||
'max' => 90,
|
||||
'step' => 0.01
|
||||
],
|
||||
'required' => true,
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'longitude' => [
|
||||
'label' => trans('Longitude'),
|
||||
'type' => CrudType::float(),
|
||||
'validate' => [
|
||||
'numeric',
|
||||
'between:-179.99,180.00',
|
||||
],
|
||||
'rules' => [
|
||||
'min' => -179.99,
|
||||
'max' => 180,
|
||||
'step' => 0.01
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'societe_id' => [
|
||||
'label' => trans('Societe'),
|
||||
'type' => CrudType::belongsTo(),
|
||||
'belongsTo' => Site::class,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
]
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has one Societe
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function societe()
|
||||
{
|
||||
return $this->belongsTo(Societe::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has many Employee
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function employees()
|
||||
{
|
||||
return $this->hasMany(Employee::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Belongs To Many Sites
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\belongsToMany
|
||||
*/
|
||||
public function users()
|
||||
{
|
||||
return $this->belongsToMany(Site::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has many Flash
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function flashes()
|
||||
{
|
||||
return $this->hasMany(Flash::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has many Sondage
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function sondages()
|
||||
{
|
||||
return $this->hasMany(Sondage::class);
|
||||
}
|
||||
}
|
||||
129
app/Models/Societe.php
Normal file
129
app/Models/Societe.php
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\CrudAction;
|
||||
use App\Enums\CrudType;
|
||||
use App\Traits\IsCrudModel;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
|
||||
class Societe extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use IsCrudModel;
|
||||
|
||||
protected $crudLabelColumn = 'name';
|
||||
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'logo',
|
||||
'style',
|
||||
'colors'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'colors' => 'array',
|
||||
];
|
||||
|
||||
protected $attributes = [
|
||||
'style' => '',
|
||||
'colors' => '{"color0":"#EEE"'
|
||||
];
|
||||
|
||||
public function __construct($attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'name' => [
|
||||
'label' => trans('Nom'),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'string',
|
||||
'min:10',
|
||||
'max:255'
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'logo' => [
|
||||
'label' => trans('Logo'),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'style' => [
|
||||
'label' => trans('Style'),
|
||||
'type' => CrudType::text(),
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'colors' => [
|
||||
'label' => trans('Couleurs'),
|
||||
'type' => CrudType::text(),
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'pole_id' => [
|
||||
'label' => trans('Pole'),
|
||||
'type' => CrudType::belongsTo(),
|
||||
'belongsTo' => Pole::class,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
]
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has one Pole
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function pole()
|
||||
{
|
||||
return $this->belongsTo(Pole::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has many Site
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function sites()
|
||||
{
|
||||
return $this->hasMany(Site::class);
|
||||
}
|
||||
|
||||
public static function saveLogo(UploadedFile $image, string $name)
|
||||
{
|
||||
return $image->storePubliclyAs(
|
||||
'/public/societe',
|
||||
sprintf('%s-%s.%s', $name, rand(10000, 99999), $image->extension())
|
||||
);
|
||||
}
|
||||
}
|
||||
118
app/Models/Sondage.php
Normal file
118
app/Models/Sondage.php
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\CrudAction;
|
||||
use App\Enums\CrudType;
|
||||
use App\Enums\TypeSondage;
|
||||
use App\Traits\IsCrudModel;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Kwaadpepper\Enum\Traits\CastsEnums;
|
||||
|
||||
class Sondage extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use CastsEnums;
|
||||
use IsCrudModel;
|
||||
|
||||
protected $crudLabelColumn = 'question';
|
||||
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
protected $enumCasts = [
|
||||
'type' => TypeSondage::class
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'type',
|
||||
'question',
|
||||
'status'
|
||||
];
|
||||
|
||||
public function __construct($attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'question' => [
|
||||
'label' => trans('Question'),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'max:255'
|
||||
],
|
||||
'required' => true,
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'type' => [
|
||||
'label' => trans('Type'),
|
||||
'type' => CrudType::enum(),
|
||||
'enum' => TypeSondage::class,
|
||||
'validate' => [
|
||||
'required',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if (!in_array($value, TypeSondage::toValues())) {
|
||||
$fail(trans('Veuillez choisir entre :values', [
|
||||
'value' => implode(',', TypeSondage::toLabels())
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'required' => true,
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'reponses' => [
|
||||
'label' => trans('Nombre de Réponses'),
|
||||
'type' => CrudType::string(),
|
||||
'actions' => [
|
||||
CrudAction::viewAny()
|
||||
],
|
||||
'getAttribute' => function () {
|
||||
return $this->reponseSondages()->count();
|
||||
},
|
||||
],
|
||||
'status' => [
|
||||
'label' => trans('Publié'),
|
||||
'type' => CrudType::boolean(),
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
]
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has one Site
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function site()
|
||||
{
|
||||
return $this->belongsTo(Site::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has many ReponseSondage
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function reponseSondages()
|
||||
{
|
||||
return $this->hasMany(ReponseSondage::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,31 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use App\Enums\CrudAction;
|
||||
use App\Enums\CrudType;
|
||||
use App\Enums\Role;
|
||||
use App\Traits\IsCrudModel;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
use Kwaadpepper\Enum\Traits\CastsEnums;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasFactory, Notifiable;
|
||||
use HasFactory;
|
||||
use Notifiable;
|
||||
use CastsEnums;
|
||||
use IsCrudModel;
|
||||
|
||||
protected $crudLabelColumn = 'name';
|
||||
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
protected $enumCasts = [
|
||||
'role' => Role::class
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
|
@ -17,9 +34,11 @@ class User extends Authenticatable
|
|||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'role',
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
'site_id'
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -32,12 +51,124 @@ class User extends Authenticatable
|
|||
'remember_token',
|
||||
];
|
||||
|
||||
public function __construct($attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'role' => [
|
||||
'label' => trans('Role'),
|
||||
'type' => CrudType::enum(),
|
||||
'enum' => Role::class,
|
||||
'validate' => [
|
||||
'required',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if (!in_array($value, Role::toValues())) {
|
||||
$fail(trans('Veuillez choisir entre :values', [
|
||||
'value' => implode(',', Role::toLabels())
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'name' => [
|
||||
'label' => trans('Nom'),
|
||||
'type' => CrudType::string(),
|
||||
'validate' => [
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'email' => [
|
||||
'label' => trans('Email'),
|
||||
'type' => CrudType::email(),
|
||||
'nullable' => false,
|
||||
'validate' => [
|
||||
'max:255',
|
||||
'unique:users,email'
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
],
|
||||
'password' => [
|
||||
'label' => trans('Mot de passe'),
|
||||
'placeholder' => '#M1s3Cure.P4ss0rd!',
|
||||
'type' => CrudType::password(),
|
||||
'nullable' => true,
|
||||
'required' => false,
|
||||
'validate' => [
|
||||
'nullable',
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
'actions' => [
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'sites' => [
|
||||
'label' => trans('Sites'),
|
||||
'type' => CrudType::belongsToMany(),
|
||||
'belongsToMany' => Site::class,
|
||||
'belongsToManyLabel' => 'name',
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update(),
|
||||
]
|
||||
]
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::creating(function ($user) {
|
||||
$user->password = Hash::make($user->password);
|
||||
$user->remember_token = Str::random(10);
|
||||
});
|
||||
static::updating(function ($user) {
|
||||
if (Hash::needsRehash($user->password)) {
|
||||
$user->password = Hash::make($user->password);
|
||||
}
|
||||
$user->remember_token = Str::random(10);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
* Belongs To Many Sites
|
||||
*
|
||||
* @var array
|
||||
* @return \Illuminate\Database\Eloquent\Relations\belongsToMany
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
public function sites()
|
||||
{
|
||||
return $this->belongsToMany(Site::class, 'user_site');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get User Selected Site
|
||||
*
|
||||
* @return Site|null
|
||||
*/
|
||||
public function selectedSite()
|
||||
{
|
||||
return Site::where('id', $this->selected_site_id)->first();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue