contractor_id)) { return; } // Gather the authenticated user's own contractor ID plus all direct subcontractors $allowedIds = $this->resolveAllowedContractorIds($user->contractor_id); if ($model instanceof \Modules\MasterData\Models\Material) { $sharesCatalog = \DB::table('contractors') ->where('id', $user->contractor_id) ->value('shares_materials_catalog') ?? true; if ($sharesCatalog) { $builder->where(function ($q) use ($model, $allowedIds) { $q->whereIn($model->getTable() . '.contractor_id', $allowedIds) ->orWhereNull($model->getTable() . '.contractor_id'); }); } else { $builder->whereIn($model->getTable() . '.contractor_id', $allowedIds); } } else { $builder->whereIn($model->getTable() . '.contractor_id', $allowedIds); } } finally { self::$resolvingAuth = false; } } /** * Build the set of contractor IDs the current user can access. * This is the user's own contractor plus any direct children (subcontractors). * * We deliberately keep this to one level for performance. If you need full * recursive trees, swap this for a CTE or Spatie-Nested-Set package. */ private function resolveAllowedContractorIds(int $contractorId): array { // Use DB to avoid loading the Contractor model (prevents circular scope boot) $childIds = \DB::table('contractors') ->where('parent_id', $contractorId) ->pluck('id') ->toArray(); return array_merge([$contractorId], $childIds); } }