diff --git a/laravel/app/Http/Controllers/ReportController.php b/laravel/app/Http/Controllers/ReportController.php index 76976878..39e7f0ac 100644 --- a/laravel/app/Http/Controllers/ReportController.php +++ b/laravel/app/Http/Controllers/ReportController.php @@ -60,7 +60,7 @@ public function searchUsers(Request $request) return json_encode($users); } - + public function getDepartments(Request $request) { $id = $request->get('event'); diff --git a/laravel/app/Http/Controllers/SlotController.php b/laravel/app/Http/Controllers/SlotController.php index 851a9e4e..3b17e841 100644 --- a/laravel/app/Http/Controllers/SlotController.php +++ b/laravel/app/Http/Controllers/SlotController.php @@ -66,7 +66,7 @@ public function view(Request $request, Slot $slot) $request->session()->flash('error', "You must enter your name before you can sign up for shifts."); return redirect('/profile/data/edit'); } - + return view('pages/slot/view', compact('slot')); } @@ -101,6 +101,12 @@ public function take(SlotRequest $request, Slot $slot) // Has somebody else already taken this slot? if(is_null($slot->user)) { + $concurrent_slot_warning = $this->warnIfConcurrentSlotForUserExists($request, $slot, Auth::user()); + if($concurrent_slot_warning) + { + return back(); + } + $slot->user_id = Auth::user()->id; $slot->save(); @@ -167,7 +173,7 @@ public function adminRelease(Request $request, Slot $slot) { if(!is_null($slot->user)) { - $username = Helpers::displayName($slot->user); + $user_name = Helpers::displayName($slot->user); $slot->user_id = null; $slot->save(); @@ -185,15 +191,63 @@ public function adminAssign(Request $request, Slot $slot) { $user = User::findorFail($request->get('user')); + $user_name = Helpers::displayName($user, false); + if(is_null($slot->user)) { - $username = Helpers::displayName($user); + $concurrent_slot_warning = $this->warnIfConcurrentSlotForUserExists($request, $slot, $user, true); + if($concurrent_slot_warning) + { + return back(); + } $slot->user_id=$user->id; $slot->save(); event(new SlotChanged($slot, ['status' => 'taken', 'admin_assigned' => true, 'name' => $user->name, 'email' => $user->email])); - $request->session()->flash('success', 'You added '.$username.' to this shift'); + $request->session()->flash('success', 'You added '.$user_name.' to this shift'); } return redirect('/event/'.$slot->event->id); } + + /** + * Give a warning, if one hasn't already been delivered, to the client if a + * the user is trying to sign up or an admin is attempting to sign a user + * up for a slot one that overlaps with another slot the user is assigned + * to. + * + * @param Request $request the client request + * @param Slot $slot a currently unoccupied slot + * @param User $user the user that will fill the slot + * @param boolean $admin whether or not this an admin request + * @return Response a warning response or null + */ + private function warnIfConcurrentSlotForUserExists(Request $request, Slot $slot, User $user, $admin=false) + { + //search for all user occupied slots that are concurrent with the given one + $concurrent_slot = Slot::where('user_id', $user->id) + ->where('start_date', $slot->start_date) + ->where('start_time', '<', $slot->end_time) + ->where('end_time', '>', $slot->start_time) + ->first(); + + //check if an overlapping slot for the user exists + if($concurrent_slot) + { + //check if the client has already been warned that the user has a concurrent slot + if(intval($request->input('concurrent-slot-warning-user-id')) !== $user->id) + { + $request->session()->flash('warning', [ + 'layout' => 'concurrent-slot', + 'user' => $user, + 'slot' => $slot, + 'admin' => $admin, + 'user_id' => $user->id, + 'user_name' => Helpers::displayName($user, false), + 'concurrent_slot_id' => $concurrent_slot->id + ]); + return true; + } + } + return false; + } } diff --git a/laravel/database/factories/ScheduleFactory.php b/laravel/database/factories/ScheduleFactory.php index 10bfe2ed..cb2016be 100644 --- a/laravel/database/factories/ScheduleFactory.php +++ b/laravel/database/factories/ScheduleFactory.php @@ -2,6 +2,8 @@ use App\Models\Department; use App\Models\Event; +use App\Models\EventRole; +use App\Models\Role; use App\Models\Schedule; use App\Models\Shift; use Carbon\Carbon; @@ -54,6 +56,10 @@ return $duration->format('H:i:s'); }, 'volunteers' => $faker->numberBetween($volunteer_min, $volunteer_max), + 'dates' => function($schedule) + { + return json_encode([$schedule['start_date'], $schedule['end_date']]); + }, 'department_id' => function ($schedule) { $event_id = function () use ($schedule) @@ -77,3 +83,21 @@ }, ]; }); + +$factory->afterCreating(Schedule::class, function(Schedule $schedule, Faker $faker) +{ + //find the admin role + $volunteer_role = Role::where('name', 'volunteer')->first(); + //if there is no admin role, create it + if (!$volunteer_role) + { + $volunteer_role = factory(Role::class)->create([ + 'name' => 'volunteer', + ]); + } + + $schedule->roles()->save(factory(EventRole::class)->make([ + 'role_id' => $volunteer_role->id, + 'foreign_id' => $schedule->id, + ])); +}); \ No newline at end of file diff --git a/laravel/database/factories/UserFactory.php b/laravel/database/factories/UserFactory.php index 52c3828d..e8410623 100644 --- a/laravel/database/factories/UserFactory.php +++ b/laravel/database/factories/UserFactory.php @@ -12,7 +12,25 @@ 'name' => $faker->unique()->userName, 'email' => $faker->unique()->safeEmail, 'password' => bcrypt($faker->password), - ]; + ]; +}); + +$factory->afterCreating(User::class, function (User $user, Faker $faker) +{ + //find the volunteer role + $volunteer_role = Role::where('name', 'volunteer')->first(); + //if there is no volunteer role, create it + if (!$volunteer_role) + { + $volunteer_role = factory(Role::class)->create([ + 'name' => 'volunteer', + ]); + } + + $user->roles()->save(factory(UserRole::class)->make([ + 'role_id' => $volunteer_role->id, + 'user_id' => $user->id, + ])); }); $factory->afterCreatingState(User::class, 'admin', function (User $user, Faker $faker) diff --git a/laravel/resources/views/app.blade.php b/laravel/resources/views/app.blade.php index b0cb1eb9..cd25a59a 100644 --- a/laravel/resources/views/app.blade.php +++ b/laravel/resources/views/app.blade.php @@ -33,6 +33,16 @@ @endif + @if(Session::has('warning')) +