# 고객사정산 ## 개요 고객사정산은 고객사별 월간 매출, 수수료, 비용을 집계하여 순정산액을 관리하는 기능입니다. 기간별 정산 현황 추적, 정산 완료 처리, 통계 기능을 제공합니다. - **라우트**: `GET /finance/customer-settlement` - **UI 기술**: React 18 + Babel (브라우저 트랜스파일링) ## 파일 구조 ``` mng/ ├── app/Http/Controllers/Finance/ │ └── CustomerSettlementController.php # 메인 컨트롤러 (4개 메서드) ├── app/Models/Finance/ │ └── CustomerSettlement.php # 고객사정산 모델 └── resources/views/finance/ └── customer-settlement.blade.php # React 기반 단일 페이지 api/ └── database/migrations/ └── 2026_02_04_230007_create_customer_settlements_table.php ``` ## 라우트 ```php // routes/web.php (finance prefix 그룹 내) GET /customer-settlement → Blade 페이지 렌더링 (HX-Redirect) // API 라우트 (customer-settlements prefix) GET /customer-settlements/list → index() 목록 + 통계 (JSON) POST /customer-settlements/store → store() 등록 PUT /customer-settlements/{id} → update() 수정 DELETE /customer-settlements/{id} → destroy() 삭제 ``` ## 컨트롤러 ### CustomerSettlementController | 메서드 | HTTP | 설명 | |--------|------|------| | `index()` | GET | 목록 + 통계 (검색, 기간, 상태 필터) | | `store()` | POST | 정산 등록 | | `update()` | PUT | 정산 수정 | | `destroy()` | DELETE | 삭제 (Soft Delete) | ### index() 응답 구조 ```json { "success": true, "data": [ { "id": 1, "period": "2026-02", "customer": "A사", "totalSales": 10000000, "commission": 500000, "expense": 200000, "netAmount": 9300000, "status": "pending", "settledDate": null, "memo": "" } ], "stats": { "totalSales": 50000000, "totalCommission": 2500000, "totalNet": 45000000, "settledAmount": 30000000 } } ``` ## 핵심 로직 ### 순정산액 계산 ``` 순정산액(net_amount) = 총 매출(total_sales) - 수수료(commission) - 비용(expense) ``` ### 상태 관리 ``` pending (대기) → settled (정산완료) → 정산완료 시 settled_date 기록 ``` ## 모델 ### CustomerSettlement **테이블**: `customer_settlements` | 필드 | 타입 | 설명 | |------|------|------| | `tenant_id` | bigint | 테넌트 ID | | `period` | string(7) | 정산월 (YYYY-MM) | | `customer` | string(100) | 고객사명 | | `total_sales` | bigint | 총 매출액 | | `commission` | bigint | 수수료 | | `expense` | bigint | 비용 | | `net_amount` | bigint | 순정산액 | | `status` | string(20) | pending / settled | | `settled_date` | date | 정산완료일 | | `memo` | text | 메모 | - SoftDeletes 적용 - Casts: total_sales, commission, expense, net_amount → integer, settled_date → date - Scope: `forTenant($tenantId)` ## 뷰 구성 (React) ### customer-settlement.blade.php ``` ┌─ 페이지 헤더 ────────────────────── │ 제목: "고객사정산" │ [CSV 내보내기] [등록] 버튼 │ ├─ 통계 카드 (4열) ────────────────── │ 총 매출 | 정산금액 | 정산완료 | 총 수수료 │ ├─ 필터 영역 ──────────────────────── │ 검색 (고객사명) | 기간 (YYYY-MM) | 상태 (전체/대기/정산완료) │ ├─ 정산 목록 테이블 ───────────────── │ 기간 | 고객사 | 매출 | 수수료 | 비용 | 정산액 | 상태 | 작업 │ └─ 정산액: 매출-수수료-비용 자동 계산 │ └─ 상태: 대기(노랑), 정산완료(초록) 배지 │ └─ 작업: 수정/삭제 버튼 │ ├─ 등록/수정 모달 ─────────────────── │ 정산월(YYYY-MM), 고객사명 │ 총 매출액, 수수료, 비용 │ → 순정산액 (자동 계산 표시) │ 상태, 정산완료일, 메모 │ [삭제] [취소] [등록/저장] │ └─ 비어있을 때: 안내 메시지 ``` ## 데이터 흐름 ``` React 컴포넌트 ↓ fetch GET /finance/customer-settlements/list CustomerSettlementController::index() ↓ CustomerSettlement::forTenant() ↓ (search, status, period 필터) 통계 계산 (totalSales, totalCommission, totalNet, settledAmount) ↓ JSON 응답 → React 렌더링 ``` ## HTMX 호환성 - React 기반 페이지이므로 **HX-Redirect 필요** - `@push('scripts')` 블록에 React/Babel 스크립트 포함