feat:수당 지급 탭 + 수당지급현황통계 페이지 추가

- 정산관리에 수당 지급 탭 추가 (파트너별 그룹핑 지급 대기 목록)
- 파트너별 상세 건 목록 HTMX 확장 기능
- 수당지급현황통계 페이지 (Chart.js 4개 차트 + 월별 요약 테이블)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
김보곤
2026-02-19 10:39:52 +09:00
parent 8f308b8877
commit 981c3c68d4
6 changed files with 860 additions and 4 deletions

View File

@@ -180,6 +180,143 @@ public function subscriptionTab(Request $request): View
return view('finance.settlement.partials.subscription-tab');
}
/**
* 수당 지급 탭 (파트너별 그룹핑)
*/
public function paymentTab(Request $request): View
{
// approved 상태 수당을 partner_id 기준 GROUP BY
$partnerPayments = SalesCommission::where('status', SalesCommission::STATUS_APPROVED)
->selectRaw('
partner_id,
GROUP_CONCAT(id) as commission_ids,
COUNT(*) as count,
SUM(partner_commission) as partner_total,
SUM(manager_commission) as manager_total,
SUM(COALESCE(referrer_commission, 0)) as referrer_total
')
->groupBy('partner_id')
->get();
// 파트너 정보 eager load
$partners = SalesPartner::with('user')
->whereIn('id', $partnerPayments->pluck('partner_id'))
->get()
->keyBy('id');
// 통계 카드 데이터
$now = now();
$paymentStats = [
'waiting_count' => $partnerPayments->sum('count'),
'waiting_amount' => $partnerPayments->sum(fn ($p) => $p->partner_total + $p->manager_total + $p->referrer_total),
'this_month_paid_count' => SalesCommission::where('status', SalesCommission::STATUS_PAID)
->whereYear('actual_payment_date', $now->year)
->whereMonth('actual_payment_date', $now->month)
->count(),
'this_month_paid_amount' => SalesCommission::where('status', SalesCommission::STATUS_PAID)
->whereYear('actual_payment_date', $now->year)
->whereMonth('actual_payment_date', $now->month)
->selectRaw('SUM(partner_commission + manager_commission + COALESCE(referrer_commission, 0)) as total')
->value('total') ?? 0,
'partner_total' => $partnerPayments->sum('partner_total'),
'manager_referrer_total' => $partnerPayments->sum('manager_total') + $partnerPayments->sum('referrer_total'),
];
return view('finance.settlement.partials.payment-tab', compact('partnerPayments', 'partners', 'paymentStats'));
}
/**
* 파트너별 수당 건 상세 (HTMX partial)
*/
public function paymentPartnerDetail(int $partnerId): View
{
$commissions = SalesCommission::where('status', SalesCommission::STATUS_APPROVED)
->where('partner_id', $partnerId)
->with(['management.tenant', 'manager'])
->orderBy('scheduled_payment_date')
->get();
return view('finance.settlement.partials.payment-partner-detail', compact('commissions', 'partnerId'));
}
/**
* 수당지급현황통계 페이지
*/
public function paymentStats(Request $request): View|Response
{
if ($request->header('HX-Request') && !$request->header('HX-Boosted')) {
return response('', 200)->header('HX-Redirect', route('finance.settlement.payment-stats'));
}
$year = (int) $request->input('year', now()->year);
// 통계 카드
$totalPaidAmount = SalesCommission::where('status', SalesCommission::STATUS_PAID)
->whereYear('actual_payment_date', $year)
->selectRaw('SUM(partner_commission + manager_commission + COALESCE(referrer_commission, 0)) as total')
->value('total') ?? 0;
$totalPaidCount = SalesCommission::where('status', SalesCommission::STATUS_PAID)
->whereYear('actual_payment_date', $year)
->count();
$activePartners = SalesCommission::where('status', SalesCommission::STATUS_PAID)
->whereYear('actual_payment_date', $year)
->distinct('partner_id')
->count('partner_id');
$avgCommission = $totalPaidCount > 0 ? round($totalPaidAmount / $totalPaidCount) : 0;
$statsCards = [
'total_paid_amount' => $totalPaidAmount,
'total_paid_count' => $totalPaidCount,
'active_partners' => $activePartners,
'avg_commission' => $avgCommission,
];
// 차트 1 & 4: 월별 지급 추이 (해당 연도)
$monthlyTrend = SalesCommission::where('status', SalesCommission::STATUS_PAID)
->whereYear('actual_payment_date', $year)
->selectRaw("
DATE_FORMAT(actual_payment_date, '%Y-%m') as month,
SUM(partner_commission) as partner_total,
SUM(manager_commission) as manager_total,
SUM(COALESCE(referrer_commission, 0)) as referrer_total,
COUNT(*) as count
")
->groupByRaw("DATE_FORMAT(actual_payment_date, '%Y-%m')")
->orderBy('month')
->get();
// 차트 2: 수당 유형별 비율
$typeRatio = SalesCommission::where('status', SalesCommission::STATUS_PAID)
->whereYear('actual_payment_date', $year)
->selectRaw("
SUM(partner_commission) as partner_total,
SUM(manager_commission) as manager_total,
SUM(COALESCE(referrer_commission, 0)) as referrer_total
")
->first();
// 차트 3: 파트너별 수당 Top 10
$topPartners = SalesCommission::where('status', SalesCommission::STATUS_PAID)
->whereYear('actual_payment_date', $year)
->selectRaw('partner_id, SUM(partner_commission + manager_commission + COALESCE(referrer_commission, 0)) as total')
->groupBy('partner_id')
->orderByDesc('total')
->limit(10)
->get();
$topPartnerNames = SalesPartner::with('user')
->whereIn('id', $topPartners->pluck('partner_id'))
->get()
->keyBy('id');
return view('finance.settlement.payment-stats', compact(
'year', 'statsCards', 'monthlyTrend', 'typeRatio', 'topPartners', 'topPartnerNames'
));
}
/**
* 통합 통계 데이터
*/