validate([ 'start_date' => 'nullable|date', 'end_date' => 'nullable|date|after_or_equal:start_date', 'card_id' => 'nullable|integer', 'search' => 'nullable|string|max:100', 'sort_by' => 'nullable|in:used_at,amount,merchant_name,created_at', 'sort_dir' => 'nullable|in:asc,desc', 'per_page' => 'nullable|integer|min:1|max:100', 'page' => 'nullable|integer|min:1', ]); return $this->service->index($params); }, __('message.fetched')); } /** * 카드 거래 요약 통계 */ public function summary(Request $request): JsonResponse { return ApiResponse::handle(function () use ($request) { $params = $request->validate([ 'start_date' => 'nullable|date', 'end_date' => 'nullable|date|after_or_equal:start_date', ]); return $this->service->summary($params); }, __('message.fetched')); } /** * 계정과목 일괄 수정 */ public function bulkUpdateAccountCode(Request $request): JsonResponse { return ApiResponse::handle(function () use ($request) { $validated = $request->validate([ 'ids' => 'required|array|min:1', 'ids.*' => 'required|integer', 'account_code' => 'required|string|max:20', ]); $updatedCount = $this->service->bulkUpdateAccountCode( $validated['ids'], $validated['account_code'] ); return ['updated_count' => $updatedCount]; }, __('message.updated')); } /** * 단일 카드 거래 조회 */ public function show(int $id): JsonResponse { return ApiResponse::handle(function () use ($id) { $transaction = $this->service->show($id); if (! $transaction) { throw new \Illuminate\Database\Eloquent\ModelNotFoundException; } return $transaction; }, __('message.fetched')); } }