From a29c31b817b5c52dba2792d7cdcb3d647f9eb84c Mon Sep 17 00:00:00 2001 From: Fenrikur <3359222+Fenrikur@users.noreply.github.com> Date: Thu, 1 Feb 2024 23:17:58 +0100 Subject: [PATCH] feat(invite): simplify seat calculation and visualisation --- .../Applications/InviteesController.php | 10 +-- .../ForceOverseatingRedirectMiddleware.php | 18 ++-- app/Models/Application.php | 63 +++++++++----- .../views/application/invitees.blade.php | 83 ++++++++++++++----- 4 files changed, 121 insertions(+), 53 deletions(-) diff --git a/app/Http/Controllers/Applications/InviteesController.php b/app/Http/Controllers/Applications/InviteesController.php index 713f556..fa28b8d 100644 --- a/app/Http/Controllers/Applications/InviteesController.php +++ b/app/Http/Controllers/Applications/InviteesController.php @@ -17,6 +17,7 @@ class InviteesController extends Controller public function view() { $user = Auth::user(); + /** @var Application */ $application = $user->application; abort_if($application->type !== ApplicationType::Dealer, 403, 'Shares and Assistants cannot manage this.'); @@ -33,14 +34,11 @@ public function view() return view('application.invitees', [ 'application' => $application, + 'seats' => $application->getSeats(), 'currentSeats' => $application->children()->whereNotNull('canceled_at')->count() + 1, 'maxSeats' => $application->requestedTable->seats, - "assistants" => $application->children()->where('type', ApplicationType::Assistant)->with('user')->get(), - "shares" => $application->children()->where('type', ApplicationType::Share)->with('user')->get(), - "shares_count" => $application->getAvailableShares(), - "assistants_count" => $application->getAvailableAssistants(), - "shares_active_count" => $application->getActiveShares(), - "assistants_active_count" => $application->getActiveAssistants(), + 'assistants' => $application->assistants()->get(), + 'shares' => $application->shares()->get(), ]); } diff --git a/app/Http/Middleware/ForceOverseatingRedirectMiddleware.php b/app/Http/Middleware/ForceOverseatingRedirectMiddleware.php index 55a27d4..a4e23d5 100644 --- a/app/Http/Middleware/ForceOverseatingRedirectMiddleware.php +++ b/app/Http/Middleware/ForceOverseatingRedirectMiddleware.php @@ -3,26 +3,30 @@ namespace App\Http\Middleware; use App\Enums\ApplicationType; +use App\Models\Application; use Closure; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Redirect; +use Illuminate\Support\Facades\Route; class ForceOverseatingRedirectMiddleware { public function handle(Request $request, Closure $next) { - if(\Route::is('applications.invitees.*')) { + if(Route::is('applications.invitees.*')) { return $next($request); } - $application = \Auth::user()->application; - if(is_null($application) || $application->type !== ApplicationType::Dealer || !is_null($application->canceled_at)) { + /** @var Application */ + $application = Auth::user()->application; + if(is_null($application) || $application->type !== ApplicationType::Dealer || !$application->isActive()) { return $next($request); } - $isTooManyAssistant = $application?->getFreeShares() < 0; - $isTooManyShare = $application?->getFreeAssistants() < 0; - if($isTooManyAssistant || $isTooManyShare) { - return \Redirect::route('applications.invitees.view'); + $seats = $application->getSeats(); + if($seats['free'] < 0) { + return Redirect::route('applications.invitees.view'); } return $next($request); } diff --git a/app/Models/Application.php b/app/Models/Application.php index 436bdf1..c6c5f3c 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -210,38 +210,59 @@ public function cancel() $this->save(); } - public function getActiveShares(): int + public function shares() { - return $this->children()->whereNull('canceled_at')->where('type', ApplicationType::Share)->count(); + return $this->children()->whereNull('canceled_at')->where('type', ApplicationType::Share); } - public function getActiveAssistants(): int + public function assistants() { - return $this->children()->whereNull('canceled_at')->where('type', ApplicationType::Assistant)->count(); + return $this->children()->whereNull('canceled_at')->where('type', ApplicationType::Assistant); } - public function getAvailableShares(): int + public function getSeats(): array { - if (is_null($this->requestedTable)) { - return 0; + /** @var TableType */ + $tableType = $this->assignedTable ?? $this->requestedTable; + if (is_null($tableType) || !$this->isActive()) { + return [ + 'table' => 0, + 'dealers' => 0, + 'assistants' => 0, + 'free' => 0, + 'additional' => null, + ]; } - $countedAssistants = $this->getActiveShares() < $this->requestedTable->seats - 1 ? $this->getActiveAssistants() : max($this->getActiveAssistants() - 1, 0); - return !is_null($this->requestedTable) ? max($this->requestedTable->seats - 1 - $countedAssistants, 0) : 0; - } - public function getAvailableAssistants(): int - { - return !is_null($this->requestedTable) ? max(1, $this->requestedTable->seats - 1 - $this->getActiveShares()) : 0; - } + $totalSeats = $tableType->seats; - public function getFreeShares(): int - { - return !is_null($this->requestedTable) ? $this->getAvailableShares() - $this->getActiveShares() : 0; - } + $dealers = $this->shares()->count() + 1; + $assistants = $this->assistants()->count(); + $additional = null; - public function getFreeAssistants(): int - { - return $this->getAvailableAssistants() - $this->children()->whereNull('canceled_at')->where('type', ApplicationType::Assistant)->count(); + if ($totalSeats - $dealers <= 0 && $assistants === 0) { + // Single assistant is available even if table is filled with dealers. + $additional = 'assistant'; + } + + if ($totalSeats - $dealers === 1 && $assistants === 1) { + // Single assistant doesn't consume dealer seat and results in free dealer-only seat. + $additional = 'dealer'; + } + + $free = $totalSeats - $dealers - $assistants; + if ($free < 0 && $assistants === 1) { + // Free seat count should not be negative because of minimum assistant. + $free += 1; + } + + return [ + 'table' => $totalSeats, + 'dealers' => $dealers, + 'assistants' => $assistants, + 'free' => $free, + 'additional' => $additional, + ]; } public function getStatusAttribute() diff --git a/resources/views/application/invitees.blade.php b/resources/views/application/invitees.blade.php index 6fdeadc..b1914e8 100644 --- a/resources/views/application/invitees.blade.php +++ b/resources/views/application/invitees.blade.php @@ -3,6 +3,17 @@ Shares and Assistants @endsection @section('content') +

Manage Shares and Assistants

@@ -17,26 +28,62 @@
The user has been removed.
@endif - @if ($assistants_active_count <= $assistants_count && $shares_active_count <= $shares_count) + @if ($seats['free'] >= 0) @endif +
+

Seats in your Dealership

+
+ @for ($i = 0; $i < $seats['dealers']; $i++) + + @endfor + @for ($i = 0; $i < $seats['free']; $i++) + + @endfor + @if (!is_null($seats['additional'])) + + @endif + @for ($i = 0; $i < $seats['assistants']; $i++) + + @endfor +
+
+ Legend: + Dealer + Free + @if (!is_null($seats['additional'])) + Free* ({{ ucfirst($seats['additional']) }}) + @endif + Assistant +
+
+ @if ($seats['free'] < 0) +
+ You have too many people in your dealership for the number of + seats available for your table size.
+ Please remove excess shares or assistants. +
+ @endif
- @if ($shares_active_count > $shares_count) -
You have too many dealers for your table size.
Please remove - dealers.
- @endif -
+
-
{{ $shares_active_count }}/{{ $shares_count }} Share your - space with other dealers
+
+ Share your space with other dealers +
    - @if ($shares_active_count < $shares_count && Carbon\Carbon::parse(config('con.reg_end_date'))->isFuture()) + @if ( + ($seats['free'] > 0 || $seats['additional'] === 'dealer') && + Carbon\Carbon::parse(config('con.reg_end_date'))->isFuture())
  • @csrf @@ -76,18 +123,16 @@ class="badge bg-secondary">{{ $shares_active_count }}/{{ $shares_count }}
- @if ($assistants_active_count > $assistants_count) -
You have too many assistants for your table size.
Please - remove assistants.
- @endif -
+
-
{{ $assistants_active_count }}/{{ $assistants_count }} - Invite assistants to your space
+
+ Invite assistants to your space +
    - @if ($assistants_active_count < $assistants_count && Carbon\Carbon::parse(config('con.assistant_end_date'))->isFuture()) + @if ( + ($seats['free'] > 0 || $seats['additional'] === 'assistant') && + Carbon\Carbon::parse(config('con.assistant_end_date'))->isFuture())
  • @csrf