feat:영업파트너 유치 현황 대시보드 탭 추가

- SalesDashboardController에 partnerActivity() 메서드 추가
- 유치 파트너 요약 통계 (파트너 수, 영업권, 계약, 예상수당)
- 파트너별 상세 활동 테이블 (펼침/접기 기능)
- 기존 대시보드에 탭 UI 통합 (내 활동 / 유치 파트너 현황)
- HTMX로 탭 콘텐츠 지연 로드

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
pro
2026-01-31 16:15:50 +09:00
parent ac9c156257
commit 9d00064165
4 changed files with 406 additions and 4 deletions

View File

@@ -311,6 +311,149 @@ public function getManagers(Request $request): JsonResponse
]);
}
/**
* 유치 파트너 활동 현황 (HTMX 탭 로드)
*/
public function partnerActivity(Request $request): View
{
$data = $this->getPartnerActivityData();
return view('sales.dashboard.partials.partner-activity', $data);
}
/**
* 유치 파트너 활동 데이터 조회
*/
private function getPartnerActivityData(): array
{
$currentUser = auth()->user();
$currentUserId = $currentUser->id;
// 직접 유치한 하위 파트너 목록 (parent_id가 현재 사용자인 사용자들)
$recruitedPartners = User::where('parent_id', $currentUserId)
->where('is_active', true)
->with(['userRoles.role'])
->get();
$partnerIds = $recruitedPartners->pluck('id')->toArray();
// 요약 통계 계산
$summaryStats = $this->calculatePartnerSummaryStats($partnerIds, $currentUserId);
// 파트너별 상세 활동 데이터
$partnerActivities = $this->getPartnerActivitiesDetail($recruitedPartners, $currentUserId);
return [
'summaryStats' => $summaryStats,
'partnerActivities' => $partnerActivities,
'recruitedPartners' => $recruitedPartners,
];
}
/**
* 유치 파트너 요약 통계 계산
*/
private function calculatePartnerSummaryStats(array $partnerIds, int $currentUserId): array
{
// 유치 파트너 수
$partnerCount = count($partnerIds);
// 하위 파트너들이 등록한 총 영업권(명함) 수
$totalProspects = TenantProspect::whereIn('registered_by', $partnerIds)->count();
// 하위 파트너들의 계약 성사 건수
$totalConversions = TenantProspect::whereIn('registered_by', $partnerIds)
->where('status', TenantProspect::STATUS_CONVERTED)
->count();
// 매니저로서 받을 수당 (내가 매니저로 지정된 수당 중 하위 파트너 관련)
$expectedCommission = SalesCommission::where('manager_user_id', $currentUserId)
->whereHas('partner', function ($query) use ($partnerIds) {
$query->whereIn('user_id', $partnerIds);
})
->sum('manager_commission');
return [
'partner_count' => $partnerCount,
'total_prospects' => $totalProspects,
'total_conversions' => $totalConversions,
'expected_commission' => $expectedCommission,
];
}
/**
* 파트너별 상세 활동 데이터
*/
private function getPartnerActivitiesDetail($recruitedPartners, int $currentUserId): array
{
$activities = [];
foreach ($recruitedPartners as $partner) {
// 파트너의 영업파트너 정보
$salesPartner = SalesPartner::where('user_id', $partner->id)->first();
// 파트너가 등록한 영업권 수
$prospectCount = TenantProspect::where('registered_by', $partner->id)->count();
// 진행 중인 영업권 (active 상태)
$activeProspects = TenantProspect::where('registered_by', $partner->id)
->where('status', TenantProspect::STATUS_ACTIVE)
->count();
// 계약 성사 건수
$conversions = TenantProspect::where('registered_by', $partner->id)
->where('status', TenantProspect::STATUS_CONVERTED)
->count();
// 이 파트너로 인한 나의 매니저 수당
$managerCommission = 0;
if ($salesPartner) {
$managerCommission = SalesCommission::where('manager_user_id', $currentUserId)
->where('partner_id', $salesPartner->id)
->sum('manager_commission');
}
// 최근 활동 내역 (최근 전환된 테넌트 5개)
$recentTenants = TenantProspect::where('registered_by', $partner->id)
->where('status', TenantProspect::STATUS_CONVERTED)
->with(['tenant'])
->orderBy('converted_at', 'desc')
->limit(5)
->get();
// 활동 상태 판단
$lastActivity = TenantProspect::where('registered_by', $partner->id)
->orderBy('updated_at', 'desc')
->first();
$status = 'inactive';
if ($lastActivity) {
$daysSinceActivity = now()->diffInDays($lastActivity->updated_at);
if ($daysSinceActivity <= 7) {
$status = 'active';
} elseif ($daysSinceActivity <= 30) {
$status = 'moderate';
}
}
// 역할 정보
$roles = $partner->userRoles->pluck('role.name')->filter()->toArray();
$roleLabel = !empty($roles) ? implode(', ', $roles) : '영업';
$activities[] = [
'partner' => $partner,
'role_label' => $roleLabel,
'prospect_count' => $prospectCount,
'active_prospects' => $activeProspects,
'conversions' => $conversions,
'manager_commission' => $managerCommission,
'status' => $status,
'recent_tenants' => $recentTenants,
];
}
return $activities;
}
/**
* 영업파트너 수당 정보 조회
*/