Files
sam-manage/docs/GROUP_COMMISSION_CHANGELOG.md
김보곤 d7d4eb0926 fix:협업지원금 개념 반영 (개인 파트너도 유치자에게 3% 지급)
- createCommission: 개인 파트너도 parent_id → SalesPartner 조회하여 3% 협업지원금 계산
- 대시보드: "유치수당" → "협업지원금" 카드 이름 복원
- 본사 총 수당 구조: 개인 28%(20+5+3), 단체 33%(30+0+3)
- 변경 보고서 v2 업데이트

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 20:02:56 +09:00

290 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 단체(그룹) 수당 체계 통합 + 협업지원금 - 변경 보고서
> 작성일: 2026-02-14 (v2 수정: 협업지원금 개념 반영)
> 적용 버전: develop 브랜치
---
## 1. 수당 체계 전체 구조
### 핵심 원칙
- **협업지원금**: 유치자(parent)가 자신이 유치한 하위 파트너의 매출에서 3%를 받는 내부 제도
- 영업파트너가 직접 영업을 못 하는 시기에도 하위 파트너의 매출로 생계를 보조하기 위한 목적
- 1단계까지만 적용 (유치자 → 하위 파트너, 그 이상의 상위로는 올라가지 않음)
### 수당 체계 비교표
| 가입 유형 | 파트너/단체 수당 | 매니저 수당 | 협업지원금(유치자) | **본사 총 지급률** |
|-----------|----------------|------------|-------------------|------------------|
| **개인 가입** | 20% | 5% | 3% | **28%** |
| **단체 가입** | 30% | 0% | 3% | **33%** |
- 기준금액: 개발비의 50%
- 분할 지급: 2단계(1차/2차) 방식 동일 적용
- 협업지원금은 개인/단체 모두 적용
### 협업지원금 대상 결정 방식
| 가입 유형 | 협업지원금 수령자 | 결정 기준 |
|-----------|-----------------|----------|
| **개인 파트너** | 유치자(parent) | `users.parent_id` → 해당 User의 SalesPartner |
| **단체 파트너** | 유치 영업파트너 | `sales_partners.referrer_partner_id` |
---
## 2. 수정 파일 상세
### 2-1. DB 마이그레이션 (API 프로젝트)
**파일**: `api/database/migrations/2026_02_15_100000_add_group_commission_support.php` (신규 생성)
#### sales_partners 테이블 추가 컬럼
| 컬럼명 | 타입 | 설명 |
|--------|------|------|
| `referrer_partner_id` | BIGINT UNSIGNED NULL | 이 단체를 유치한 영업파트너 ID (FK → sales_partners.id) |
#### sales_commissions 테이블 추가 컬럼
| 컬럼명 | 타입 | 기본값 | 설명 |
|--------|------|--------|------|
| `referrer_partner_id` | BIGINT UNSIGNED NULL | NULL | 협업지원금 받을 파트너 ID (FK → sales_partners.id) |
| `referrer_rate` | DECIMAL(5,2) | 0 | 협업지원금 수당률 (%) |
| `referrer_commission` | DECIMAL(14,2) | 0 | 협업지원금 수당액 |
| `first_referrer_paid_at` | DATE NULL | NULL | 1차 협업지원금 지급일 |
| `second_referrer_paid_at` | DATE NULL | NULL | 2차 협업지원금 지급일 |
---
### 2-2. SalesPartner 모델 (MNG)
**파일**: `mng/app/Models/Sales/SalesPartner.php`
| 항목 | 변경 내용 |
|------|----------|
| `$fillable` | `referrer_partner_id` 추가 |
| `referrer()` 관계 | BelongsTo(SalesPartner) - 이 단체를 유치한 영업파트너 |
| `referredGroups()` 관계 | HasMany(SalesPartner) - 이 파트너가 유치한 단체 목록 |
| `isGroup()` 헬퍼 | `referrer_partner_id !== null`이면 단체로 판단 |
---
### 2-3. SalesCommission 모델 (MNG)
**파일**: `mng/app/Models/Sales/SalesCommission.php`
| 항목 | 변경 내용 |
|------|----------|
| `$fillable` | 협업지원금 관련 5개 필드 추가 |
| `$casts` | `referrer_rate`, `referrer_commission` → decimal:2, 날짜 필드 → date |
| `referrerPartner()` 관계 | BelongsTo(SalesPartner) - 협업지원금 받을 파트너 |
| `getTotalCommissionAttribute()` | `partner + manager + referrer_commission` 합산 |
| `recordFirstReferrerPaid()` | 1차 협업지원금 지급 기록 |
| `recordSecondReferrerPaid()` | 2차 협업지원금 지급 기록 |
| `isFirstReferrerPaid()` | 1차 협업지원금 지급 완료 여부 |
| `isSecondReferrerPaid()` | 2차 협업지원금 지급 완료 여부 |
| `isFullyPaid()` | 협업지원금이 있으면 유치 1차/2차 지급까지 확인 |
---
### 2-4. SalesCommissionService (MNG)
**파일**: `mng/app/Services/SalesCommissionService.php`
#### 상수
| 상수 | 값 | 설명 |
|------|-----|------|
| `DEFAULT_PARTNER_RATE` | 20.00 | 개인 파트너 수당률 (기존) |
| `DEFAULT_MANAGER_RATE` | 5.00 | 매니저 수당률 (기존) |
| `DEFAULT_GROUP_RATE` | 30.00 | 단체 수당률 (신규) |
| `DEFAULT_REFERRER_RATE` | 3.00 | 협업지원금 수당률 (신규) |
#### createCommission() 수당 계산 로직
```
IF 단체(isGroup):
partnerRate = 30%
managerRate = 0%
referrerId = sales_partners.referrer_partner_id ← 단체 등록 시 지정한 유치자
referrerRate = 3%
ELSE 개인:
partnerRate = 20%
managerRate = 5%
referrerId = users.parent_id → User → SalesPartner ← 이 파트너를 유치한 상위 파트너
referrerRate = 3% (유치자가 있을 때만)
수당 계산:
partnerCommission = baseAmount × partnerRate
managerCommission = baseAmount × managerRate (매니저 있을 때만)
referrerCommission = baseAmount × referrerRate (유치자 있을 때만)
```
#### 수당 계산 예시 (기준금액 100만원)
| 가입 유형 | 파트너/단체 | 매니저 | 협업지원금 | 본사 총 지급 |
|-----------|-----------|--------|-----------|------------|
| 개인 (유치자 있음) | 200,000원 | 50,000원 | 30,000원 | **280,000원 (28%)** |
| 개인 (유치자 없음) | 200,000원 | 50,000원 | 0원 | 250,000원 (25%) |
| 단체 | 300,000원 | 0원 | 30,000원 | **330,000원 (33%)** |
---
### 2-5. SalesManagerService (MNG)
**파일**: `mng/app/Services/Sales/SalesManagerService.php`
| 항목 | 변경 내용 |
|------|----------|
| `partner_type` | `$data['partner_type'] ?? 'individual'` (기존: 고정 `'individual'`) |
| `referrer_partner_id` | `$data['referrer_partner_id'] ?? null` 추가 |
| 단체 수당률 | `partner_type === 'corporate'`이면 `commission_rate=30`, `manager_commission_rate=0` 자동 설정 |
---
### 2-6. SalesManagerController (MNG)
**파일**: `mng/app/Http/Controllers/Sales/SalesManagerController.php`
| 메서드 | 변경 내용 |
|--------|----------|
| `create()` | `$activePartners` (활성 개인 파트너 목록) 뷰에 전달 |
| `store()` | `partner_type`, `referrer_partner_id` validation 추가 |
---
### 2-7. create.blade.php (MNG)
**파일**: `mng/resources/views/sales/managers/create.blade.php`
"사업자 정보" 섹션과 "역할 및 조직" 섹션 사이에 **"파트너 유형"** 섹션 추가:
- 유형 선택 라디오: 개인(individual) / 단체(corporate)
- 단체 선택 시 유치 파트너 드롭다운 표시 (Alpine.js `x-show`)
- 안내 문구: "단체 가입 시: 단체 30%, 유치 파트너 3%, 매니저 0%"
---
### 2-8. SalesDashboardController (MNG)
**파일**: `mng/app/Http/Controllers/Sales/SalesDashboardController.php`
| 항목 | 변경 내용 |
|------|----------|
| 협업지원금 조회 | `SalesCommission::where('referrer_partner_id', $partnerId)` - 내가 유치자인 모든 건 |
| 협업지원금 계산 | total / paid / pending / approved 상태별 합산 |
| `commissionByRole` 카드 | **"협업지원금"** 3% (보라색) - 실제 금액 표시 |
| `$totalCommission` | `파트너 + 매니저 + 협업지원금` 합산 |
| `$paidCommission` | `파트너 지급완료 + 매니저 지급완료 + 협업지원금 지급완료` 합산 |
#### 대시보드 카드 변경
```
# 변경 전 (구버전)
[판매자 20% (녹색)] [관리자 1개월구독료 (파란색)] [협업지원금 "운영팀 산정" (보라색)]
# 변경 후
[판매자 20% (녹색)] [관리자 1개월구독료 (파란색)] [협업지원금 3% ₩금액 (보라색)]
```
---
### 2-9. commission-by-role.blade.php (MNG)
**파일**: `mng/resources/views/sales/dashboard/partials/commission-by-role.blade.php`
- `purple` 색상 조건 추가 (배경, 아이콘, 텍스트, 수당률, 금액 5곳)
---
## 3. 데이터 흐름
### 개인 파트너 매출 발생 시 (28% 구조)
```
파트너 A (유치자)
└─ 파트너 B (A가 유치, users.parent_id = A.id)
└─ B가 계약 체결 후 입금 발생
createCommission() 실행:
├─ B의 SalesPartner 조회
├─ isGroup() = false (개인)
├─ B의 User.parent → A의 User → A의 SalesPartner 조회
├─ referrerId = A의 SalesPartner.id
├─ 수당 계산:
│ ├─ B (파트너): 기준금액 × 20%
│ ├─ 매니저: 기준금액 × 5%
│ └─ A (협업지원금): 기준금액 × 3%
└─ SalesCommission 저장 (referrer_partner_id = A의 SalesPartner.id)
```
### 단체 매출 발생 시 (33% 구조)
```
파트너 P (유치 영업파트너)
└─ 단체 G (P가 유치, sales_partners.referrer_partner_id = P.id)
└─ G의 계약에 입금 발생
createCommission() 실행:
├─ G의 SalesPartner 조회
├─ isGroup() = true (단체)
├─ referrerId = G.referrer_partner_id (= P의 SalesPartner.id)
├─ 수당 계산:
│ ├─ G (단체): 기준금액 × 30%
│ ├─ 매니저: 0% (단체는 매니저 수당 없음)
│ └─ P (협업지원금): 기준금액 × 3%
└─ SalesCommission 저장 (referrer_partner_id = P의 SalesPartner.id)
```
---
## 4. 기존 기능과의 호환성
| 항목 | 영향 |
|------|------|
| 기존 개인 파트너 수당 (20%/5%) | 유지. 추가로 유치자에게 3% 협업지원금 발생 |
| 기존 수당 정산 데이터 | 영향 없음 (referrer 필드는 NULL 기본값, 0 기본값) |
| 기존 대시보드 | "협업지원금" 카드가 실제 금액 표시로 변경 |
| isFullyPaid() | 협업지원금이 있는 건만 유치수당 지급 여부 추가 확인 |
| 총 수당(getTotalCommissionAttribute) | 협업지원금 포함 합산으로 변경 |
---
## 5. 서버 배포 시 필요한 작업
### API 프로젝트
```bash
cd /home/webservice/api
git pull
php artisan migrate
```
### MNG 프로젝트
```bash
cd /home/webservice/mng
git pull
php artisan config:clear
```
---
## 6. 검증 체크리스트
### 개인 파트너 (28% 구조)
- [ ] 유치자(parent)가 있는 개인 파트너의 입금 등록 → 협업지원금 3% 계산 확인
- [ ] `sales_commissions.referrer_partner_id`에 유치자의 SalesPartner ID 저장 확인
- [ ] 유치자 대시보드에서 "협업지원금" 카드(보라색)에 금액 표시 확인
- [ ] 유치자가 없는 개인 파트너 → 협업지원금 0원 (기존 25% 구조 유지)
### 단체 파트너 (33% 구조)
- [ ] 파트너 등록 폼에서 "단체" 선택 시 유치 파트너 드롭다운 표시
- [ ] 단체 등록 시 `sales_partners.referrer_partner_id`, `commission_rate=30`, `manager_commission_rate=0` 확인
- [ ] 단체 입금 등록 시: 단체 30%, 매니저 0%, 협업지원금 3% 계산 확인
- [ ] 유치 파트너 대시보드에서 협업지원금 합산 확인
### 공통
- [ ] 총 수당 합계에 협업지원금 포함
- [ ] 기존 개인 파트너 수당 계산에 영향 없는지 확인 (20%/5% 유지)