with(['userHavingAccess' => function ($q) { $q->where('users.user_type', 'user')->where('users.allow_login', 1); }]) ->findOrFail($contact_id); $users = collect($contact->userHavingAccess); if ($users->isEmpty()) { $users = $this->specialistsFromProjects($business_id, $contact_id); } if ($users->isEmpty()) { $users = $this->specialistsFromMaintenance($business_id, $contact_id); } if ($users->isEmpty()) { $users = $this->fallbackSpecialists($business_id); } return $users->unique('id')->values()->map(function (User $user) { return [ 'id' => $user->id, 'name' => trim($user->surname.' '.$user->first_name.' '.$user->last_name), 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'email' => $user->email, 'mobile' => $user->contact_no, 'username' => $user->username, ]; }); } public function assertSpecialistForContact(int $business_id, int $contact_id, int $specialist_id): User { $specialists = $this->specialistsForContact($business_id, $contact_id); $match = $specialists->firstWhere('id', $specialist_id); if (! $match) { abort(403, 'Unauthorized action.'); } return User::where('business_id', $business_id) ->where('id', $specialist_id) ->where('user_type', 'user') ->firstOrFail(); } private function specialistsFromProjects(int $business_id, int $contact_id): Collection { if (! Schema::hasTable('pjt_projects') || ! Schema::hasTable('pjt_project_members')) { return collect(); } $projectIds = Project::where('business_id', $business_id) ->where('contact_id', $contact_id) ->pluck('id'); if ($projectIds->isEmpty()) { return collect(); } $leadIds = Project::whereIn('id', $projectIds) ->whereNotNull('lead_id') ->pluck('lead_id'); $memberIds = DB::table('pjt_project_members') ->whereIn('project_id', $projectIds) ->pluck('user_id'); $userIds = $leadIds->merge($memberIds)->unique()->filter(); if ($userIds->isEmpty()) { return collect(); } return User::where('business_id', $business_id) ->whereIn('id', $userIds) ->where('user_type', 'user') ->where('allow_login', 1) ->get(); } private function specialistsFromMaintenance(int $business_id, int $contact_id): Collection { if (! Schema::hasTable('maintenance_equipment') || ! Schema::hasTable('maintenance_field_missions')) { return collect(); } $equipmentIds = Equipment::where('business_id', $business_id) ->where('customer_id', $contact_id) ->pluck('id'); if ($equipmentIds->isEmpty()) { return collect(); } $leadIds = FieldMission::where('business_id', $business_id) ->whereIn('equipment_id', $equipmentIds) ->whereNotNull('lead_user_id') ->pluck('lead_user_id') ->unique(); if ($leadIds->isEmpty()) { return collect(); } return User::where('business_id', $business_id) ->whereIn('id', $leadIds) ->where('user_type', 'user') ->where('allow_login', 1) ->get(); } private function fallbackSpecialists(int $business_id): Collection { $ownerId = Business::where('id', $business_id)->value('owner_id'); $query = User::where('business_id', $business_id) ->where('user_type', 'user') ->where('allow_login', 1); if ($ownerId) { $owner = (clone $query)->where('id', $ownerId)->first(); if ($owner) { return collect([$owner]); } } return $query->orderBy('id')->limit(3)->get(); } }