$query */ public static function applyToJobsQuery(Builder $query, AdminUser $admin): void { if ($admin->isSuperAdmin()) { return; } $siteIds = $admin->accessibleAdminSiteIds(); if ($siteIds === null) { return; } if ($siteIds === []) { $query->whereRaw('0 = 1'); return; } $siteCodes = AdminSite::query() ->whereIn('id', $siteIds) ->pluck('code') ->map(static fn ($code): string => (string) $code) ->all(); $agent = AdminAgentScope::primaryAgentNode($admin); $query->where(function (Builder $outer) use ($siteIds, $siteCodes, $agent): void { $outer->whereIn('admin_site_id', $siteIds); if ($siteCodes !== []) { $outer->orWhere(function (Builder $legacy) use ($siteCodes, $agent): void { $legacy->whereNull('admin_site_id') ->whereHas('items', function (Builder $items) use ($siteCodes, $agent): void { self::applyItemsTransferPlayerScope($items, $siteCodes, $agent); }); }); } }); if ($agent instanceof AgentNode) { $query->whereHas('items', function (Builder $items) use ($agent): void { self::applyItemsAgentSubtree($items, $agent); }); } } public static function jobAccessible(AdminUser $admin, ReconcileJob $job): bool { if ($admin->isSuperAdmin()) { return true; } $siteIds = $admin->accessibleAdminSiteIds(); if ($siteIds === null) { return true; } if ($siteIds === []) { return false; } $jobSiteId = $job->admin_site_id !== null ? (int) $job->admin_site_id : null; if ($jobSiteId !== null) { if (! in_array($jobSiteId, $siteIds, true)) { return false; } } else { $siteCodes = AdminSite::query() ->whereIn('id', $siteIds) ->pluck('code') ->map(static fn ($code): string => (string) $code) ->all(); $hasScopedItem = $job->items() ->where(function (Builder $items) use ($siteCodes, $admin): void { $agent = AdminAgentScope::primaryAgentNode($admin); self::applyItemsTransferPlayerScope($items, $siteCodes, $agent); }) ->exists(); if (! $hasScopedItem) { return false; } } $agent = AdminAgentScope::primaryAgentNode($admin); if ($agent === null) { return true; } return $job->items() ->where(function (Builder $items) use ($agent): void { self::applyItemsAgentSubtree($items, $agent); }) ->exists(); } public static function resolveAdminSiteIdForJob(AdminUser $admin, ?Player $player = null): ?int { if ($player !== null) { $siteId = AdminSite::query() ->where('code', (string) $player->site_code) ->value('id'); return $siteId !== null ? (int) $siteId : null; } if ($admin->isSuperAdmin()) { return null; } $agent = AdminAgentScope::primaryAgentNode($admin); if ($agent !== null) { return (int) $agent->admin_site_id; } $siteIds = $admin->accessibleAdminSiteIds(); return $siteIds[0] ?? null; } public static function denyUnlessJobAccessible(AdminUser $admin, ReconcileJob $job): ?JsonResponse { if (! self::jobAccessible($admin, $job)) { return ApiMessage::errorResponse( request(), 'admin.reconcile_job_access_denied', ErrorCode::AdminForbidden->value, null, 403, ); } return null; } /** * @param Builder<\App\Models\ReconcileItem> $query * @param list $siteCodes */ public static function applyItemsTransferPlayerScope( Builder $query, array $siteCodes, ?AgentNode $agent = null, ): void { if ($siteCodes === []) { $query->whereRaw('0 = 1'); return; } $query->whereExists(function ($sub) use ($siteCodes, $agent): void { $sub->selectRaw('1') ->from('transfer_orders') ->join('players', 'players.id', '=', 'transfer_orders.player_id') ->whereColumn('transfer_orders.transfer_no', 'reconcile_items.side_a_ref'); $sub->whereIn('players.site_code', $siteCodes); if ($agent instanceof AgentNode) { $sub->whereIn('players.agent_node_id', function ($nodes) use ($agent): void { $nodes->select('id') ->from('agent_nodes') ->where('path', 'like', $agent->path.'%'); }); } }); } /** * @param Builder<\App\Models\ReconcileItem> $query */ private static function applyItemsAgentSubtree(Builder $query, AgentNode $agent): void { $query->whereExists(function ($sub) use ($agent): void { $sub->selectRaw('1') ->from('transfer_orders') ->join('players', 'players.id', '=', 'transfer_orders.player_id') ->whereColumn('transfer_orders.transfer_no', 'reconcile_items.side_a_ref') ->whereIn('players.agent_node_id', function ($nodes) use ($agent): void { $nodes->select('id') ->from('agent_nodes') ->where('path', 'like', $agent->path.'%'); }); }); } }