input('q', ''); $users = DB::table('users') ->join('user_tenants', function ($join) use ($tenantId) { $join->on('users.id', '=', 'user_tenants.user_id') ->where('user_tenants.tenant_id', $tenantId) ->where('user_tenants.is_active', true); }) ->leftJoin('tenant_user_profiles as tp', function ($join) use ($tenantId) { $join->on('tp.user_id', '=', 'users.id') ->where('tp.tenant_id', $tenantId); }) ->leftJoin('departments', 'departments.id', '=', 'tp.department_id') ->whereNull('users.deleted_at') ->where(function ($q) { $q->whereNull('tp.employee_status') ->orWhere('tp.employee_status', '!=', 'resigned'); }) ->when($query, function ($q) use ($query) { $q->where(function ($sub) use ($query) { $sub->where('users.name', 'like', "%{$query}%") ->orWhere('departments.name', 'like', "%{$query}%"); }); }) ->orderBy('users.name') ->limit(30) ->select([ 'users.id', 'users.name', 'departments.name as department', 'tp.position_key as position', ]) ->get(); return response()->json([ 'success' => true, 'data' => $users, ]); } /** * 테넌트 전체 인원 목록 (부서별 그룹핑, 결재선 에디터용) */ public function list(): JsonResponse { $tenantId = session('selected_tenant_id'); $users = DB::table('users') ->join('user_tenants', function ($join) use ($tenantId) { $join->on('users.id', '=', 'user_tenants.user_id') ->where('user_tenants.tenant_id', $tenantId) ->where('user_tenants.is_active', true); }) ->leftJoin('tenant_user_profiles as tp', function ($join) use ($tenantId) { $join->on('tp.user_id', '=', 'users.id') ->where('tp.tenant_id', $tenantId); }) ->leftJoin('departments', 'departments.id', '=', 'tp.department_id') ->leftJoin('positions as pos_rank', function ($join) use ($tenantId) { $join->on('pos_rank.tenant_id', '=', DB::raw($tenantId)) ->where('pos_rank.type', 'rank') ->whereRaw('pos_rank.`key` COLLATE utf8mb4_unicode_ci = tp.position_key COLLATE utf8mb4_unicode_ci'); }) ->leftJoin('positions as pos_title', function ($join) use ($tenantId) { $join->on('pos_title.tenant_id', '=', DB::raw($tenantId)) ->where('pos_title.type', 'title') ->whereRaw('pos_title.`key` COLLATE utf8mb4_unicode_ci = tp.job_title_key COLLATE utf8mb4_unicode_ci'); }) ->whereNull('users.deleted_at') ->whereNotNull('tp.department_id') ->where(function ($q) { $q->whereNull('tp.employee_status') ->orWhere('tp.employee_status', '!=', 'resigned'); }) ->when($tenantId == 1, function ($q) { $q->where('departments.name', '!=', '영업팀'); }) ->orderBy('departments.name') ->orderByRaw('COALESCE(pos_rank.sort_order, pos_title.sort_order, 9999) ASC') ->orderBy('users.name') ->select([ 'users.id', 'users.name', 'tp.department_id', 'departments.name as department_name', DB::raw('COALESCE(pos_rank.name, tp.position_key, \'\') as position'), DB::raw('COALESCE(pos_title.name, tp.job_title_key, \'\') as job_title'), ]) ->get(); $grouped = $users->groupBy(fn ($u) => $u->department_id ?? 'none'); $data = []; foreach ($grouped as $deptId => $deptUsers) { $first = $deptUsers->first(); $data[] = [ 'department_id' => $deptId === 'none' ? null : (int) $deptId, 'department_name' => $deptId === 'none' ? '미배정' : $first->department_name, 'users' => $deptUsers->map(fn ($u) => [ 'id' => $u->id, 'name' => $u->name, 'position' => $u->position, 'job_title' => $u->job_title, ])->values()->toArray(), ]; } // 미배정 그룹을 마지막으로 usort($data, function ($a, $b) { if ($a['department_id'] === null) { return 1; } if ($b['department_id'] === null) { return -1; } return strcmp($a['department_name'], $b['department_name']); }); return response()->json([ 'success' => true, 'data' => $data, ]); } }