diff --git a/app/Http/Controllers/Finance/SettlementController.php b/app/Http/Controllers/Finance/SettlementController.php index 1fbb700a..70132713 100644 --- a/app/Http/Controllers/Finance/SettlementController.php +++ b/app/Http/Controllers/Finance/SettlementController.php @@ -12,7 +12,6 @@ use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Http\Response; -use Illuminate\Support\Facades\DB; use Illuminate\View\View; class SettlementController extends Controller @@ -26,7 +25,7 @@ public function __construct( */ public function index(Request $request): View|Response { - if ($request->header('HX-Request') && !$request->header('HX-Boosted')) { + if ($request->header('HX-Request') && ! $request->header('HX-Boosted')) { return response('', 200)->header('HX-Redirect', route('finance.settlement')); } @@ -170,7 +169,7 @@ public function partnerSummary(Request $request): View // 각 파트너별 수당 집계 $partnerIds = $partners->pluck('id')->toArray(); - if (!empty($partnerIds)) { + if (! empty($partnerIds)) { $commissionStats = SalesCommission::selectRaw(' partner_id, SUM(CASE WHEN status = "paid" THEN partner_commission ELSE 0 END) as paid_total, @@ -215,7 +214,7 @@ public function customerTab(Request $request): View if ($search = $request->input('search')) { $query->where(function ($q) use ($search) { $q->whereHas('tenant', fn ($tq) => $tq->where('company_name', 'like', "%{$search}%")) - ->orWhereHas('tenantProspect', fn ($pq) => $pq->where('company_name', 'like', "%{$search}%")); + ->orWhereHas('tenantProspect', fn ($pq) => $pq->where('company_name', 'like', "%{$search}%")); }); } @@ -228,9 +227,9 @@ public function customerTab(Request $request): View if ($partnerId = $request->input('partner_id')) { $query->where(function ($q) use ($partnerId) { $q->where('sales_partner_id', $partnerId) - ->orWhereHas('tenantProspect.registeredBy.salesPartner', function ($sq) use ($partnerId) { - $sq->where('id', $partnerId); - }); + ->orWhereHas('tenantProspect.registeredBy.salesPartner', function ($sq) use ($partnerId) { + $sq->where('id', $partnerId); + }); }); } @@ -245,10 +244,11 @@ public function customerTab(Request $request): View $managements->getCollection()->filter(function ($mgmt) use ($paymentStatus) { $depositPaid = $mgmt->deposit_status === 'paid'; $balancePaid = $mgmt->balance_status === 'paid'; + return match ($paymentStatus) { 'fully_paid' => $depositPaid && $balancePaid, - 'partial' => ($depositPaid || $balancePaid) && !($depositPaid && $balancePaid), - 'unpaid' => !$depositPaid && !$balancePaid, + 'partial' => ($depositPaid || $balancePaid) && ! ($depositPaid && $balancePaid), + 'unpaid' => ! $depositPaid && ! $balancePaid, default => true, }; }) @@ -264,7 +264,7 @@ public function customerTab(Request $request): View ->toArray(); $subscriptionFees = []; - if (!empty($tenantIds)) { + if (! empty($tenantIds)) { $subscriptionFees = SalesContractProduct::whereIn('tenant_id', $tenantIds) ->selectRaw('tenant_id, SUM(subscription_fee) as total_subscription_fee') ->groupBy('tenant_id') @@ -305,13 +305,13 @@ public function subscriptionTab(Request $request): View 'tenant', 'tenantProspect', 'salesPartner.user', 'manager', 'contractProducts.product', 'contractProducts.category', ]) - ->where('hq_status', 'handover'); + ->where('hq_status', 'handover'); // 검색 필터 if ($search = $request->input('search')) { $query->where(function ($q) use ($search) { - $q->whereHas('tenant', fn($t) => $t->where('company_name', 'like', "%{$search}%")) - ->orWhereHas('tenantProspect', fn($t) => $t->where('company_name', 'like', "%{$search}%")); + $q->whereHas('tenant', fn ($t) => $t->where('company_name', 'like', "%{$search}%")) + ->orWhereHas('tenantProspect', fn ($t) => $t->where('company_name', 'like', "%{$search}%")); }); } @@ -320,8 +320,8 @@ public function subscriptionTab(Request $request): View // 통계 계산 $stats = [ 'activeCount' => $managements->count(), - 'monthlyRecurring' => $managements->sum(fn($m) => $m->contractProducts->sum('subscription_fee')), - 'totalProducts' => $managements->sum(fn($m) => $m->contractProducts->where('subscription_fee', '>', 0)->count()), + 'monthlyRecurring' => $managements->sum(fn ($m) => $m->contractProducts->sum('subscription_fee')), + 'totalProducts' => $managements->sum(fn ($m) => $m->contractProducts->where('subscription_fee', '>', 0)->count()), ]; $stats['yearlyRecurring'] = $stats['monthlyRecurring'] * 12; @@ -392,7 +392,7 @@ public function paymentPartnerDetail(int $partnerId): View */ public function paymentStats(Request $request): View|Response { - if ($request->header('HX-Request') && !$request->header('HX-Boosted')) { + if ($request->header('HX-Request') && ! $request->header('HX-Boosted')) { return response('', 200)->header('HX-Redirect', route('finance.settlement.payment-stats')); } @@ -445,8 +445,8 @@ public function paymentStats(Request $request): View|Response if ($search) { $query->where(function ($q) use ($search) { $q->whereHas('partner.user', fn ($uq) => $uq->where('name', 'like', "%{$search}%")) - ->orWhereHas('partner', fn ($pq) => $pq->where('partner_code', 'like', "%{$search}%")) - ->orWhereHas('management.tenant', fn ($tq) => $tq->where('company_name', 'like', "%{$search}%")); + ->orWhereHas('partner', fn ($pq) => $pq->where('partner_code', 'like', "%{$search}%")) + ->orWhereHas('management.tenant', fn ($tq) => $tq->where('company_name', 'like', "%{$search}%")); }); } @@ -538,11 +538,11 @@ private function getMonthlyTrend(\Closure $baseQuery, Carbon $startDate, Carbon private function getTypeRatio(\Closure $baseQuery): ?object { return $baseQuery() - ->selectRaw(" + ->selectRaw(' SUM(partner_commission) as partner_total, SUM(manager_commission) as manager_total, SUM(COALESCE(referrer_commission, 0)) as referrer_total - ") + ') ->first(); } @@ -575,11 +575,11 @@ private function getTopPartners(\Closure $baseQuery): array private function getStatusDistribution(\Closure $baseQuery): \Illuminate\Support\Collection { return $baseQuery() - ->selectRaw(" + ->selectRaw(' status, COUNT(*) as count, SUM(partner_commission + manager_commission + COALESCE(referrer_commission, 0)) as amount - ") + ') ->groupBy('status') ->get(); } @@ -602,37 +602,39 @@ private function getMonthlyComparison(\Closure $baseQuery, Carbon $startDate, Ca } /** - * 파트너별 결산 테이블 + * 파트너별 결산 테이블 (개별 건 포함) */ private function getPartnerSettlement(\Closure $baseQuery): \Illuminate\Support\Collection { $data = $baseQuery() - ->selectRaw(" - partner_id, - COUNT(*) as contract_count, - SUM(CASE WHEN payment_type = 'deposit' THEN partner_commission ELSE 0 END) as first_commission, - SUM(CASE WHEN payment_type = 'balance' THEN partner_commission ELSE 0 END) as second_commission, - SUM(partner_commission) as total_partner, - SUM(CASE WHEN status = 'paid' THEN partner_commission + manager_commission + COALESCE(referrer_commission, 0) ELSE 0 END) as paid_amount, - SUM(CASE WHEN status IN ('pending','approved') THEN partner_commission + manager_commission + COALESCE(referrer_commission, 0) ELSE 0 END) as unpaid_amount, - SUM(partner_commission + manager_commission + COALESCE(referrer_commission, 0)) as total_amount - ") - ->groupBy('partner_id') - ->orderByDesc('total_amount') + ->with(['partner.user', 'management.tenant']) + ->select([ + 'id', 'partner_id', 'management_id', 'payment_type', + 'partner_commission', 'manager_commission', 'referrer_commission', + 'status', 'scheduled_payment_date', + ]) + ->orderBy('partner_id') + ->orderBy('scheduled_payment_date') ->get(); - $partnerInfo = SalesPartner::with('user') - ->whereIn('id', $data->pluck('partner_id')) - ->get() - ->keyBy('id'); + $commissionTotal = fn ($item) => $item->partner_commission + $item->manager_commission + ($item->referrer_commission ?? 0); - return $data->map(function ($row) use ($partnerInfo) { - $partner = $partnerInfo->get($row->partner_id); - $row->partner_name = $partner?->user?->name ?? 'N/A'; - $row->partner_type = $partner?->partner_type ?? ''; - $row->completion_rate = $row->total_amount > 0 ? round(($row->paid_amount / $row->total_amount) * 100, 1) : 0; - return $row; - }); + return $data->groupBy('partner_id')->map(function ($items, $partnerId) use ($commissionTotal) { + $partner = $items->first()->partner; + + return (object) [ + 'partner_id' => $partnerId, + 'partner_name' => $partner?->user?->name ?? 'N/A', + 'partner_type' => $partner?->partner_type ?? '', + 'items' => $items, + 'contract_count' => $items->count(), + 'first_commission' => $items->where('payment_type', 'deposit')->sum($commissionTotal), + 'second_commission' => $items->where('payment_type', 'balance')->sum($commissionTotal), + 'total_amount' => $items->sum($commissionTotal), + 'paid_amount' => $items->where('status', 'paid')->sum($commissionTotal), + 'unpaid_amount' => $items->whereIn('status', ['pending', 'approved'])->sum($commissionTotal), + ]; + })->sortByDesc('total_amount')->values(); } /** @@ -661,6 +663,7 @@ private function getManagerSettlement(\Closure $baseQuery): \Illuminate\Support\ $manager = $managerInfo->get($row->manager_user_id); $row->manager_name = $manager?->name ?? 'N/A'; $row->completion_rate = $row->total_manager > 0 ? round(($row->paid_amount / $row->total_manager) * 100, 1) : 0; + return $row; }); } @@ -681,8 +684,8 @@ private function getCustomerStats(): array ->where('deposit_status', 'paid') ->sum('deposit_amount') + (clone $baseQuery) - ->where('balance_status', 'paid') - ->sum('balance_amount'); + ->where('balance_status', 'paid') + ->sum('balance_amount'); // 미수금 $uncollectedAmount = $totalFee - $collectedAmount; diff --git a/resources/views/finance/settlement/payment-stats.blade.php b/resources/views/finance/settlement/payment-stats.blade.php index 4d191317..275ff579 100644 --- a/resources/views/finance/settlement/payment-stats.blade.php +++ b/resources/views/finance/settlement/payment-stats.blade.php @@ -380,78 +380,113 @@ class="px-6 py-3 border-b-2 text-sm font-medium transition-colors"> - {{-- 파트너별 결산 테이블 --}} + {{-- 파트너별 결산 테이블 (개별 건 표시) --}}
| 파트너 | -유형 | -건수 | -1차수당 | -2차수당 | -총수당 | -지급완료 | -미지급 | -완료율 | +구분 | +고객사 | +파트너수당 | +매니저수당 | +유치수당 | +소계 | +상태 | |||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| {{ $row->partner_name }} | -
-
- {{ $row->partner_type === 'corporate' ? '법인' : '개인' }}
+ {{-- 파트너 헤더행 --}}
+ |
+ {{ $group->partner_name }}
+
+ {{ $group->partner_type === 'corporate' ? '법인' : '개인' }}
|
- {{ $row->contract_count }}건 |
- {{ number_format($row->first_commission) }}원 |
- {{ number_format($row->second_commission) }}원 |
- {{ number_format($row->total_amount) }}원 |
- {{ number_format($row->paid_amount) }}원 |
- {{ number_format($row->unpaid_amount) }}원 |
-
- |
-
-
+ {{ $group->contract_count }}건 |
+
+ 총 {{ number_format($group->total_amount) }}원
+
+ (지급 {{ number_format($group->paid_amount) }}원 / 미지급 {{ number_format($group->unpaid_amount) }}원)
+
+ |
+
+ |
+
+
- {{ $row->completion_rate }}%
+ {{ $completionRate }}%
└ |
+
+
+ {{ $item->payment_type === 'deposit' ? '계약금' : '잔금' }}
+
+ |
+ {{ $item->management?->tenant?->company_name ?? '-' }} |
+ {{ number_format($item->partner_commission) }}원 |
+ {{ number_format($item->manager_commission) }}원 |
+ {{ number_format($item->referrer_commission ?? 0) }}원 |
+ {{ number_format($itemTotal) }}원 |
+
+ @switch($item->status)
+ @case('paid')
+ 지급완료
+ @break
+ @case('approved')
+ 승인
+ @break
+ @case('pending')
+ 대기
+ @break
+ @case('cancelled')
+ 취소
+ @break
+ @endswitch
+ |
+ 해당 기간의 데이터가 없습니다. |
+ 해당 기간의 데이터가 없습니다. |
합계 |
- |
- {{ $pCount }}건 |
- {{ number_format($pFirst) }}원 |
- {{ number_format($pSecond) }}원 |
- {{ number_format($pTotal) }}원 |
- {{ number_format($pPaid) }}원 |
- {{ number_format($pUnpaid) }}원 |
-
- |
-
+ {{ $gCount }}건 |
+ {{ number_format($gPartner) }}원 |
+ {{ number_format($gManager) }}원 |
+ {{ number_format($gReferrer) }}원 |
+ {{ number_format($gTotal) }}원 |
+
+ |
+
| |||||||||||||||||||