feat:영업파트너 고객관리 메뉴 추가 (관리자 전용)
- AdminProspectController 생성 (관리자/슈퍼관리자만 접근) - 전체 영업파트너의 고객 현황을 한눈에 파악 - 영업파트너별 필터, 상태별 필터 제공 - 영업/매니저 진행률 및 개발 상태 표시 - 상세 모달에서 담당자 정보 및 진행 현황 확인 - AdminProspectMenuSeeder 생성 (메뉴 추가용) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
133
app/Http/Controllers/Sales/AdminProspectController.php
Normal file
133
app/Http/Controllers/Sales/AdminProspectController.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Sales;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Sales\SalesScenarioChecklist;
|
||||
use App\Models\Sales\SalesTenantManagement;
|
||||
use App\Models\Sales\TenantProspect;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\View\View;
|
||||
|
||||
/**
|
||||
* 관리자용 전체 영업파트너 고객 관리 컨트롤러
|
||||
* 관리자/슈퍼관리자만 접근 가능
|
||||
*/
|
||||
class AdminProspectController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
// 관리자 권한 체크 미들웨어
|
||||
$this->middleware(function ($request, $next) {
|
||||
if (!auth()->user()->isAdmin() && !auth()->user()->isSuperAdmin()) {
|
||||
abort(403, '관리자만 접근할 수 있습니다.');
|
||||
}
|
||||
return $next($request);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 전체 고객 목록 페이지
|
||||
*/
|
||||
public function index(Request $request): View|Response
|
||||
{
|
||||
if ($request->header('HX-Request')) {
|
||||
return response('', 200)->header('HX-Redirect', route('sales.admin-prospects.index'));
|
||||
}
|
||||
|
||||
// 영업 역할을 가진 사용자 목록 (영업파트너)
|
||||
$salesPartners = User::whereHas('userRoles', function ($q) {
|
||||
$q->whereHas('role', function ($rq) {
|
||||
$rq->whereIn('name', ['sales', 'manager', 'recruiter']);
|
||||
});
|
||||
})->orderBy('name')->get();
|
||||
|
||||
// 필터
|
||||
$filters = [
|
||||
'search' => $request->get('search'),
|
||||
'status' => $request->get('status'),
|
||||
'registered_by' => $request->get('registered_by'), // 특정 영업파트너 필터
|
||||
];
|
||||
|
||||
// 쿼리 빌드
|
||||
$query = TenantProspect::with(['registeredBy', 'tenant']);
|
||||
|
||||
// 검색
|
||||
if (!empty($filters['search'])) {
|
||||
$search = $filters['search'];
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('company_name', 'like', "%{$search}%")
|
||||
->orWhere('business_number', 'like', "%{$search}%")
|
||||
->orWhere('ceo_name', 'like', "%{$search}%")
|
||||
->orWhere('contact_phone', 'like', "%{$search}%");
|
||||
});
|
||||
}
|
||||
|
||||
// 상태 필터
|
||||
if (!empty($filters['status'])) {
|
||||
$query->where('status', $filters['status']);
|
||||
}
|
||||
|
||||
// 영업파트너 필터
|
||||
if (!empty($filters['registered_by'])) {
|
||||
$query->where('registered_by', $filters['registered_by']);
|
||||
}
|
||||
|
||||
$prospects = $query->orderByDesc('created_at')->paginate(20);
|
||||
|
||||
// 각 가망고객의 진행률 계산
|
||||
foreach ($prospects as $prospect) {
|
||||
$progress = SalesScenarioChecklist::getProspectProgress($prospect->id);
|
||||
$prospect->sales_progress = $progress['sales']['percentage'];
|
||||
$prospect->manager_progress = $progress['manager']['percentage'];
|
||||
|
||||
// management 정보
|
||||
$management = SalesTenantManagement::where('tenant_prospect_id', $prospect->id)->first();
|
||||
$prospect->hq_status = $management?->hq_status ?? 'pending';
|
||||
$prospect->hq_status_label = $management?->hq_status_label ?? '대기';
|
||||
$prospect->manager_user = $management?->manager;
|
||||
}
|
||||
|
||||
// 전체 통계
|
||||
$stats = [
|
||||
'total' => TenantProspect::count(),
|
||||
'active' => TenantProspect::where('status', TenantProspect::STATUS_ACTIVE)->count(),
|
||||
'expired' => TenantProspect::where('status', TenantProspect::STATUS_EXPIRED)->count(),
|
||||
'converted' => TenantProspect::where('status', TenantProspect::STATUS_CONVERTED)->count(),
|
||||
];
|
||||
|
||||
// 영업파트너별 통계
|
||||
$partnerStats = TenantProspect::selectRaw('registered_by, COUNT(*) as total')
|
||||
->groupBy('registered_by')
|
||||
->with('registeredBy')
|
||||
->get()
|
||||
->map(function ($item) {
|
||||
return [
|
||||
'user' => $item->registeredBy,
|
||||
'total' => $item->total,
|
||||
];
|
||||
});
|
||||
|
||||
return view('sales.admin-prospects.index', compact('prospects', 'stats', 'salesPartners', 'partnerStats', 'filters'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 고객 상세 모달
|
||||
*/
|
||||
public function modalShow(int $id): View
|
||||
{
|
||||
$prospect = TenantProspect::with(['registeredBy', 'tenant'])->findOrFail($id);
|
||||
|
||||
// 진행률
|
||||
$progress = SalesScenarioChecklist::getProspectProgress($prospect->id);
|
||||
$prospect->sales_progress = $progress['sales']['percentage'];
|
||||
$prospect->manager_progress = $progress['manager']['percentage'];
|
||||
|
||||
// management 정보
|
||||
$management = SalesTenantManagement::findOrCreateByProspect($prospect->id);
|
||||
|
||||
return view('sales.admin-prospects.partials.show-modal', compact('prospect', 'management', 'progress'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user