From 79d9061bc985f3ddc7bcfc91db38efda4d5b6a50 Mon Sep 17 00:00:00 2001 From: Karl Muller Date: Mon, 10 Feb 2025 15:18:10 +0000 Subject: [PATCH] fix: :bug: user->id null on SalarieExportJob + add public holiday with cron + condition on public holiday's calendar --- .../Commands/GetPublicHolidayNextYear.php | 35 +++++ app/Console/Kernel.php | 2 + app/Enums/ExceptionDayType.php | 42 ++++++ .../Controllers/Bo/MagasinsController.php | 6 +- .../Controllers/Bo/SalariesController.php | 3 +- .../Controllers/OrderTunnelController.php | 41 +++++- app/Imports/SalariesImport.php | 2 +- app/Jobs/GetPublicHolidayForNextYear.php | 64 ++++++++ app/Jobs/SalariesExportJob.php | 20 ++- app/Models/CollecteException.php | 2 +- app/Models/Salarie.php | 32 ++-- ...10_112337_add_type_to_exceptions_table.php | 50 +++++++ .../js/components/CreneauxExceptions.vue | 139 ++++++++++-------- resources/views/bo/magasins/edit.blade.php | 63 +++++--- 14 files changed, 382 insertions(+), 119 deletions(-) create mode 100644 app/Console/Commands/GetPublicHolidayNextYear.php create mode 100644 app/Enums/ExceptionDayType.php create mode 100644 app/Jobs/GetPublicHolidayForNextYear.php create mode 100644 database/migrations/2025_02_10_112337_add_type_to_exceptions_table.php diff --git a/app/Console/Commands/GetPublicHolidayNextYear.php b/app/Console/Commands/GetPublicHolidayNextYear.php new file mode 100644 index 0000000..38ed4fd --- /dev/null +++ b/app/Console/Commands/GetPublicHolidayNextYear.php @@ -0,0 +1,35 @@ +argument('year'); + (new GetPublicHolidayForNextYear($year))->handle(); + $this->info("Les jours fériés de l'année " . ($year ?? (now()->year + 1)) . " ont été récupéré."); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 7976a60..11e4597 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,6 +2,7 @@ namespace App\Console; +use App\Jobs\GetPublicHolidayForNextYear; use App\Jobs\SendReminderMail; use App\Jobs\XmlIncoReader as JobsXmlIncoReader; use Illuminate\Console\Scheduling\Schedule; @@ -26,6 +27,7 @@ class Kernel extends ConsoleKernel { $schedule->job(JobsXmlIncoReader::class)->name('xml-inco-reader')->onOneServer()->dailyAt('15:00'); $schedule->job(SendReminderMail::class)->onOneServer()->dailyAt('7:00'); + $schedule->job(GetPublicHolidayForNextYear::class)->onOneServer()->yearlyOn(11, 1, '7:30'); } /** diff --git a/app/Enums/ExceptionDayType.php b/app/Enums/ExceptionDayType.php new file mode 100644 index 0000000..761b29b --- /dev/null +++ b/app/Enums/ExceptionDayType.php @@ -0,0 +1,42 @@ + 'Jour férié', + 'other' => 'Autre', + ]; + } + + /** + * Enum labels + * + * @return array + */ + protected static function labels(): array + { + return [ + 'ferie' => __('Jour férié'), + 'other' => __('Autre'), + ]; + } +} diff --git a/app/Http/Controllers/Bo/MagasinsController.php b/app/Http/Controllers/Bo/MagasinsController.php index d16f32c..a77dd80 100644 --- a/app/Http/Controllers/Bo/MagasinsController.php +++ b/app/Http/Controllers/Bo/MagasinsController.php @@ -147,6 +147,7 @@ class MagasinsController extends Controller $ce = CollecteException::findOrFail($collecteException[$i]["id"]); $ce->date = $collecteException[$i]["date"]; $ce->comment = $collecteException[$i]["comment"]; + $ce->type = $collecteException[$i]["type"]; $ce->magasin_id = $collecteException[$i]["magasin_id"]; $ce->save(); } else { @@ -154,15 +155,16 @@ class MagasinsController extends Controller $ce = CollecteException::updateOrCreate([ 'date' => $collecteException[$i]["date"], 'comment' => $collecteException[$i]["comment"], + 'type' => $collecteException[$i]["type"], 'magasin_id' => $collecteException[$i]["magasin_id"] - ]); + ]); $collecteException[$i]["id"] = $ce->id; } else { unset($collecteException[$i]); $i--; } } - }//end for + } //end for // Remet dans l'ordre avant de renvoyer. $this->arraySortByColumn($collecteException, "date"); diff --git a/app/Http/Controllers/Bo/SalariesController.php b/app/Http/Controllers/Bo/SalariesController.php index 50cf051..7e49a7b 100644 --- a/app/Http/Controllers/Bo/SalariesController.php +++ b/app/Http/Controllers/Bo/SalariesController.php @@ -6,6 +6,7 @@ use App\Http\Controllers\Controller; use App\Http\Requests\Bo\ImportRequest; use App\Imports\SalariesImport; use App\Jobs\SalariesExportJob; +use Illuminate\Support\Facades\Auth; use Maatwebsite\Excel\Facades\Excel; class SalariesController extends Controller @@ -47,7 +48,7 @@ class SalariesController extends Controller */ public function export(array $salariesImport) { - $this->dispatch(new SalariesExportJob($salariesImport)); + $this->dispatch(new SalariesExportJob($salariesImport, Auth::user())); return redirect()->route('bo.salaries.index')->with('success', 'Export terminé.'); } } diff --git a/app/Http/Controllers/OrderTunnelController.php b/app/Http/Controllers/OrderTunnelController.php index d65a056..02cc49a 100644 --- a/app/Http/Controllers/OrderTunnelController.php +++ b/app/Http/Controllers/OrderTunnelController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Enums\ExceptionDayType; use App\Http\Controllers\Controller; use App\Models\Order; use App\Models\OrderLine; @@ -166,7 +167,6 @@ class OrderTunnelController extends Controller if (Auth::user()->salarie->magasin) { $magasin = Auth::user()->salarie->magasin; } - $availCreneaux = array(); $order = Order::where('reference', '=', $reference)->firstOrFail(); @@ -198,7 +198,9 @@ class OrderTunnelController extends Controller CarbonInterval $delaiPrepa, CarbonInterval $interval, Carbon $currentTime, - Carbon $endTime + Carbon $endTime, + bool $hasPublicHolidayNextWeekButNoFriday, + bool $afterThursdayNight ) { $retArray = array(); do { @@ -225,6 +227,11 @@ class OrderTunnelController extends Controller } // Attention si la date est passée (today mais avant maintenant) : pas de créneau. if ($current > $today || $currentTime >= $now) { + // Si un jour de la semaine prochaine est férié et qu'on passe commande un jeudi après 23h59...alors le vendredi de la semaine suivante n'est pas dispo. + $nextFriday = $now->addWeek()->startOfWeek(Carbon::MONDAY)->addDays(4); + if ($hasPublicHolidayNextWeekButNoFriday && $afterThursdayNight && $current->isSameDay($nextFriday)) { + $isDispo = false; + } $retArray[] = array($creneau, $isDispo); } $currentTime->add($interval); @@ -242,7 +249,6 @@ class OrderTunnelController extends Controller { // Setting à stocker et réutiliser. $plage_days = Setting::where('key', 'order_withdrawal_period')->firstOrFail()->value; - $magasin = Magasin::findOrFail($id); $timeslotSettings = $magasin->timeslotSettings; // $timeslotSettings = TimeslotSetting::all(); @@ -267,12 +273,30 @@ class OrderTunnelController extends Controller // Final boundary (permet de limiter la liste des jours d'exception). $finalday = $today->add($plage_days, 'day'); $now = CarbonImmutable::now(); + // Jours exceptions. $noCollectDays = $magasin->collecteExceptions() ->whereDate('date', '>', $now) ->whereDate('date', '<=', $finalday) ->orderBy('date')->get(); + + // On effectue des vérifications pour récupérer des jours de la semaine suivante + // =/= de vendredi qui seraient fériés. + $thursdayNight = $now->startOfWeek(Carbon::MONDAY)->addDays(3)->setTime(23, 59); + $afterThursdayNight = $now->greaterThanOrEqualTo($thursdayNight); + $currentweekStartDate = $now->startOfWeek(); + $currentweekEndDate = $now->endOfWeek(); + $nextWeekStartDate = $currentweekStartDate->addWeek(); + $nextWeekEndDate = $currentweekEndDate->addWeek(); + + $hasPublicHolidayNextWeekButNoFriday = $magasin->collecteExceptions() + ->whereDate('date', '>=', $nextWeekStartDate) + ->whereDate('date', '<=', $nextWeekEndDate) + ->where('type', '=', ExceptionDayType::ferie()) + ->whereRaw('DAYOFWEEK(date) != ?', 6) + ->count() > 0; + $delaiPrepa = CarbonInterval::createFromFormat('h:i', $plage[$weekDay]['min_order_preparation'] ?? '01:00'); $availCreneaux = array(); @@ -288,6 +312,7 @@ class OrderTunnelController extends Controller $interval = CarbonInterval::createFromFormat('h:i', $plage[$weekDay]['interval'] ?? '00:15'); // Si c'est un jour exception skip. + // ah ? mais on skip quoi et ou ? et pourquoi ? $skip = false; foreach ($noCollectDays as $not_today) { if ($current->isSameDay($not_today->date)) { @@ -297,7 +322,9 @@ class OrderTunnelController extends Controller if ($skip) { continue; } + $availCreneaux[$current->format('d/m/Y')] = array(); + // Matinée. if (!empty($plage[$weekDay]['morning_start'])) { $currentTime = Carbon::createFromTimeString($plage[$weekDay]['morning_start']); @@ -313,7 +340,9 @@ class OrderTunnelController extends Controller $delaiPrepa, $interval, $currentTime, - $endTime + $endTime, + $hasPublicHolidayNextWeekButNoFriday, + $afterThursdayNight, ); // Cela sert à rien d'afficher un jour avec des créneaux sur lesquels le conso ne peut pas cliquer... if ($this->hasCreneauAvailableTime($morningCreneaux)) { @@ -338,7 +367,9 @@ class OrderTunnelController extends Controller $delaiPrepa, $interval, $currentTime, - $endTime + $endTime, + $hasPublicHolidayNextWeekButNoFriday, + $afterThursdayNight, ); // Cela sert à rien d'afficher un jour avec des créneaux sur lesquels le conso ne peut pas cliquer... if ($this->hasCreneauAvailableTime($afternoonCreneaux)) { diff --git a/app/Imports/SalariesImport.php b/app/Imports/SalariesImport.php index da93569..2378e28 100644 --- a/app/Imports/SalariesImport.php +++ b/app/Imports/SalariesImport.php @@ -56,7 +56,7 @@ class SalariesImport implements ToModel, WithCustomCsvSettings, WithHeadingRow, $salarie->site = Arr::get($row, 'site'); $salarie->service = Arr::get($row, 'service'); $salarie->code = $salarie->code ?? Salarie::generateRandomString(8, Salarie::query()); - Salarie::setSalarieMagasin($salarie); + $salarie->setMagasin(); $salarie->saveOrFail(); $this->salariesImport = array_merge($this->salariesImport, [$matricule]); return $salarie; diff --git a/app/Jobs/GetPublicHolidayForNextYear.php b/app/Jobs/GetPublicHolidayForNextYear.php new file mode 100644 index 0000000..f22ad72 --- /dev/null +++ b/app/Jobs/GetPublicHolidayForNextYear.php @@ -0,0 +1,64 @@ +year = is_numeric($year) ? (int)$year : null; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + $targetYear = $this->year ?? now()->year + 1; + $url = "https://calendrier.api.gouv.fr/jours-feries/metropole/{$targetYear}.json"; + $response = Http::get($url); + if ($response->successful()) { + $publicHolidays = $response->json(); + $magasins = Magasin::with('collecteExceptions')->get(); + foreach ($magasins as $magasin) { + foreach ($publicHolidays as $date => $holidayName) { + $existingException = $magasin->collecteExceptions()->where('date', $date)->first(); + if (!$existingException) { + $magasin->collecteExceptions()->create([ + 'date' => $date, + 'comment' => $holidayName, + 'type' => ExceptionDayType::ferie() + ]); + } + } + } + } + } +} diff --git a/app/Jobs/SalariesExportJob.php b/app/Jobs/SalariesExportJob.php index 4568aed..660e98a 100644 --- a/app/Jobs/SalariesExportJob.php +++ b/app/Jobs/SalariesExportJob.php @@ -4,9 +4,9 @@ namespace App\Jobs; use App\Exports\SalariesExport; use Illuminate\Contracts\Queue\ShouldQueue; -use Illuminate\Support\Facades\Auth; use Maatwebsite\Excel\Facades\Excel; use App\Mail\SendSalariesCSVMail; +use App\Models\User; use Carbon\Carbon; use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Storage; @@ -19,15 +19,23 @@ class SalariesExportJob implements ShouldQueue */ public $salariesImport = null; + /** + * Auth user + * @var User|null + */ + public $user = null; + /** * Create a new job instance. * - * @param array $salariesImport + * @param array $salariesImport + * @param \Illuminate\Auth\Authenticatable $user * @return void */ - public function __construct(array $salariesImport) + public function __construct(array $salariesImport, User $user) { $this->salariesImport = $salariesImport; + $this->user = $user; } /** @@ -37,14 +45,12 @@ class SalariesExportJob implements ShouldQueue */ public function handle() { - /** @var \App\Models\User */ - $user = Auth::user(); $disk = Storage::disk('salaries'); - $csv_file = Carbon::now()->format('d_m_Y-H_i_s') . '-' . $user->id . '-export_salaries.csv'; + $csv_file = Carbon::now()->format('d_m_Y-H_i_s') . '-' . $this->user->id . '-export_salaries.csv'; Excel::store(new SalariesExport($this->salariesImport), $csv_file, 'salaries'); - Mail::to($user->email)->send(new SendSalariesCSVMail($user, $csv_file)); + Mail::to($this->user->email)->send(new SendSalariesCSVMail($this->user, $csv_file)); if ($disk->exists($csv_file)) { $disk->delete($csv_file); diff --git a/app/Models/CollecteException.php b/app/Models/CollecteException.php index 61d4e23..27670be 100644 --- a/app/Models/CollecteException.php +++ b/app/Models/CollecteException.php @@ -15,7 +15,7 @@ class CollecteException extends Model * * @var array */ - protected $fillable = ['date', 'comment', 'magasin_id']; + protected $fillable = ['date', 'comment', 'magasin_id', 'type']; /** * The attributes that should be cast to native types. diff --git a/app/Models/Salarie.php b/app/Models/Salarie.php index fd87c59..17b65af 100644 --- a/app/Models/Salarie.php +++ b/app/Models/Salarie.php @@ -18,31 +18,24 @@ class Salarie extends Model */ protected $fillable = [ 'matricule', - 'nom', 'prenom', + 'nom', + 'prenom', 'code', - 'start_date', 'end_date', 'etablissement', 'site', 'service' + 'start_date', + 'end_date', + 'etablissement', + 'site', + 'service' ]; - /** - * Setter magasin for a salarie. - * - * @param \App\Models\Salarie $salarie - * @return void - */ - public static function setSalarieMagasin(Salarie $salarie) - { - Salarie::setMagasin($salarie); - } - /** * Sets the fixed collection point for a salarie. * - * @param \App\Models\Salarie $salarie * @return void */ - private function setMagasin(Salarie $salarie) + public function setMagasin() { - switch ($salarie->site) { + switch ($this->site) { case SalarieSite::ldccav(): // Cavol. $magasin = Magasin::find(3); @@ -56,10 +49,10 @@ class Salarie extends Model $magasin = Magasin::find(9); break; case SalarieSite::cepacpe(): - if (in_array($salarie->service, ["CEPACP060", "CEPACP070", "CEPACP072"])) { + if (in_array($this->service, ["CEPACP060", "CEPACP070", "CEPACP072"])) { // CPE. $magasin = Magasin::find(6); - } elseif (in_array($salarie->service, ["CEPACP065", "CEPACP066"])) { + } elseif (in_array($this->service, ["CEPACP065", "CEPACP066"])) { // PLB. $magasin = Magasin::find(11); } else { @@ -83,8 +76,7 @@ class Salarie extends Model $magasin = Magasin::find(1); } //end switch - $salarie->magasin()->associate($magasin); - $salarie->save(); + $this->magasin()->associate($magasin); } /** diff --git a/database/migrations/2025_02_10_112337_add_type_to_exceptions_table.php b/database/migrations/2025_02_10_112337_add_type_to_exceptions_table.php new file mode 100644 index 0000000..e78743a --- /dev/null +++ b/database/migrations/2025_02_10_112337_add_type_to_exceptions_table.php @@ -0,0 +1,50 @@ +label; + $other = ExceptionDayType::other()->label; + + Schema::table('collecte_exceptions', function (Blueprint $table) { + $table->string('type') + ->default(ExceptionDayType::ferie()->label) + ->after('comment') + ->comment('Type of exception day.'); + }); + + + + DB::table('collecte_exceptions') + ->where('comment', 'Jour férié') + ->update(['type' => $ferie]); + + DB::table('collecte_exceptions') + ->where('comment', '<>', 'Jour férié') + ->update(['type' => $other]); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('collecte_exceptions', function (Blueprint $table) { + $table->dropColumn('type'); + }); + } +} diff --git a/resources/js/components/CreneauxExceptions.vue b/resources/js/components/CreneauxExceptions.vue index 6b9c547..63693f9 100644 --- a/resources/js/components/CreneauxExceptions.vue +++ b/resources/js/components/CreneauxExceptions.vue @@ -1,6 +1,7 @@ diff --git a/resources/views/bo/magasins/edit.blade.php b/resources/views/bo/magasins/edit.blade.php index 2c2349d..c426789 100644 --- a/resources/views/bo/magasins/edit.blade.php +++ b/resources/views/bo/magasins/edit.blade.php @@ -1,16 +1,17 @@ @extends('layouts.bo-layout') @section('content') -
+ @method('PUT') @csrf -
-

< Magasin Modification

+
+

+ Magasin Modification

@if (session('success')) {{ session('success') }} @endif -
-
@if ($errors->any()) @@ -25,66 +26,88 @@
- +
- +
- +
- +
- +
- +
-
+

Google Maps

- +
- +
- +
- +
- + + @php + $exceptionType = collect(\App\Enums\ExceptionDayType::toLabels()) + ->map(function ($label, $key) { + return [ + 'label' => $label, + 'value' => \App\Enums\ExceptionDayType::toValues()[$key], + ]; + }) + ->values(); + @endphp + + @endsection @section('scripts') - @endsection