# 영업수수료정산

## 개요

영업수수료정산은 영업파트너와 매니저의 수당을 계산하고 승인/지급하는 기능입니다.
입금 등록 시 수당 자동 계산, 승인 프로세스(대기→승인→지급), 지급 추적, 일괄 처리를 지원합니다.

- **라우트**: `GET /finance/sales-commissions`
- **UI 기술**: Blade + HTMX (부분 업데이트, 모달)
- **컨트롤러**: `SalesCommissionController` (13개 메서드)
- **서비스**: `SalesCommissionService` (핵심 비즈니스 로직)

## 파일 구조

```
mng/
├── app/Http/Controllers/Finance/
│   └── SalesCommissionController.php          # 메인 컨트롤러 (13개 메서드)
├── app/Services/
│   └── SalesCommissionService.php             # 비즈니스 로직 서비스
├── app/Models/Sales/
│   ├── SalesCommission.php                    # 수수료 정산 모델
│   └── SalesCommissionDetail.php              # 상품별 상세 모델
└── resources/views/finance/sales-commission/
    ├── index.blade.php                        # 메인 페이지
    ├── stats-cards.blade.php                  # 통계 카드 (HTMX partial)
    ├── commission-table.blade.php             # 테이블 (HTMX partial)
    └── payment-form.blade.php                 # 입금 등록 폼 (HTMX partial)

api/
└── database/migrations/
    ├── 2026_01_29_170000_create_sales_commissions_table.php
    └── 2026_01_29_170100_create_sales_commission_details_table.php
```

## 라우트

```php
// routes/web.php (finance prefix 그룹 내)
GET    /sales-commissions                → index()          목록 페이지
POST   /sales-commissions/payment        → registerPayment() 입금 등록
GET    /sales-commissions/{id}           → show()           JSON 상세
GET    /sales-commissions/{id}/detail    → detail()         모달 상세 (HTMX)
POST   /sales-commissions/{id}/approve   → approve()        승인
POST   /sales-commissions/{id}/mark-paid → markPaid()       지급완료
POST   /sales-commissions/{id}/cancel    → cancel()         취소
POST   /sales-commissions/bulk-approve   → bulkApprove()    일괄 승인
POST   /sales-commissions/bulk-mark-paid → bulkMarkPaid()   일괄 지급완료
GET    /sales-commissions/table          → table()          테이블 새로고침 (HTMX)
GET    /sales-commissions/stats          → stats()          통계 새로고침 (HTMX)
GET    /sales-commissions/payment-form   → paymentForm()    입금 폼 (HTMX)
GET    /sales-commissions/export         → export()         CSV 다운로드
```

## 컨트롤러

### SalesCommissionController

| 메서드 | HTTP | 설명 |
|--------|------|------|
| `index()` | GET | 정산 목록 (필터, 페이지네이션) |
| `show(id)` | GET | JSON 상세 조회 |
| `detail(id)` | GET | 모달 상세 (HTMX partial) |
| `registerPayment()` | POST | **입금 등록 및 수당 자동 생성** |
| `approve(id)` | POST | 단일 승인 처리 |
| `bulkApprove()` | POST | 일괄 승인 (체크박스 선택) |
| `markPaid(id)` | POST | 단일 지급완료 |
| `bulkMarkPaid()` | POST | 일괄 지급완료 |
| `cancel(id)` | POST | 취소 처리 (paid 상태 제외) |
| `table()` | GET | 테이블 부분 새로고침 (HTMX) |
| `stats()` | GET | 통계 카드 부분 새로고침 (HTMX) |
| `paymentForm()` | GET | 입금 등록 폼 모달 (HTMX) |
| `export()` | GET | CSV 엑셀 다운로드 (UTF-8 BOM) |

## 서비스 클래스

### SalesCommissionService

#### 상수

```php
const DEFAULT_PARTNER_RATE = 20.00;    // 기본 파트너 수당률 (%)
const DEFAULT_MANAGER_RATE = 5.00;     // 기본 매니저 수당률 (%)
```

#### 주요 메서드

| 메서드 | 설명 |
|--------|------|
| `getCommissions(filters, perPage)` | 정산 목록 (페이지네이션, 필터) |
| `getCommissionById(id)` | 정산 상세 (관계 포함) |
| `getPendingPaymentTenants()` | 입금 대기 테넌트 목록 |
| `createCommission(managementId, type, amount, date)` | **입금 등록 + 수당 생성** |
| `approve(id, approverId)` | 승인 처리 |
| `bulkApprove(ids, approverId)` | 일괄 승인 |
| `markAsPaid(id, bankReference?)` | 지급완료 처리 |
| `bulkMarkAsPaid(ids, bankReference?)` | 일괄 지급완료 |
| `cancel(id)` | 취소 처리 |
| `getSettlementStats(year, month)` | 월별 정산 통계 |
| `getPartnerCommissionSummary(partnerId)` | 파트너 수당 요약 |
| `getManagerCommissionSummary(userId)` | 매니저 수당 요약 |

## 핵심 로직

### 수당 자동 계산 (createCommission)

```
입금 등록
    ↓
1. 계약 상품 목록 조회 (sales_contract_products)
    ↓
2. 각 상품별 수당 계산:
   기본 개발비 = 등록 금액 × 2 (없을 경우)
   기준액     = 개발비 × 50%
   파트너 수당 = 기준액 × 20%
   매니저 수당 = 기준액 × 5% (매니저 있을 경우만)
    ↓
3. sales_commissions 레코드 생성
   + sales_commission_details (상품별 N건)
    ↓
4. sales_tenant_managements 입금 정보 업데이트
    ↓
5. DB 트랜잭션으로 원자적 처리
```

### 승인 프로세스

```
pending (대기)
    ↓  approve()
approved (승인) ← approved_by, approved_at 기록
    ↓  markAsPaid()
paid (지급완료) ← actual_payment_date, bank_reference 기록

pending/approved → cancel() → cancelled
(paid 상태에서는 취소 불가)
```

### 지급 추적 (SalesCommission 모델)

```
1차 납입완료일          → first_payment_date
1차 파트너 수당 지급일   → first_partner_paid_date
2차 납입완료일          → second_payment_date
2차 파트너 수당 지급일   → second_partner_paid_date
첫 구독료 입금일         → first_subscription_date
매니저 수당 지급일       → manager_paid_date
```

### 지급예정일 계산

```
1차 파트너 수당: 1차 납입완료 익월 10일
2차 파트너 수당: 2차 납입완료 익월 10일
매니저 수당:    첫 구독료 입금 익월 10일
```

## 모델

### SalesCommission

**테이블**: `sales_commissions`

| 필드 | 타입 | 설명 |
|------|------|------|
| `tenant_id` | bigint | 테넌트 ID |
| `management_id` | bigint | 영업 테넌트 관리 FK |
| `payment_type` | enum | deposit(계약금) / balance(잔금) |
| `payment_amount` | decimal(14,2) | 입금액 |
| `payment_date` | date | 입금일 |
| `base_amount` | decimal(14,2) | 수당 계산 기준액 (개발비 50%) |
| `partner_rate` | decimal(5,2) | 파트너 수당률 (기본 20%) |
| `manager_rate` | decimal(5,2) | 매니저 수당률 (기본 5%) |
| `partner_commission` | decimal(14,2) | 파트너 수당액 |
| `manager_commission` | decimal(14,2) | 매니저 수당액 |
| `scheduled_payment_date` | date | 지급예정일 (입금 익월 10일) |
| `status` | enum | pending / approved / paid / cancelled |
| `actual_payment_date` | date | 실제 지급일 |
| `partner_id` | bigint | 영업파트너 FK |
| `manager_user_id` | bigint | 매니저 사용자 FK |
| `notes` | text | 메모 |
| `bank_reference` | string(100) | 이체 참조번호 |
| `approved_by` | bigint | 승인자 FK |
| `approved_at` | timestamp | 승인 일시 |

#### Relationships

```php
$commission->management    // BelongsTo SalesTenantManagement
$commission->partner       // BelongsTo SalesPartner
$commission->manager       // BelongsTo User
$commission->details       // HasMany SalesCommissionDetail
$commission->approver      // BelongsTo User
```

#### 주요 Scope

```php
->pending()                                   // 대기 상태
->approved()                                  // 승인 완료
->paid()                                      // 지급 완료
->forPartner($partnerId)                      // 특정 파트너
->forManager($managerUserId)                  // 특정 매니저
->forScheduledMonth($year, $month)            // 지급예정 월
->paymentDateBetween($startDate, $endDate)    // 입금일 기간
```

#### 주요 Accessor

```php
$commission->status_label          // "대기", "승인", "지급완료", "취소"
$commission->payment_type_label    // "계약금", "잔금"
$commission->total_commission      // 파트너 + 매니저 수당 합계
```

### SalesCommissionDetail

**테이블**: `sales_commission_details`

| 필드 | 타입 | 설명 |
|------|------|------|
| `commission_id` | bigint | 정산 FK (cascade delete) |
| `contract_product_id` | bigint | 계약 상품 FK |
| `registration_fee` | decimal(14,2) | 개발비 (적용가) |
| `base_amount` | decimal(14,2) | 수당 계산 기준액 |
| `partner_rate` / `manager_rate` | decimal(5,2) | 수당률 |
| `partner_commission` / `manager_commission` | decimal(14,2) | 수당액 |

## 뷰 구성

### index.blade.php (메인 페이지)

```
┌─ 페이지 헤더 ──────────────────────
│  제목: "영업수수료 정산"
│  [입금 등록] [CSV 다운로드] 버튼
│
├─ 필터 영역 ────────────────────────
│  년/월 선택 | 상태 | 입금구분 | 파트너 | 검색
│
├─ 통계 카드 (HTMX partial) ────────
│  대기 금액 | 승인 금액 | 지급 금액 | 월간 합계
│  (파트너/매니저 수당 구분)
│
├─ 정산 테이블 (HTMX partial) ──────
│  ☑ | 관리ID | 입금구분 | 금액 | 입금일 | 파트너 | 수당액 | 상태 | 작업
│  └─ 체크박스: 일괄 승인/지급 선택
│  └─ 인라인 작업: 승인, 지급완료, 취소
│  └─ 페이지네이션
│
├─ 입금 등록 모달 (HTMX partial) ───
│  테넌트 선택 → 계약 상품 표시
│  입금구분(계약금/잔금) | 입금액 | 입금일
│
└─ 상세 모달 (HTMX partial) ────────
   파트너/매니저 정보, 상품별 수당 내역
   지급 추적 일정
```

## HTMX 호환성

- Blade + HTMX 기반 (부분 업데이트 활용)
- 테이블, 통계 카드, 모달이 HTMX partial로 동작
- 전체 페이지는 HX-Redirect 필요 (JavaScript 포함)
