diff --git a/app/Http/Controllers/Sales/SalesManagerController.php b/app/Http/Controllers/Sales/SalesManagerController.php index 1d62eab7..5eb0bc9f 100644 --- a/app/Http/Controllers/Sales/SalesManagerController.php +++ b/app/Http/Controllers/Sales/SalesManagerController.php @@ -332,4 +332,81 @@ public function deleteDocument(int $id, int $documentId) return redirect()->back() ->with('success', '서류가 삭제되었습니다.'); } + + /** + * 영업파트너 승인 목록 (본사 관리자 전용) + */ + public function approvals(Request $request): View|Response + { + // 권한 체크: admin 역할만 접근 가능 + if (!auth()->user()->isAdmin()) { + abort(403, '접근 권한이 없습니다.'); + } + + if ($request->header('HX-Request')) { + return response('', 200)->header('HX-Redirect', route('sales.managers.approvals')); + } + + $filters = [ + 'search' => $request->get('search'), + 'approval_status' => 'pending', // 승인 대기만 + ]; + + $partners = $this->service->getSalesPartners($filters)->paginate(20); + $stats = $this->service->getApprovalStats(); + + return view('sales.managers.approvals', compact('partners', 'stats')); + } + + /** + * 승인 목록에서 승인 처리 + */ + public function approveFromList(Request $request, int $id) + { + // 권한 체크 + if (!auth()->user()->isAdmin()) { + abort(403, '접근 권한이 없습니다.'); + } + + $partner = User::findOrFail($id); + $this->service->approve($partner, auth()->id()); + + if ($request->header('HX-Request')) { + return response()->json([ + 'success' => true, + 'message' => "{$partner->name}님이 승인되었습니다.", + ]); + } + + return redirect()->route('sales.managers.approvals') + ->with('success', "{$partner->name}님이 승인되었습니다."); + } + + /** + * 승인 목록에서 반려 처리 + */ + public function rejectFromList(Request $request, int $id) + { + // 권한 체크 + if (!auth()->user()->isAdmin()) { + abort(403, '접근 권한이 없습니다.'); + } + + $validated = $request->validate([ + 'rejection_reason' => 'required|string|max:1000', + ]); + + $partner = User::findOrFail($id); + $this->service->reject($partner, auth()->id(), $validated['rejection_reason']); + + if ($request->header('HX-Request')) { + return response()->json([ + 'success' => true, + 'message' => "{$partner->name}님이 반려되었습니다.", + ]); + } + + return redirect()->route('sales.managers.approvals') + ->with('success', "{$partner->name}님이 반려되었습니다."); + } } diff --git a/app/Services/Sales/SalesManagerService.php b/app/Services/Sales/SalesManagerService.php index 1a25036b..270b9d6e 100644 --- a/app/Services/Sales/SalesManagerService.php +++ b/app/Services/Sales/SalesManagerService.php @@ -491,6 +491,34 @@ public function getStats(?int $parentId = null): array ]; } + /** + * 승인 대기 통계 조회 (본사 관리자용) + */ + public function getApprovalStats(): array + { + $tenantId = session('selected_tenant_id', 1); + + $baseQuery = User::query() + ->whereHas('userRoles', function ($q) use ($tenantId) { + $q->where('tenant_id', $tenantId) + ->whereHas('role', function ($rq) { + $rq->whereIn('name', self::SALES_ROLES); + }); + }); + + return [ + 'pending' => (clone $baseQuery)->where('approval_status', 'pending')->count(), + 'approved_today' => (clone $baseQuery) + ->where('approval_status', 'approved') + ->whereDate('approved_at', today()) + ->count(), + 'rejected_today' => (clone $baseQuery) + ->where('approval_status', 'rejected') + ->whereDate('approved_at', today()) + ->count(), + ]; + } + /** * 파트너의 계층 레벨 계산 */ diff --git a/resources/views/sales/managers/approvals.blade.php b/resources/views/sales/managers/approvals.blade.php new file mode 100644 index 00000000..d5a82c77 --- /dev/null +++ b/resources/views/sales/managers/approvals.blade.php @@ -0,0 +1,335 @@ +@extends('layouts.app') + +@section('title', '영업파트너 승인') + +@section('content') +
영업파트너 가입 신청을 검토하고 승인/반려합니다
+| 신청자 | +아이디 | +역할 | +연락처 | +추천인(유치자) | +신청일 | +처리 | +
|---|---|---|---|---|---|---|
|
+ {{ $partner->name }}
+ @if($partner->email)
+ {{ $partner->email }}
+ @endif
+ |
+ + {{ $partner->user_id ?? '-' }} + | +
+
+ @foreach($partner->userRoles as $userRole)
+ @php
+ $roleColor = match($userRole->role->name ?? '') {
+ 'sales' => 'bg-blue-100 text-blue-800',
+ 'manager' => 'bg-purple-100 text-purple-800',
+ 'recruiter' => 'bg-green-100 text-green-800',
+ default => 'bg-gray-100 text-gray-800',
+ };
+ $roleLabel = match($userRole->role->name ?? '') {
+ 'sales' => '영업',
+ 'manager' => '매니저',
+ 'recruiter' => '유치담당',
+ default => $userRole->role->name ?? '-',
+ };
+ @endphp
+
+ {{ $roleLabel }}
+
+ @endforeach
+
+ |
+ + {{ $partner->phone ?? '-' }} + | ++ @if($partner->parent) + {{ $partner->parent->name }} + @else + - + @endif + | ++ {{ $partner->created_at->format('Y-m-d H:i') }} + | +
+
+
+
+
+
+ |
+
| + 승인 대기 중인 영업파트너가 없습니다. + | +||||||
+ 님의 가입 신청을 반려합니다. +
+ +로딩 중...
+