diff --git a/app/Http/Controllers/Api/V1/ClientController.php b/app/Http/Controllers/Api/V1/ClientController.php index 308bd48..4a22a0b 100644 --- a/app/Http/Controllers/Api/V1/ClientController.php +++ b/app/Http/Controllers/Api/V1/ClientController.php @@ -56,4 +56,32 @@ public function toggle(int $id) return $this->service->toggle($id); }, __('message.client.toggled')); } + + /** + * 거래처 통계 + */ + public function stats() + { + return ApiResponse::handle(function () { + return $this->service->stats(); + }, __('message.fetched')); + } + + /** + * 거래처 일괄 삭제 + */ + public function bulkDestroy(Request $request) + { + $ids = $request->input('ids', []); + + if (empty($ids)) { + return ApiResponse::error(__('error.no_items_selected'), 400); + } + + return ApiResponse::handle(function () use ($ids) { + $deletedCount = $this->service->bulkDestroy($ids); + + return ['deleted_count' => $deletedCount]; + }, __('message.deleted')); + } } diff --git a/app/Services/ClientService.php b/app/Services/ClientService.php index 87484f3..8937118 100644 --- a/app/Services/ClientService.php +++ b/app/Services/ClientService.php @@ -9,7 +9,6 @@ use Illuminate\Support\Facades\DB; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -use App\Services\PushNotificationService; class ClientService extends Service { @@ -224,4 +223,67 @@ public function toggle(int $id) return $client->refresh(); } + + /** + * 거래처 통계 조회 + */ + public function stats(): array + { + $tenantId = $this->tenantId(); + + $total = Client::where('tenant_id', $tenantId)->count(); + + // 거래처 유형별 통계 + $typeCounts = Client::where('tenant_id', $tenantId) + ->selectRaw('client_type, COUNT(*) as count') + ->groupBy('client_type') + ->pluck('count', 'client_type') + ->toArray(); + + // 악성채권 보유 거래처 수 (활성 악성채권이 있는 거래처) + $badDebtClientIds = BadDebt::where('tenant_id', $tenantId) + ->whereIn('status', [BadDebt::STATUS_COLLECTING, BadDebt::STATUS_LEGAL_ACTION]) + ->where('is_active', true) + ->whereNull('deleted_at') + ->distinct('client_id') + ->pluck('client_id'); + + $badDebtCount = Client::where('tenant_id', $tenantId) + ->whereIn('id', $badDebtClientIds) + ->count(); + + return [ + 'total' => $total, + 'sales' => $typeCounts['SALES'] ?? 0, + 'purchase' => $typeCounts['PURCHASE'] ?? 0, + 'both' => $typeCounts['BOTH'] ?? 0, + 'badDebt' => $badDebtCount, + 'normal' => $total - $badDebtCount, + ]; + } + + /** + * 거래처 일괄 삭제 + */ + public function bulkDestroy(array $ids): int + { + $tenantId = $this->tenantId(); + + $clients = Client::where('tenant_id', $tenantId) + ->whereIn('id', $ids) + ->get(); + + $deletedCount = 0; + foreach ($clients as $client) { + // 주문 존재 검사 - 주문 있으면 건너뛰기 + if ($client->orders()->exists()) { + continue; + } + + $client->delete(); + $deletedCount++; + } + + return $deletedCount; + } } diff --git a/routes/api.php b/routes/api.php index 58e6a9c..6a3819b 100644 --- a/routes/api.php +++ b/routes/api.php @@ -921,6 +921,8 @@ // Clients (거래처 관리) Route::prefix('clients')->group(function () { + Route::get('/stats', [ClientController::class, 'stats'])->name('v1.clients.stats'); // 통계 + Route::delete('/bulk', [ClientController::class, 'bulkDestroy'])->name('v1.clients.bulk-destroy'); // 일괄 삭제 Route::get('', [ClientController::class, 'index'])->name('v1.clients.index'); // 목록 Route::post('', [ClientController::class, 'store'])->name('v1.clients.store'); // 생성 Route::get('/{id}', [ClientController::class, 'show'])->whereNumber('id')->name('v1.clients.show'); // 단건