feat:정산관리 기간설정 체크박스 필터 추가 (시작~끝 년월 범위 조회)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
김보곤
2026-02-20 14:11:21 +09:00
parent a945c63a83
commit fb47badb18
3 changed files with 155 additions and 21 deletions

View File

@@ -35,19 +35,38 @@ public function index(Request $request): View|Response
// 수당 정산 탭 데이터 (기본 탭이므로 즉시 로드)
$year = $request->input('year', now()->year);
$month = $request->input('month', now()->month);
$dateRange = $request->boolean('date_range');
$filters = [
'scheduled_year' => $year,
'scheduled_month' => $month,
'status' => $request->input('status'),
'payment_type' => $request->input('payment_type'),
'partner_id' => $request->input('partner_id'),
'commission_type' => $request->input('commission_type'),
'search' => $request->input('search'),
'date_range' => $dateRange,
];
if ($dateRange) {
$filters['scheduled_start_year'] = (int) $request->input('start_year', $year);
$filters['scheduled_start_month'] = (int) $request->input('start_month', $month);
$filters['scheduled_end_year'] = (int) $request->input('end_year', $year);
$filters['scheduled_end_month'] = (int) $request->input('end_month', $month);
$filters['start_year'] = $filters['scheduled_start_year'];
$filters['start_month'] = $filters['scheduled_start_month'];
$filters['end_year'] = $filters['scheduled_end_year'];
$filters['end_month'] = $filters['scheduled_end_month'];
} else {
$filters['scheduled_year'] = $year;
$filters['scheduled_month'] = $month;
}
$commissions = $this->service->getCommissions($filters);
$stats = $this->service->getSettlementStats($year, $month);
$stats = $dateRange
? $this->service->getSettlementStatsForRange(
$filters['scheduled_start_year'], $filters['scheduled_start_month'],
$filters['scheduled_end_year'], $filters['scheduled_end_month']
)
: $this->service->getSettlementStats($year, $month);
$partners = SalesPartner::with('user')
->active()
@@ -91,10 +110,9 @@ public function commissionTable(Request $request): View
{
$year = $request->input('year', now()->year);
$month = $request->input('month', now()->month);
$dateRange = $request->boolean('date_range');
$filters = [
'scheduled_year' => $year,
'scheduled_month' => $month,
'status' => $request->input('status'),
'payment_type' => $request->input('payment_type'),
'partner_id' => $request->input('partner_id'),
@@ -102,6 +120,16 @@ public function commissionTable(Request $request): View
'search' => $request->input('search'),
];
if ($dateRange) {
$filters['scheduled_start_year'] = (int) $request->input('start_year', $year);
$filters['scheduled_start_month'] = (int) $request->input('start_month', $month);
$filters['scheduled_end_year'] = (int) $request->input('end_year', $year);
$filters['scheduled_end_month'] = (int) $request->input('end_month', $month);
} else {
$filters['scheduled_year'] = $year;
$filters['scheduled_month'] = $month;
}
$commissions = $this->service->getCommissions($filters);
return view('finance.settlement.partials.commission.table', compact('commissions'));

View File

@@ -61,8 +61,15 @@ public function getCommissions(array $filters = [], int $perPage = 20): LengthAw
$query->where('manager_user_id', $filters['manager_user_id']);
}
// 지급예정 년/월 필터
if (!empty($filters['scheduled_year']) && !empty($filters['scheduled_month'])) {
// 지급예정 기간 범위 필터
if (!empty($filters['scheduled_start_year']) && !empty($filters['scheduled_start_month'])
&& !empty($filters['scheduled_end_year']) && !empty($filters['scheduled_end_month'])) {
$startDate = \Carbon\Carbon::create($filters['scheduled_start_year'], $filters['scheduled_start_month'], 1)->startOfMonth();
$endDate = \Carbon\Carbon::create($filters['scheduled_end_year'], $filters['scheduled_end_month'], 1)->endOfMonth();
$query->whereBetween('scheduled_payment_date', [$startDate, $endDate]);
}
// 지급예정 년/월 필터 (단일)
elseif (!empty($filters['scheduled_year']) && !empty($filters['scheduled_month'])) {
$query->forScheduledMonth((int) $filters['scheduled_year'], (int) $filters['scheduled_month']);
}
@@ -530,6 +537,41 @@ public function getSettlementStats(int $year, int $month): array
];
}
/**
* 정산 통계 (기간 범위)
*/
public function getSettlementStatsForRange(int $startYear, int $startMonth, int $endYear, int $endMonth): array
{
$startDate = \Carbon\Carbon::create($startYear, $startMonth, 1)->startOfMonth();
$endDate = \Carbon\Carbon::create($endYear, $endMonth, 1)->endOfMonth();
$commissions = SalesCommission::whereBetween('scheduled_payment_date', [$startDate, $endDate])->get();
return [
'pending' => [
'count' => $commissions->where('status', SalesCommission::STATUS_PENDING)->count(),
'partner_total' => $commissions->where('status', SalesCommission::STATUS_PENDING)->sum('partner_commission'),
'manager_total' => $commissions->where('status', SalesCommission::STATUS_PENDING)->sum('manager_commission'),
],
'approved' => [
'count' => $commissions->where('status', SalesCommission::STATUS_APPROVED)->count(),
'partner_total' => $commissions->where('status', SalesCommission::STATUS_APPROVED)->sum('partner_commission'),
'manager_total' => $commissions->where('status', SalesCommission::STATUS_APPROVED)->sum('manager_commission'),
],
'paid' => [
'count' => $commissions->where('status', SalesCommission::STATUS_PAID)->count(),
'partner_total' => $commissions->where('status', SalesCommission::STATUS_PAID)->sum('partner_commission'),
'manager_total' => $commissions->where('status', SalesCommission::STATUS_PAID)->sum('manager_commission'),
],
'total' => [
'count' => $commissions->count(),
'base_amount' => $commissions->sum('base_amount'),
'partner_commission' => $commissions->sum('partner_commission'),
'manager_commission' => $commissions->sum('manager_commission'),
],
];
}
/**
* 입금 대기 중인 테넌트 목록
*/

View File

@@ -3,22 +3,72 @@
<form id="filter-form" method="GET" action="{{ route('finance.settlement') }}">
<input type="hidden" name="tab" value="commission">
<div class="flex flex-wrap items-end gap-3">
<div class="w-[calc(50%-6px)] sm:w-auto sm:min-w-[100px]">
<label class="block text-xs font-medium text-gray-500 mb-1">년도</label>
<select name="year" class="w-full rounded-lg border-gray-300 text-sm focus:border-emerald-500 focus:ring-emerald-500">
@for ($y = now()->year - 2; $y <= now()->year + 1; $y++)
<option value="{{ $y }}" {{ $year == $y ? 'selected' : '' }}>{{ $y }}</option>
@endfor
</select>
{{-- 기간설정 체크박스 --}}
<div class="flex items-center self-end pb-2">
<label class="flex items-center gap-1.5 cursor-pointer select-none">
<input type="checkbox" name="date_range" value="1"
{{ !empty($filters['date_range']) ? 'checked' : '' }}
onchange="toggleDateRange(this.checked)"
class="rounded border-gray-300 text-emerald-600 focus:ring-emerald-500">
<span class="text-xs font-medium text-gray-600 whitespace-nowrap">기간설정</span>
</label>
</div>
<div class="w-[calc(50%-6px)] sm:w-auto sm:min-w-[80px]">
<label class="block text-xs font-medium text-gray-500 mb-1"></label>
<select name="month" class="w-full rounded-lg border-gray-300 text-sm focus:border-emerald-500 focus:ring-emerald-500">
@for ($m = 1; $m <= 12; $m++)
<option value="{{ $m }}" {{ $month == $m ? 'selected' : '' }}>{{ $m }}</option>
@endfor
</select>
{{-- 단일 / (기본) --}}
<div id="single-date" class="{{ !empty($filters['date_range']) ? 'hidden' : '' }} flex items-end gap-3">
<div class="w-[calc(50%-6px)] sm:w-auto sm:min-w-[100px]">
<label class="block text-xs font-medium text-gray-500 mb-1">년도</label>
<select name="year" class="w-full rounded-lg border-gray-300 text-sm focus:border-emerald-500 focus:ring-emerald-500">
@for ($y = now()->year - 2; $y <= now()->year + 1; $y++)
<option value="{{ $y }}" {{ $year == $y ? 'selected' : '' }}>{{ $y }}</option>
@endfor
</select>
</div>
<div class="w-[calc(50%-6px)] sm:w-auto sm:min-w-[80px]">
<label class="block text-xs font-medium text-gray-500 mb-1"></label>
<select name="month" class="w-full rounded-lg border-gray-300 text-sm focus:border-emerald-500 focus:ring-emerald-500">
@for ($m = 1; $m <= 12; $m++)
<option value="{{ $m }}" {{ $month == $m ? 'selected' : '' }}>{{ $m }}</option>
@endfor
</select>
</div>
</div>
{{-- 기간 범위 (체크 표시) --}}
<div id="range-date" class="{{ !empty($filters['date_range']) ? '' : 'hidden' }} flex items-end gap-2">
<div class="sm:min-w-[100px]">
<label class="block text-xs font-medium text-gray-500 mb-1">시작</label>
<select name="start_year" class="w-full rounded-lg border-gray-300 text-sm focus:border-emerald-500 focus:ring-emerald-500">
@for ($y = now()->year - 2; $y <= now()->year + 1; $y++)
<option value="{{ $y }}" {{ ($filters['start_year'] ?? $year) == $y ? 'selected' : '' }}>{{ $y }}</option>
@endfor
</select>
</div>
<div class="sm:min-w-[70px]">
<label class="block text-xs font-medium text-gray-500 mb-1">&nbsp;</label>
<select name="start_month" class="w-full rounded-lg border-gray-300 text-sm focus:border-emerald-500 focus:ring-emerald-500">
@for ($m = 1; $m <= 12; $m++)
<option value="{{ $m }}" {{ ($filters['start_month'] ?? $month) == $m ? 'selected' : '' }}>{{ $m }}</option>
@endfor
</select>
</div>
<span class="text-gray-400 pb-2">~</span>
<div class="sm:min-w-[100px]">
<label class="block text-xs font-medium text-gray-500 mb-1">종료</label>
<select name="end_year" class="w-full rounded-lg border-gray-300 text-sm focus:border-emerald-500 focus:ring-emerald-500">
@for ($y = now()->year - 2; $y <= now()->year + 1; $y++)
<option value="{{ $y }}" {{ ($filters['end_year'] ?? $year) == $y ? 'selected' : '' }}>{{ $y }}</option>
@endfor
</select>
</div>
<div class="sm:min-w-[70px]">
<label class="block text-xs font-medium text-gray-500 mb-1">&nbsp;</label>
<select name="end_month" class="w-full rounded-lg border-gray-300 text-sm focus:border-emerald-500 focus:ring-emerald-500">
@for ($m = 1; $m <= 12; $m++)
<option value="{{ $m }}" {{ ($filters['end_month'] ?? $month) == $m ? 'selected' : '' }}>{{ $m }}</option>
@endfor
</select>
</div>
</div>
<div class="w-[calc(50%-6px)] sm:w-auto sm:min-w-[100px]">
@@ -66,3 +116,17 @@ class="px-3 py-2 bg-gray-200 hover:bg-gray-300 text-gray-700 text-sm rounded-lg
</div>
</form>
</div>
<script>
function toggleDateRange(checked) {
document.getElementById('single-date').classList.toggle('hidden', checked);
document.getElementById('range-date').classList.toggle('hidden', !checked);
document.querySelectorAll('#single-date select').forEach(s => s.disabled = checked);
document.querySelectorAll('#range-date select').forEach(s => s.disabled = !checked);
}
document.addEventListener('DOMContentLoaded', function() {
const checked = document.querySelector('input[name="date_range"]')?.checked || false;
document.querySelectorAll('#single-date select').forEach(s => s.disabled = checked);
document.querySelectorAll('#range-date select').forEach(s => s.disabled = !checked);
});
</script>