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', $onlyActive ? 'Y' : 'N'); } $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 $params) { $tenantId = $this->tenantId(); $uid = $this->apiUserId(); $v = Validator::make($params, [ 'client_code' => 'required|string|max:50', 'name' => 'required|string|max:100', 'contact_person' => 'nullable|string|max:50', 'phone' => 'nullable|string|max:30', 'email' => 'nullable|email|max:80', 'address' => 'nullable|string|max:255', 'is_active' => 'nullable|in:Y,N', ]); if ($v->fails()) { throw new BadRequestHttpException($v->errors()->first()); } $data = $v->validated(); // client_code 중복 검사 $exists = Client::where('tenant_id', $tenantId) ->where('client_code', $data['client_code']) ->exists(); if ($exists) { throw new BadRequestHttpException(__('error.duplicate_code')); } $data['tenant_id'] = $tenantId; $data['is_active'] = $data['is_active'] ?? 'Y'; return Client::create($data); } /** 수정 */ public function update(int $id, array $params) { $tenantId = $this->tenantId(); $uid = $this->apiUserId(); $client = Client::where('tenant_id', $tenantId)->find($id); if (!$client) { throw new NotFoundHttpException(__('error.not_found')); } $v = Validator::make($params, [ 'client_code' => 'sometimes|required|string|max:50', 'name' => 'sometimes|required|string|max:100', 'contact_person' => 'nullable|string|max:50', 'phone' => 'nullable|string|max:30', 'email' => 'nullable|email|max:80', 'address' => 'nullable|string|max:255', 'is_active' => 'nullable|in:Y,N', ]); if ($v->fails()) { throw new BadRequestHttpException($v->errors()->first()); } $payload = $v->validated(); // client_code 변경 시 중복 검사 if (isset($payload['client_code']) && $payload['client_code'] !== $client->client_code) { $exists = Client::where('tenant_id', $tenantId) ->where('client_code', $payload['client_code']) ->exists(); if ($exists) { throw new BadRequestHttpException(__('error.duplicate_code')); } } $client->update($payload); 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 === 'Y' ? 'N' : 'Y'; $client->save(); return $client->refresh(); } }