tenantId(); $page = (int) ($params['page'] ?? 1); $size = (int) ($params['size'] ?? 20); $q = trim((string) ($params['q'] ?? '')); $onlyActive = $params['only_active'] ?? null; $query = Client::query()->where('tenant_id', $tenantId); if ($q !== '') { $query->where(function ($qq) use ($q) { $qq->where('name', 'like', "%{$q}%") ->orWhere('client_code', 'like', "%{$q}%") ->orWhere('contact_person', 'like', "%{$q}%"); }); } if ($onlyActive !== null) { $query->where('is_active', (bool) $onlyActive); } $query->orderBy('client_code')->orderBy('id'); return $query->paginate($size, ['*'], 'page', $page); } /** 단건 */ public function show(int $id) { $tenantId = $this->tenantId(); $client = Client::where('tenant_id', $tenantId)->find($id); if (! $client) { throw new NotFoundHttpException(__('error.not_found')); } return $client; } /** 생성 */ public function store(array $data) { $tenantId = $this->tenantId(); // client_code 자동 생성 (프론트에서 보내도 무시) $data['client_code'] = $this->generateClientCode($tenantId); $data['tenant_id'] = $tenantId; $data['is_active'] = $data['is_active'] ?? true; return Client::create($data); } /** * 유니크한 client_code 자동 생성 * 형식: 8자리 영숫자 (예: A3B7X9K2) */ private function generateClientCode(int $tenantId): string { $maxAttempts = 10; $attempt = 0; do { // 8자리 영숫자 코드 생성 (대문자 + 숫자) $code = strtoupper(substr(bin2hex(random_bytes(4)), 0, 8)); // 중복 검사 $exists = Client::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('client_code', $code) ->exists(); $attempt++; } while ($exists && $attempt < $maxAttempts); if ($exists) { // 극히 드문 경우: timestamp 추가하여 유니크성 보장 $code = strtoupper(substr(bin2hex(random_bytes(2)), 0, 4).dechex(time() % 0xFFFF)); } return $code; } /** 수정 */ public function update(int $id, array $data) { $tenantId = $this->tenantId(); $client = Client::where('tenant_id', $tenantId)->find($id); if (! $client) { throw new NotFoundHttpException(__('error.not_found')); } // client_code 변경 불가 (프론트에서 보내도 무시) unset($data['client_code']); $client->update($data); return $client->refresh(); } /** 삭제 */ public function destroy(int $id) { $tenantId = $this->tenantId(); $client = Client::where('tenant_id', $tenantId)->find($id); if (! $client) { throw new NotFoundHttpException(__('error.not_found')); } // 주문 존재 검사 if ($client->orders()->exists()) { throw new BadRequestHttpException(__('error.has_orders')); } $client->delete(); return 'success'; } /** 활성/비활성 토글 */ public function toggle(int $id) { $tenantId = $this->tenantId(); $client = Client::where('tenant_id', $tenantId)->find($id); if (! $client) { throw new NotFoundHttpException(__('error.not_found')); } $client->is_active = ! $client->is_active; $client->save(); return $client->refresh(); } }