inYear((int) $params['year']); } // 카테고리 필터 if (! empty($params['category']) && $params['category'] !== 'all') { $query->byCategory($params['category']); } // 통합 검색 if (! empty($params['search'])) { $search = $params['search']; $query->where(function ($q) use ($search) { $q->where('partner_name', 'like', "%{$search}%") ->orWhere('description', 'like', "%{$search}%") ->orWhere('memo', 'like', "%{$search}%"); }); } // 정렬 $sortBy = $params['sort_by'] ?? 'event_date'; $sortOrder = $params['sort_order'] ?? 'desc'; $query->orderBy($sortBy, $sortOrder)->orderByDesc('id'); $perPage = $params['per_page'] ?? 50; return $query->paginate($perPage); } /** * 상세 조회 */ public function show(int $id): CondolenceExpense { return CondolenceExpense::with('creator:id,name')->findOrFail($id); } /** * 등록 */ public function store(array $data): CondolenceExpense { $tenantId = $this->tenantId(); $userId = $this->apiUserId(); return DB::transaction(function () use ($data, $tenantId, $userId) { return CondolenceExpense::create([ 'tenant_id' => $tenantId, 'event_date' => $data['event_date'] ?? null, 'expense_date' => $data['expense_date'] ?? null, 'partner_name' => $data['partner_name'], 'description' => $data['description'] ?? null, 'category' => $data['category'], 'has_cash' => $data['has_cash'] ?? false, 'cash_method' => ($data['has_cash'] ?? false) ? ($data['cash_method'] ?? null) : null, 'cash_amount' => ($data['has_cash'] ?? false) ? ($data['cash_amount'] ?? 0) : 0, 'has_gift' => $data['has_gift'] ?? false, 'gift_type' => ($data['has_gift'] ?? false) ? ($data['gift_type'] ?? null) : null, 'gift_amount' => ($data['has_gift'] ?? false) ? ($data['gift_amount'] ?? 0) : 0, 'total_amount' => $this->calculateTotal($data), 'memo' => $data['memo'] ?? null, 'created_by' => $userId, 'updated_by' => $userId, ]); }); } /** * 수정 */ public function update(int $id, array $data): CondolenceExpense { $userId = $this->apiUserId(); return DB::transaction(function () use ($id, $data, $userId) { $expense = CondolenceExpense::findOrFail($id); $expense->fill([ 'event_date' => $data['event_date'] ?? $expense->event_date, 'expense_date' => $data['expense_date'] ?? $expense->expense_date, 'partner_name' => $data['partner_name'] ?? $expense->partner_name, 'description' => $data['description'] ?? $expense->description, 'category' => $data['category'] ?? $expense->category, 'has_cash' => $data['has_cash'] ?? $expense->has_cash, 'cash_method' => ($data['has_cash'] ?? $expense->has_cash) ? ($data['cash_method'] ?? $expense->cash_method) : null, 'cash_amount' => ($data['has_cash'] ?? $expense->has_cash) ? ($data['cash_amount'] ?? $expense->cash_amount) : 0, 'has_gift' => $data['has_gift'] ?? $expense->has_gift, 'gift_type' => ($data['has_gift'] ?? $expense->has_gift) ? ($data['gift_type'] ?? $expense->gift_type) : null, 'gift_amount' => ($data['has_gift'] ?? $expense->has_gift) ? ($data['gift_amount'] ?? $expense->gift_amount) : 0, 'total_amount' => $this->calculateTotal(array_merge($expense->toArray(), $data)), 'memo' => $data['memo'] ?? $expense->memo, 'updated_by' => $userId, ]); $expense->save(); return $expense->fresh(); }); } /** * 삭제 (소프트) */ public function destroy(int $id): bool { $userId = $this->apiUserId(); return DB::transaction(function () use ($id, $userId) { $expense = CondolenceExpense::findOrFail($id); $expense->deleted_by = $userId; $expense->save(); $expense->delete(); return true; }); } /** * 통계 조회 */ public function summary(array $params): array { $query = CondolenceExpense::query(); if (! empty($params['year'])) { $query->inYear((int) $params['year']); } if (! empty($params['category']) && $params['category'] !== 'all') { $query->byCategory($params['category']); } $stats = $query->selectRaw(' COUNT(*) as total_count, COALESCE(SUM(total_amount), 0) as total_amount, COALESCE(SUM(cash_amount), 0) as cash_total, COALESCE(SUM(gift_amount), 0) as gift_total, COALESCE(SUM(CASE WHEN category = ? THEN 1 ELSE 0 END), 0) as congratulation_count, COALESCE(SUM(CASE WHEN category = ? THEN 1 ELSE 0 END), 0) as condolence_count, COALESCE(SUM(CASE WHEN category = ? THEN total_amount ELSE 0 END), 0) as congratulation_amount, COALESCE(SUM(CASE WHEN category = ? THEN total_amount ELSE 0 END), 0) as condolence_amount ', [ CondolenceExpense::CATEGORY_CONGRATULATION, CondolenceExpense::CATEGORY_CONDOLENCE, CondolenceExpense::CATEGORY_CONGRATULATION, CondolenceExpense::CATEGORY_CONDOLENCE, ])->first(); return [ 'total_count' => (int) $stats->total_count, 'total_amount' => (int) $stats->total_amount, 'cash_total' => (int) $stats->cash_total, 'gift_total' => (int) $stats->gift_total, 'congratulation_count' => (int) $stats->congratulation_count, 'condolence_count' => (int) $stats->condolence_count, 'congratulation_amount' => (int) $stats->congratulation_amount, 'condolence_amount' => (int) $stats->condolence_amount, ]; } /** * 총금액 자동 계산 */ private function calculateTotal(array $data): int { $cash = ($data['has_cash'] ?? false) ? (int) ($data['cash_amount'] ?? 0) : 0; $gift = ($data['has_gift'] ?? false) ? (int) ($data['gift_amount'] ?? 0) : 0; return $cash + $gift; } }