docs:영업/매출관리 개발문서 추가 (7개 메뉴)
- 영업관리 대시보드: 수당 현황, 테넌트 진행률, 파트너 활동 - 파트너관리: 영업파트너 CRUD, 역할 관리, 서류 관리 - 영업파트너승인: 신규 파트너 신청 승인/반려 워크플로우 - 상품관리: 카테고리별 상품, 가격/수당률 설정 - 고객관리(관리자): 전사 고객 현황, 본사 진행상태 8단계 - 영업파트너 고객관리: 명함등록 기반 영업권, 테넌트 전환 - 인터뷰 시나리오: 질문 템플릿, 세션 기반 인터뷰 기록 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
128
features/sales/README.md
Normal file
128
features/sales/README.md
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
# 영업/매출관리
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
|
||||||
|
영업/매출관리 모듈은 영업파트너 관리, 고객 영업권, 상품 관리, 인터뷰 시나리오 등
|
||||||
|
영업 전체 프로세스를 관리하는 기능 그룹입니다.
|
||||||
|
|
||||||
|
- **라우트 Prefix**: `/sales`
|
||||||
|
- **미들웨어**: `auth`, `hq.member` (본사 회원 전용)
|
||||||
|
- **UI 기술**: Blade + HTMX + Alpine.js (일부 React)
|
||||||
|
|
||||||
|
## 메뉴 구성
|
||||||
|
|
||||||
|
| # | 메뉴명 | 경로 | 문서 | 상태 |
|
||||||
|
|---|--------|------|------|------|
|
||||||
|
| 1 | 영업관리 대시보드 | `/sales/salesmanagement/dashboard` | [sales-dashboard.md](sales-dashboard.md) | 구현완료 |
|
||||||
|
| 2 | 파트너관리 | `/sales/managers` | [partners.md](partners.md) | 구현완료 |
|
||||||
|
| 3 | 영업파트너승인 | `/sales/managers/approvals` | [partner-approvals.md](partner-approvals.md) | 구현완료 |
|
||||||
|
| 4 | 상품관리 | `/sales/products` | [products.md](products.md) | 구현완료 |
|
||||||
|
| 5 | 세일즈사이트 | (외부 링크) | - | 미구현 |
|
||||||
|
| 6 | 랜딩페이지 | (외부 링크) | - | 미구현 |
|
||||||
|
| 7 | 고객 관리 | `/sales/admin-prospects` | [admin-prospects.md](admin-prospects.md) | 구현완료 |
|
||||||
|
| 8 | 영업파트너 고객관리 | `/sales/prospects` | [prospects.md](prospects.md) | 구현완료 |
|
||||||
|
| 9 | 인터뷰 시나리오 | `/sales/interviews` | [interviews.md](interviews.md) | 구현완료 |
|
||||||
|
|
||||||
|
## 아키텍처
|
||||||
|
|
||||||
|
```
|
||||||
|
영업/매출관리
|
||||||
|
├── 대시보드 ──── 수당 현황, 테넌트 진행률, 파트너 활동
|
||||||
|
├── 파트너관리
|
||||||
|
│ ├── 파트너 CRUD ──── 영업파트너 등록/수정/역할 관리
|
||||||
|
│ └── 파트너 승인 ──── 신규 파트너 신청 승인/반려
|
||||||
|
├── 상품관리 ──── 카테고리별 상품, 가격/수당률 설정
|
||||||
|
├── 고객관리
|
||||||
|
│ ├── 고객 관리(관리자) ──── 전사 고객 현황, 본사 진행상태
|
||||||
|
│ └── 파트너 고객관리 ──── 명함등록 기반 영업권 관리
|
||||||
|
└── 인터뷰 시나리오 ──── 질문 템플릿, 인터뷰 세션 기록
|
||||||
|
```
|
||||||
|
|
||||||
|
## 파일 구조
|
||||||
|
|
||||||
|
```
|
||||||
|
mng/
|
||||||
|
├── app/Http/Controllers/Sales/
|
||||||
|
│ ├── SalesDashboardController.php # 영업관리 대시보드
|
||||||
|
│ ├── SalesManagerController.php # 파트너관리 + 승인
|
||||||
|
│ ├── SalesProductController.php # 상품관리
|
||||||
|
│ ├── TenantProspectController.php # 영업권(명함등록) 관리
|
||||||
|
│ ├── AdminProspectController.php # 관리자 전체 고객 관리
|
||||||
|
│ └── InterviewScenarioController.php # 인터뷰 시나리오
|
||||||
|
├── app/Models/Sales/
|
||||||
|
│ ├── SalesPartner.php # 영업파트너
|
||||||
|
│ ├── SalesTenantManagement.php # 테넌트 영업 관리
|
||||||
|
│ ├── TenantProspect.php # 가망고객 (영업권)
|
||||||
|
│ ├── SalesCommission.php # 영업 수수료
|
||||||
|
│ ├── SalesProduct.php # 영업 상품
|
||||||
|
│ ├── SalesProductCategory.php # 상품 카테고리
|
||||||
|
│ └── SalesManagerDocument.php # 파트너 서류
|
||||||
|
├── app/Models/Interview/
|
||||||
|
│ ├── InterviewCategory.php # 인터뷰 카테고리
|
||||||
|
│ ├── InterviewTemplate.php # 인터뷰 템플릿
|
||||||
|
│ ├── InterviewQuestion.php # 인터뷰 질문
|
||||||
|
│ ├── InterviewSession.php # 인터뷰 세션
|
||||||
|
│ └── InterviewAnswer.php # 인터뷰 답변
|
||||||
|
├── app/Services/Sales/
|
||||||
|
│ ├── SalesManagerService.php # 파트너 관리 서비스
|
||||||
|
│ ├── TenantProspectService.php # 영업권 서비스
|
||||||
|
│ └── InterviewScenarioService.php # 인터뷰 서비스
|
||||||
|
└── resources/views/sales/
|
||||||
|
├── dashboard/ # 대시보드 뷰
|
||||||
|
├── managers/ # 파트너관리 뷰
|
||||||
|
├── products/ # 상품관리 뷰
|
||||||
|
├── prospects/ # 영업권 관리 뷰
|
||||||
|
├── admin-prospects/ # 관리자 고객관리 뷰
|
||||||
|
└── interviews/ # 인터뷰 시나리오 뷰
|
||||||
|
|
||||||
|
api/
|
||||||
|
└── database/migrations/
|
||||||
|
├── 2026_01_27_221000_create_tenant_prospects_table.php
|
||||||
|
├── 2026_01_28_090000_add_attachments_to_tenant_prospects_table.php
|
||||||
|
├── 2026_01_29_100000_create_sales_partners_table.php
|
||||||
|
├── 2026_01_29_100100_create_sales_tenant_managements_table.php
|
||||||
|
├── 2026_01_29_150000_create_sales_products_tables.php
|
||||||
|
└── 2026_02_06_10000x_create_interview_*_tables.php (5개)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 핵심 데이터 모델 관계
|
||||||
|
|
||||||
|
```
|
||||||
|
User (영업파트너)
|
||||||
|
│
|
||||||
|
├── SalesPartner (파트너 정보, 수수료율, 계좌)
|
||||||
|
│
|
||||||
|
├── TenantProspect (영업권 = 명함등록)
|
||||||
|
│ ├── status: active → expired / converted / completed
|
||||||
|
│ ├── 유효기간: 2개월
|
||||||
|
│ └── 쿨다운: 만료 후 1개월
|
||||||
|
│ │
|
||||||
|
│ ↓ convert()
|
||||||
|
│ Tenant (계약 고객사)
|
||||||
|
│ │
|
||||||
|
│ ↓
|
||||||
|
│ SalesTenantManagement (영업 관리)
|
||||||
|
│ ├── status: prospect → approach → negotiation → contracted → onboarding → active
|
||||||
|
│ ├── hq_status: pending → review → planning → coding → dev_test → dev_done → int_test → handover
|
||||||
|
│ └── SalesCommission (수당 정보)
|
||||||
|
│
|
||||||
|
└── SalesManagerDocument (등록 서류)
|
||||||
|
|
||||||
|
SalesProductCategory
|
||||||
|
└── SalesProduct (개발비, 가입비, 구독료, 수당율)
|
||||||
|
└── SalesContractProduct (계약별 선택 상품)
|
||||||
|
|
||||||
|
InterviewCategory
|
||||||
|
└── InterviewTemplate
|
||||||
|
└── InterviewQuestion
|
||||||
|
└── InterviewSession → InterviewAnswer
|
||||||
|
```
|
||||||
|
|
||||||
|
## 권한 체계
|
||||||
|
|
||||||
|
| 역할 | 대시보드 | 파트너관리 | 승인 | 상품 | 고객관리 | 파트너고객 | 인터뷰 |
|
||||||
|
|------|---------|-----------|------|------|---------|-----------|--------|
|
||||||
|
| 영업파트너 | O (본인) | - | - | - | - | O (본인) | O |
|
||||||
|
| 상담매니저 | O (본인) | - | - | - | - | - | O |
|
||||||
|
| 관리자 | O (전체) | O | O | O | O | O | O |
|
||||||
|
| 슈퍼관리자 | O (전체) | O | O | O | O (삭제) | O | O |
|
||||||
155
features/sales/admin-prospects.md
Normal file
155
features/sales/admin-prospects.md
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
# 고객 관리 (관리자)
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
|
||||||
|
고객 관리(관리자)는 본사 관리자가 모든 영업파트너의 고객을 통합 관리하는 기능입니다.
|
||||||
|
전사 고객 현황 파악, 본사 진행상태 관리, 수당 지급 기록, 상태 변경을 지원합니다.
|
||||||
|
|
||||||
|
- **라우트**: `GET /sales/admin-prospects`
|
||||||
|
- **미들웨어**: `auth`, `hq.member` + 관리자 권한 체크
|
||||||
|
- **UI 기술**: Blade + HTMX + Tailwind CSS
|
||||||
|
|
||||||
|
## 파일 구조
|
||||||
|
|
||||||
|
```
|
||||||
|
mng/
|
||||||
|
├── app/Http/Controllers/Sales/
|
||||||
|
│ └── AdminProspectController.php # 메인 컨트롤러 (8개 메서드)
|
||||||
|
└── resources/views/sales/admin-prospects/
|
||||||
|
├── index.blade.php # 전체 고객 목록 (460줄)
|
||||||
|
└── partials/
|
||||||
|
├── content.blade.php # 콘텐츠 새로고침
|
||||||
|
└── show-modal.blade.php # 고객 상세 모달
|
||||||
|
```
|
||||||
|
|
||||||
|
## 라우트
|
||||||
|
|
||||||
|
```php
|
||||||
|
// routes/web.php (sales prefix 그룹 내)
|
||||||
|
GET /admin-prospects → index() 전체 고객 목록
|
||||||
|
GET /admin-prospects/refresh → refresh() HTMX 새로고침
|
||||||
|
GET /admin-prospects/{id}/modal-show → modalShow() 상세 모달
|
||||||
|
POST /admin-prospects/{id}/hq-status → updateHqStatus() 본사 진행상태 변경
|
||||||
|
POST /admin-prospects/{id}/commission-date → updateCommissionDate() 수당 날짜 기록
|
||||||
|
DELETE /admin-prospects/{id}/commission-date → clearCommissionDate() 수당 날짜 초기화
|
||||||
|
DELETE /admin-prospects/{id} → destroy() 삭제 (슈퍼관리자)
|
||||||
|
POST /admin-prospects/{id}/toggle-status → toggleStatus() 상태 토글
|
||||||
|
```
|
||||||
|
|
||||||
|
## 컨트롤러
|
||||||
|
|
||||||
|
### AdminProspectController
|
||||||
|
|
||||||
|
| 메서드 | HTTP | 설명 | 권한 |
|
||||||
|
|--------|------|------|------|
|
||||||
|
| `index()` | GET | 전체 고객 목록 (필터+통계) | 관리자/슈퍼관리자 |
|
||||||
|
| `refresh()` | GET | 콘텐츠 새로고침 (HTMX) | 관리자/슈퍼관리자 |
|
||||||
|
| `modalShow()` | GET | 고객 상세 모달 (진행률 포함) | 관리자/슈퍼관리자 |
|
||||||
|
| `updateHqStatus()` | POST | 본사 진행상태 변경 | 관리자/슈퍼관리자 |
|
||||||
|
| `updateCommissionDate()` | POST | 수당 지급 날짜 기록/수정 | 관리자/슈퍼관리자 |
|
||||||
|
| `clearCommissionDate()` | DELETE | 수당 날짜 초기화 | 관리자/슈퍼관리자 |
|
||||||
|
| `toggleStatus()` | POST | 상태 토글 (영업중 ↔ 완료) | 관리자/슈퍼관리자 |
|
||||||
|
| `destroy()` | DELETE | 삭제 | 슈퍼관리자 전용 |
|
||||||
|
|
||||||
|
### 본사 진행상태 (HQ Status) 8단계
|
||||||
|
|
||||||
|
```
|
||||||
|
pending (대기)
|
||||||
|
→ review (검토)
|
||||||
|
→ planning (기획안작성)
|
||||||
|
→ coding (개발코드작성)
|
||||||
|
→ dev_test (개발테스트)
|
||||||
|
→ dev_done (개발완료)
|
||||||
|
→ int_test (통합테스트)
|
||||||
|
→ handover (인계)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 수당 날짜 관리
|
||||||
|
|
||||||
|
```
|
||||||
|
updateCommissionDate():
|
||||||
|
- 납입일(membership_paid_at) 입력 시
|
||||||
|
- 자동 지급일 계산: 익월 10일
|
||||||
|
- commission_paid_at 기록
|
||||||
|
```
|
||||||
|
|
||||||
|
## 모델
|
||||||
|
|
||||||
|
### SalesTenantManagement (핵심 모델)
|
||||||
|
|
||||||
|
**테이블**: `sales_tenant_managements`
|
||||||
|
|
||||||
|
| 필드 | 타입 | 설명 |
|
||||||
|
|------|------|------|
|
||||||
|
| `tenant_id` | bigint (FK, unique) | 테넌트 ID (1:1) |
|
||||||
|
| `tenant_prospect_id` | bigint (FK) | 가망고객 ID |
|
||||||
|
| `sales_partner_id` | bigint (FK) | 영업 담당자 ID |
|
||||||
|
| `manager_user_id` | bigint (FK) | 상담매니저 사용자 ID |
|
||||||
|
| `sales_scenario_step` | int | 영업 시나리오 단계 (1-6) |
|
||||||
|
| `manager_scenario_step` | int | 매니저 시나리오 단계 (1-6) |
|
||||||
|
| `status` | enum | 영업 상태 |
|
||||||
|
| `hq_status` | enum | 본사 진행상태 |
|
||||||
|
| `first_contact_at` | timestamp | 최초 접촉일 |
|
||||||
|
| `contracted_at` | timestamp | 계약 체결일 |
|
||||||
|
| `onboarding_completed_at` | timestamp | 온보딩 완료일 |
|
||||||
|
| `membership_fee` | decimal | 가입비 |
|
||||||
|
| `membership_paid_at` | timestamp | 가입비 입금일 |
|
||||||
|
| `membership_status` | enum | pending / partial / paid / refunded |
|
||||||
|
| `sales_commission` | decimal | 영업 수당 |
|
||||||
|
| `manager_commission` | decimal | 관리 수당 |
|
||||||
|
| `commission_paid_at` | timestamp | 수당 지급일 |
|
||||||
|
| `sales_progress` | tinyint | 영업 진행률 (%) |
|
||||||
|
| `manager_progress` | tinyint | 매니저 진행률 (%) |
|
||||||
|
| `incentive_status` | enum | pending / eligible / paid |
|
||||||
|
| `notes` | text | 메모 |
|
||||||
|
|
||||||
|
#### 영업 상태 흐름
|
||||||
|
|
||||||
|
```
|
||||||
|
prospect (잠재) → approach (접근) → negotiation (협상)
|
||||||
|
→ contracted (계약) → onboarding (온보딩) → active (활성) / churned (이탈)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 수당 상태
|
||||||
|
|
||||||
|
```
|
||||||
|
pending (대기) → eligible (지급대상) → paid (지급완료)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 뷰 구성
|
||||||
|
|
||||||
|
### index.blade.php
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─ 페이지 헤더 ──────────────────────
|
||||||
|
│ 제목: "고객 관리"
|
||||||
|
│ [새로고침] 버튼
|
||||||
|
│
|
||||||
|
├─ 통계 카드 ────────────────────────
|
||||||
|
│ 전체 | 활성 | 완료 | 인계완료
|
||||||
|
│
|
||||||
|
├─ 필터 영역 ────────────────────────
|
||||||
|
│ 검색 (회사명, 사업자번호, 대표자, 연락처)
|
||||||
|
│ 상태: active / expired / converted / progress_complete
|
||||||
|
│ 인계: hq_status = 'handover'
|
||||||
|
│ 영업파트너: registered_by 필터
|
||||||
|
│
|
||||||
|
├─ 고객 목록 테이블 ────────────────
|
||||||
|
│ 회사명 | 사업자번호 | 대표자 | 영업파트너
|
||||||
|
│ 영업진행률 | 매니저진행률 | 본사상태 | 작업
|
||||||
|
│ └─ 본사상태: 8단계 프로그레스바
|
||||||
|
│ └─ 작업: 상세, 상태변경, 삭제
|
||||||
|
│
|
||||||
|
└─ 상세 모달 ───────────────────────
|
||||||
|
기본 정보 (회사명, 사업자번호, 대표자, 연락처)
|
||||||
|
영업 진행률 (영업 시나리오, 매니저 시나리오)
|
||||||
|
본사 진행상태 (8단계 프로그레스바 + 변경 드롭다운)
|
||||||
|
수당 정보 (납입일, 지급일, 자동 계산)
|
||||||
|
담당 매니저 정보
|
||||||
|
```
|
||||||
|
|
||||||
|
## HTMX 호환성
|
||||||
|
|
||||||
|
- Blade + HTMX 기반으로 **HX-Redirect 불필요**
|
||||||
|
- `hx-get`으로 부분 새로고침
|
||||||
|
- 모달로 상세 조회 및 상태 변경
|
||||||
281
features/sales/interviews.md
Normal file
281
features/sales/interviews.md
Normal file
@@ -0,0 +1,281 @@
|
|||||||
|
# 인터뷰 시나리오
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
|
||||||
|
인터뷰 시나리오는 영업 상담 시 사용할 질문 템플릿을 관리하고,
|
||||||
|
인터뷰 세션을 진행/기록하는 기능입니다.
|
||||||
|
카테고리별 질문 구조, 체크리스트/텍스트 답변, MD 일괄 가져오기를 지원합니다.
|
||||||
|
|
||||||
|
- **라우트**: `GET /sales/interviews`
|
||||||
|
- **미들웨어**: `auth`, `hq.member`
|
||||||
|
- **UI 기술**: Blade + React/JavaScript (API 기반, 1,076줄)
|
||||||
|
|
||||||
|
## 파일 구조
|
||||||
|
|
||||||
|
```
|
||||||
|
mng/
|
||||||
|
├── app/Http/Controllers/Sales/
|
||||||
|
│ └── InterviewScenarioController.php # 메인 컨트롤러 (16개 메서드)
|
||||||
|
├── app/Services/Sales/
|
||||||
|
│ └── InterviewScenarioService.php # 비즈니스 로직 서비스
|
||||||
|
├── app/Models/Interview/
|
||||||
|
│ ├── InterviewCategory.php # 카테고리
|
||||||
|
│ ├── InterviewTemplate.php # 템플릿 (항목)
|
||||||
|
│ ├── InterviewQuestion.php # 질문
|
||||||
|
│ ├── InterviewSession.php # 인터뷰 세션
|
||||||
|
│ └── InterviewAnswer.php # 답변
|
||||||
|
└── resources/views/sales/interviews/
|
||||||
|
└── index.blade.php # 메인 페이지 (1,076줄)
|
||||||
|
|
||||||
|
api/
|
||||||
|
└── database/migrations/
|
||||||
|
├── 2026_02_06_100000_create_interview_categories_table.php
|
||||||
|
├── 2026_02_06_100001_create_interview_templates_table.php
|
||||||
|
├── 2026_02_06_100002_create_interview_questions_table.php
|
||||||
|
├── 2026_02_06_100003_create_interview_sessions_table.php
|
||||||
|
└── 2026_02_06_100004_create_interview_answers_table.php
|
||||||
|
```
|
||||||
|
|
||||||
|
## 라우트
|
||||||
|
|
||||||
|
```php
|
||||||
|
// routes/web.php (sales/interviews prefix 그룹 내)
|
||||||
|
|
||||||
|
// 페이지
|
||||||
|
GET /interviews → index() 메인 페이지
|
||||||
|
|
||||||
|
// 카테고리 API
|
||||||
|
GET /interviews/api/categories → categories() 카테고리 목록
|
||||||
|
POST /interviews/api/categories → storeCategory() 카테고리 생성
|
||||||
|
PUT /interviews/api/categories/{id} → updateCategory() 카테고리 수정
|
||||||
|
DELETE /interviews/api/categories/{id} → destroyCategory() 카테고리 삭제
|
||||||
|
|
||||||
|
// 트리 API
|
||||||
|
GET /interviews/api/tree → tree() 전체 계층 구조
|
||||||
|
|
||||||
|
// 템플릿(항목) API
|
||||||
|
POST /interviews/api/templates → storeTemplate() 템플릿 생성
|
||||||
|
PUT /interviews/api/templates/{id} → updateTemplate() 템플릿 수정
|
||||||
|
DELETE /interviews/api/templates/{id} → destroyTemplate() 템플릿 삭제
|
||||||
|
|
||||||
|
// 질문 API
|
||||||
|
POST /interviews/api/questions → storeQuestion() 질문 생성
|
||||||
|
PUT /interviews/api/questions/{id} → updateQuestion() 질문 수정
|
||||||
|
DELETE /interviews/api/questions/{id} → destroyQuestion() 질문 삭제
|
||||||
|
|
||||||
|
// 일괄 가져오기
|
||||||
|
POST /interviews/api/bulk-import → bulkImport() MD 파일에서 가져오기
|
||||||
|
|
||||||
|
// 세션(인터뷰) API
|
||||||
|
GET /interviews/api/sessions → sessions() 세션 목록 (필터)
|
||||||
|
POST /interviews/api/sessions → storeSession() 인터뷰 시작
|
||||||
|
GET /interviews/api/sessions/{id} → showSession() 세션 상세
|
||||||
|
POST /interviews/api/sessions/toggle-answer → toggleAnswer() 답변 토글
|
||||||
|
POST /interviews/api/sessions/{id}/complete → completeSession() 인터뷰 완료
|
||||||
|
```
|
||||||
|
|
||||||
|
## 컨트롤러
|
||||||
|
|
||||||
|
### InterviewScenarioController
|
||||||
|
|
||||||
|
| 메서드 | HTTP | 설명 |
|
||||||
|
|--------|------|------|
|
||||||
|
| `index()` | GET | 메인 페이지 |
|
||||||
|
| `categories()` | GET | 카테고리 목록 |
|
||||||
|
| `storeCategory()` | POST | 카테고리 생성 |
|
||||||
|
| `updateCategory()` | PUT | 카테고리 수정 |
|
||||||
|
| `destroyCategory()` | DELETE | 카테고리 삭제 |
|
||||||
|
| `tree()` | GET | 전체 계층 구조 (카테고리→템플릿→질문) |
|
||||||
|
| `storeTemplate()` | POST | 템플릿 생성 |
|
||||||
|
| `updateTemplate()` | PUT | 템플릿 수정 |
|
||||||
|
| `destroyTemplate()` | DELETE | 템플릿 삭제 |
|
||||||
|
| `storeQuestion()` | POST | 질문 생성 |
|
||||||
|
| `updateQuestion()` | PUT | 질문 수정 |
|
||||||
|
| `destroyQuestion()` | DELETE | 질문 삭제 |
|
||||||
|
| `bulkImport()` | POST | MD 파일에서 일괄 가져오기 |
|
||||||
|
| `sessions()` | GET | 인터뷰 세션 목록 |
|
||||||
|
| `storeSession()` | POST | 인터뷰 시작 |
|
||||||
|
| `showSession()` | GET | 세션 상세 |
|
||||||
|
| `toggleAnswer()` | POST | 답변 토글/기록 |
|
||||||
|
| `completeSession()` | POST | 인터뷰 완료 |
|
||||||
|
|
||||||
|
### InterviewScenarioService
|
||||||
|
|
||||||
|
| 메서드 | 설명 |
|
||||||
|
|--------|------|
|
||||||
|
| `getCategories()` | 카테고리 목록 |
|
||||||
|
| `createCategory()` | 카테고리 생성 |
|
||||||
|
| `updateCategory()` | 카테고리 수정 |
|
||||||
|
| `deleteCategory()` | 카테고리 삭제 |
|
||||||
|
| `getTree()` | 전체 계층 구조 조회 |
|
||||||
|
| `createTemplate()` | 템플릿 생성 |
|
||||||
|
| `updateTemplate()` | 템플릿 수정 |
|
||||||
|
| `deleteTemplate()` | 템플릿 삭제 |
|
||||||
|
| `createQuestion()` | 질문 생성 |
|
||||||
|
| `updateQuestion()` | 질문 수정 |
|
||||||
|
| `deleteQuestion()` | 질문 삭제 |
|
||||||
|
| `bulkImport()` | MD에서 일괄 가져오기 |
|
||||||
|
| `getSessions()` | 세션 목록 (필터) |
|
||||||
|
| `startSession()` | 인터뷰 시작 |
|
||||||
|
| `getSessionDetail()` | 세션 상세 |
|
||||||
|
| `toggleAnswer()` | 답변 토글 |
|
||||||
|
| `completeSession()` | 인터뷰 완료 |
|
||||||
|
|
||||||
|
## 모델
|
||||||
|
|
||||||
|
### 데이터 계층 구조
|
||||||
|
|
||||||
|
```
|
||||||
|
InterviewCategory (카테고리)
|
||||||
|
└── InterviewTemplate (템플릿/항목)
|
||||||
|
└── InterviewQuestion (질문)
|
||||||
|
|
||||||
|
InterviewSession (인터뷰 세션)
|
||||||
|
└── InterviewAnswer (답변)
|
||||||
|
```
|
||||||
|
|
||||||
|
### InterviewCategory
|
||||||
|
|
||||||
|
**테이블**: `interview_categories`
|
||||||
|
|
||||||
|
| 필드 | 타입 | 설명 |
|
||||||
|
|------|------|------|
|
||||||
|
| `tenant_id` | bigint | 테넌트 ID |
|
||||||
|
| `name` | string | 카테고리명 (예: 제조-방화셔터) |
|
||||||
|
| `description` | text | 설명 |
|
||||||
|
| `sort_order` | int | 정렬 순서 |
|
||||||
|
| `is_active` | boolean | 활성 여부 |
|
||||||
|
| `created_by` | bigint | 등록자 |
|
||||||
|
|
||||||
|
- SoftDeletes 적용
|
||||||
|
- 관계: `templates()`, `sessions()`
|
||||||
|
|
||||||
|
### InterviewTemplate
|
||||||
|
|
||||||
|
**테이블**: `interview_templates`
|
||||||
|
|
||||||
|
| 필드 | 타입 | 설명 |
|
||||||
|
|------|------|------|
|
||||||
|
| `tenant_id` | bigint | 테넌트 ID |
|
||||||
|
| `interview_category_id` | bigint (FK) | 카테고리 ID |
|
||||||
|
| `name` | string | 항목명 (예: 견적서 제작) |
|
||||||
|
| `description` | text | 설명 |
|
||||||
|
| `sort_order` | int | 정렬 순서 |
|
||||||
|
| `is_active` | boolean | 활성 여부 |
|
||||||
|
|
||||||
|
- SoftDeletes 적용
|
||||||
|
- 관계: `category()`, `questions()`
|
||||||
|
|
||||||
|
### InterviewQuestion
|
||||||
|
|
||||||
|
**테이블**: `interview_questions`
|
||||||
|
|
||||||
|
| 필드 | 타입 | 설명 |
|
||||||
|
|------|------|------|
|
||||||
|
| `tenant_id` | bigint | 테넌트 ID |
|
||||||
|
| `interview_template_id` | bigint (FK) | 템플릿 ID |
|
||||||
|
| `question_text` | string(500) | 질문 텍스트 |
|
||||||
|
| `question_type` | string | **checkbox** / **text** |
|
||||||
|
| `options` | json | 선택지 (배열) |
|
||||||
|
| `is_required` | boolean | 필수 여부 |
|
||||||
|
| `sort_order` | int | 정렬 순서 |
|
||||||
|
| `is_active` | boolean | 활성 여부 |
|
||||||
|
|
||||||
|
- SoftDeletes 적용
|
||||||
|
- 관계: `template()`
|
||||||
|
|
||||||
|
#### 질문 타입
|
||||||
|
|
||||||
|
| 타입 | 설명 | 답변 방식 |
|
||||||
|
|------|------|----------|
|
||||||
|
| `checkbox` | 체크 질문 | is_checked 토글 |
|
||||||
|
| `text` | 서술형 질문 | answer_text 입력 |
|
||||||
|
|
||||||
|
### InterviewSession
|
||||||
|
|
||||||
|
**테이블**: `interview_sessions`
|
||||||
|
|
||||||
|
| 필드 | 타입 | 설명 |
|
||||||
|
|------|------|------|
|
||||||
|
| `tenant_id` | bigint | 테넌트 ID |
|
||||||
|
| `interview_category_id` | bigint (FK) | 사용한 카테고리 ID |
|
||||||
|
| `interviewer_id` | bigint (FK) | 면담자(매니저) ID |
|
||||||
|
| `interviewee_name` | string(100) | 면담 상대 이름 |
|
||||||
|
| `interviewee_company` | string(200) | 면담 상대 회사 |
|
||||||
|
| `interview_date` | date | 면담 일자 |
|
||||||
|
| `status` | string | **in_progress** / **completed** |
|
||||||
|
| `total_questions` | int | 총 질문 수 |
|
||||||
|
| `answered_questions` | int | 답변 완료 수 |
|
||||||
|
| `memo` | text | 메모 |
|
||||||
|
| `completed_at` | timestamp | 완료 일시 |
|
||||||
|
|
||||||
|
- SoftDeletes 적용
|
||||||
|
- 관계: `category()`, `interviewer()`, `answers()`
|
||||||
|
|
||||||
|
### InterviewAnswer
|
||||||
|
|
||||||
|
**테이블**: `interview_answers`
|
||||||
|
|
||||||
|
| 필드 | 타입 | 설명 |
|
||||||
|
|------|------|------|
|
||||||
|
| `tenant_id` | bigint | 테넌트 ID |
|
||||||
|
| `interview_session_id` | bigint (FK) | 세션 ID |
|
||||||
|
| `interview_question_id` | bigint (FK) | 질문 ID |
|
||||||
|
| `interview_template_id` | bigint (FK) | 템플릿 ID |
|
||||||
|
| `is_checked` | boolean | 체크 여부 (checkbox 유형) |
|
||||||
|
| `answer_text` | text | 답변 텍스트 (text 유형) |
|
||||||
|
| `memo` | text | 메모 |
|
||||||
|
|
||||||
|
### 인터뷰 진행 흐름
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 카테고리 선택 + 면담 상대 정보 입력
|
||||||
|
→ storeSession() → 세션 생성 (status: in_progress)
|
||||||
|
→ 해당 카테고리의 모든 질문에 대해 빈 Answer 생성
|
||||||
|
|
||||||
|
2. 질문별 답변 기록
|
||||||
|
→ toggleAnswer() → is_checked 토글 / answer_text 저장
|
||||||
|
→ answered_questions 카운트 갱신
|
||||||
|
|
||||||
|
3. 인터뷰 완료
|
||||||
|
→ completeSession() → status: completed, completed_at 기록
|
||||||
|
```
|
||||||
|
|
||||||
|
## 뷰 구성
|
||||||
|
|
||||||
|
### index.blade.php
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─ 페이지 헤더 ──────────────────────
|
||||||
|
│ 제목: "인터뷰 시나리오"
|
||||||
|
│ [카테고리 추가] [일괄 가져오기] 버튼
|
||||||
|
│
|
||||||
|
├─ 좌측 사이드바 ───────────────────
|
||||||
|
│ 카테고리 트리
|
||||||
|
│ ├── 카테고리 A
|
||||||
|
│ │ ├── 템플릿 1 (질문 3개)
|
||||||
|
│ │ └── 템플릿 2 (질문 5개)
|
||||||
|
│ └── 카테고리 B
|
||||||
|
│ └── 템플릿 3 (질문 2개)
|
||||||
|
│
|
||||||
|
├─ 우측 메인 영역 ──────────────────
|
||||||
|
│ ├─ 템플릿 편집 모드
|
||||||
|
│ │ 질문 목록 + 추가/수정/삭제
|
||||||
|
│ │ 질문 타입(checkbox/text) + 옵션
|
||||||
|
│ │
|
||||||
|
│ └─ 인터뷰 세션 모드
|
||||||
|
│ 면담 상대 정보 + 날짜
|
||||||
|
│ 질문별 체크/답변 기록
|
||||||
|
│ 진행률 표시
|
||||||
|
│ [완료] 버튼
|
||||||
|
│
|
||||||
|
└─ 세션 목록 ───────────────────────
|
||||||
|
과거 인터뷰 기록 (필터: 카테고리, 날짜)
|
||||||
|
면담자 | 상대방 | 회사 | 날짜 | 완료율 | 상태
|
||||||
|
```
|
||||||
|
|
||||||
|
## HTMX 호환성
|
||||||
|
|
||||||
|
- JavaScript/React 기반 페이지이므로 **HX-Redirect 필요**
|
||||||
|
- API 호출로 동적 CRUD 관리
|
||||||
|
- `@push('scripts')` 블록에 스크립트 포함
|
||||||
102
features/sales/partner-approvals.md
Normal file
102
features/sales/partner-approvals.md
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
# 영업파트너승인
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
|
||||||
|
영업파트너승인은 신규 영업파트너 등록 신청을 검토하고 승인/반려를 처리하는 기능입니다.
|
||||||
|
본사 관리자 전용 페이지로, 신청자의 정보와 서류를 확인하고 일괄 처리할 수 있습니다.
|
||||||
|
|
||||||
|
- **라우트**: `GET /sales/managers/approvals`
|
||||||
|
- **미들웨어**: `auth`, `hq.member` + 관리자 권한 체크
|
||||||
|
- **UI 기술**: Blade + HTMX + Tailwind CSS
|
||||||
|
|
||||||
|
## 파일 구조
|
||||||
|
|
||||||
|
```
|
||||||
|
mng/
|
||||||
|
├── app/Http/Controllers/Sales/
|
||||||
|
│ └── SalesManagerController.php # 파트너관리와 동일 컨트롤러 (승인 메서드 포함)
|
||||||
|
├── app/Services/Sales/
|
||||||
|
│ └── SalesManagerService.php # approve(), reject() 로직
|
||||||
|
└── resources/views/sales/managers/
|
||||||
|
└── approvals.blade.php # 승인 관리 페이지
|
||||||
|
```
|
||||||
|
|
||||||
|
## 라우트
|
||||||
|
|
||||||
|
```php
|
||||||
|
// routes/web.php (sales prefix 그룹 내, resource 전에 정의)
|
||||||
|
GET /managers/approvals → approvals() 승인 목록 페이지
|
||||||
|
POST /managers/approvals/{id}/approve → approveFromList() 목록에서 승인
|
||||||
|
POST /managers/approvals/{id}/reject → rejectFromList() 목록에서 반려
|
||||||
|
```
|
||||||
|
|
||||||
|
## 컨트롤러
|
||||||
|
|
||||||
|
### SalesManagerController (승인 관련 메서드)
|
||||||
|
|
||||||
|
| 메서드 | HTTP | 설명 | 권한 |
|
||||||
|
|--------|------|------|------|
|
||||||
|
| `approvals()` | GET | 승인 대기 목록 페이지 | 관리자 전용 |
|
||||||
|
| `approveFromList()` | POST | 목록에서 승인 처리 | 관리자 전용 |
|
||||||
|
| `rejectFromList()` | POST | 목록에서 반려 처리 | 관리자 전용 |
|
||||||
|
| `approve()` | POST | 상세에서 승인 | - |
|
||||||
|
| `reject()` | POST | 상세에서 반려 | - |
|
||||||
|
|
||||||
|
### 승인 처리 흐름
|
||||||
|
|
||||||
|
```
|
||||||
|
영업파트너 등록 신청 (store)
|
||||||
|
↓
|
||||||
|
approval_status = 'pending' (Users 테이블)
|
||||||
|
↓
|
||||||
|
관리자 승인 목록에서 확인
|
||||||
|
├── approveFromList() → status = 'approved'
|
||||||
|
│ ├── approved_at 기록
|
||||||
|
│ └── approved_by 기록
|
||||||
|
│
|
||||||
|
└── rejectFromList() → status = 'rejected'
|
||||||
|
└── rejection_reason 저장 (필수)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 응답 방식
|
||||||
|
|
||||||
|
```
|
||||||
|
HTMX 요청 → JsonResponse (success, message)
|
||||||
|
일반 요청 → Redirect (redirect back)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 뷰 구성
|
||||||
|
|
||||||
|
### approvals.blade.php
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─ 페이지 헤더 ──────────────────────
|
||||||
|
│ 제목: "영업파트너 승인관리"
|
||||||
|
│
|
||||||
|
├─ 통계 카드 ────────────────────────
|
||||||
|
│ 승인 대기 | 오늘 승인 | 오늘 반려
|
||||||
|
│
|
||||||
|
├─ 검색/필터 영역 ──────────────────
|
||||||
|
│ 검색 (이름, 아이디, 이메일, 전화번호)
|
||||||
|
│
|
||||||
|
├─ 2분할 레이아웃 ──────────────────
|
||||||
|
│ ┌─ 좌: 승인 대기 ────────────┐ ┌─ 우: 승인 완료 ─────────────┐
|
||||||
|
│ │ 신청자명 | 역할 | 유치자 │ │ 파트너명 | 승인일 | 승인자 │
|
||||||
|
│ │ └─ [승인] [반려] 버튼 │ │ │
|
||||||
|
│ └────────────────────────────┘ └─────────────────────────────┘
|
||||||
|
│
|
||||||
|
└─ 상세 모달 ───────────────────────
|
||||||
|
파트너 정보 (이름, 아이디, 이메일, 전화)
|
||||||
|
계층 정보 (레벨, 추천인)
|
||||||
|
등록 서류 목록 (다운로드/삭제)
|
||||||
|
[승인] [반려] 버튼
|
||||||
|
```
|
||||||
|
|
||||||
|
## 반려 처리
|
||||||
|
|
||||||
|
```
|
||||||
|
반려 시:
|
||||||
|
- rejection_reason (반려 사유) 필수 입력
|
||||||
|
- 상태: pending → rejected
|
||||||
|
- 반려 후 재신청 가능
|
||||||
|
```
|
||||||
166
features/sales/partners.md
Normal file
166
features/sales/partners.md
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
# 파트너관리
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
|
||||||
|
파트너관리는 영업파트너(판매자/매니저)의 등록, 수정, 역할 관리, 서류 관리를 수행하는 기능입니다.
|
||||||
|
파트너 등록 신청, 서류 업로드, 역할 부여/위임, 계층 구조(추천인) 관리를 지원합니다.
|
||||||
|
|
||||||
|
- **라우트**: `GET /sales/managers`
|
||||||
|
- **미들웨어**: `auth`, `hq.member`
|
||||||
|
- **UI 기술**: Blade + HTMX + Alpine.js + Tailwind CSS
|
||||||
|
|
||||||
|
## 파일 구조
|
||||||
|
|
||||||
|
```
|
||||||
|
mng/
|
||||||
|
├── app/Http/Controllers/Sales/
|
||||||
|
│ └── SalesManagerController.php # 메인 컨트롤러 (425줄)
|
||||||
|
├── app/Services/Sales/
|
||||||
|
│ └── SalesManagerService.php # 비즈니스 로직 서비스
|
||||||
|
├── app/Models/Sales/
|
||||||
|
│ ├── SalesPartner.php # 영업파트너 모델
|
||||||
|
│ └── SalesManagerDocument.php # 파트너 서류 모델
|
||||||
|
└── resources/views/sales/managers/
|
||||||
|
├── index.blade.php # 파트너 목록
|
||||||
|
├── create.blade.php # 등록 폼
|
||||||
|
├── show.blade.php # 상세 페이지
|
||||||
|
├── edit.blade.php # 수정 폼
|
||||||
|
└── partials/
|
||||||
|
├── show-modal.blade.php # 상세 모달
|
||||||
|
└── edit-modal.blade.php # 수정 모달
|
||||||
|
|
||||||
|
api/
|
||||||
|
└── database/migrations/
|
||||||
|
└── 2026_01_29_100000_create_sales_partners_table.php
|
||||||
|
```
|
||||||
|
|
||||||
|
## 라우트
|
||||||
|
|
||||||
|
```php
|
||||||
|
// routes/web.php (sales prefix 그룹 내)
|
||||||
|
|
||||||
|
// Resource 라우트
|
||||||
|
GET /managers → index() 파트너 목록
|
||||||
|
GET /managers/create → create() 등록 폼
|
||||||
|
POST /managers → store() 등록 처리
|
||||||
|
GET /managers/{id} → show() 상세 페이지
|
||||||
|
GET /managers/{id}/edit → edit() 수정 폼
|
||||||
|
PUT /managers/{id} → update() 수정 처리
|
||||||
|
DELETE /managers/{id} → destroy() 비활성화 (관리자)
|
||||||
|
|
||||||
|
// 추가 라우트
|
||||||
|
GET /managers/{id}/modal-show → modalShow() 상세 모달
|
||||||
|
GET /managers/{id}/modal-edit → modalEdit() 수정 모달
|
||||||
|
POST /managers/{id}/approve → approve() 승인
|
||||||
|
POST /managers/{id}/reject → reject() 반려
|
||||||
|
POST /managers/{id}/delegate-role → delegateRole() 역할 위임
|
||||||
|
POST /managers/{id}/assign-role → assignRole() 역할 부여
|
||||||
|
POST /managers/{id}/remove-role → removeRole() 역할 제거
|
||||||
|
GET /managers/{id}/documents/{docId}/download → downloadDocument() 서류 다운로드
|
||||||
|
DELETE /managers/{id}/documents/{docId} → deleteDocument() 서류 삭제
|
||||||
|
```
|
||||||
|
|
||||||
|
## 컨트롤러
|
||||||
|
|
||||||
|
### SalesManagerController
|
||||||
|
|
||||||
|
| 메서드 | HTTP | 설명 |
|
||||||
|
|--------|------|------|
|
||||||
|
| `index()` | GET | 파트너 목록 (현재 사용자 유치분) |
|
||||||
|
| `create()` | GET | 등록 폼 |
|
||||||
|
| `store()` | POST | 파트너 등록 (서류 업로드 포함) |
|
||||||
|
| `show()` | GET | 상세 페이지 |
|
||||||
|
| `edit()` | GET | 수정 폼 |
|
||||||
|
| `update()` | PUT | 정보 수정 |
|
||||||
|
| `destroy()` | DELETE | 비활성화 (관리자 전용) |
|
||||||
|
| `modalShow()` | GET | 상세 모달 (HTMX) |
|
||||||
|
| `modalEdit()` | GET | 수정 모달 (HTMX) |
|
||||||
|
| `delegateRole()` | POST | 상담매니저 역할 위임 |
|
||||||
|
| `assignRole()` | POST | 역할 부여 (sales/manager) |
|
||||||
|
| `removeRole()` | POST | 역할 제거 |
|
||||||
|
| `downloadDocument()` | GET | 서류 파일 다운로드 |
|
||||||
|
| `deleteDocument()` | DELETE | 서류 파일 삭제 |
|
||||||
|
|
||||||
|
### SalesManagerService
|
||||||
|
|
||||||
|
| 메서드 | 설명 |
|
||||||
|
|--------|------|
|
||||||
|
| `getSalesPartners()` | 필터 적용 파트너 목록 조회 |
|
||||||
|
| `getStats()` | 파트너 통계 계산 |
|
||||||
|
| `getApprovalStats()` | 승인 관련 통계 |
|
||||||
|
| `createSalesPartner()` | 파트너 생성 |
|
||||||
|
| `updateSalesPartner()` | 파트너 수정 |
|
||||||
|
| `approve()` | 승인 처리 |
|
||||||
|
| `reject()` | 반려 처리 |
|
||||||
|
|
||||||
|
## 모델
|
||||||
|
|
||||||
|
### SalesPartner
|
||||||
|
|
||||||
|
**테이블**: `sales_partners`
|
||||||
|
|
||||||
|
| 필드 | 타입 | 설명 |
|
||||||
|
|------|------|------|
|
||||||
|
| `user_id` | bigint (FK) | 연결된 사용자 ID |
|
||||||
|
| `partner_code` | string | 파트너 고유 코드 (SP + 연도 + 순번) |
|
||||||
|
| `partner_type` | string | individual(개인) / corporate(법인) |
|
||||||
|
| `commission_rate` | decimal(5,2) | 기본 수수료율 |
|
||||||
|
| `manager_commission_rate` | decimal(5,2) | 관리자 수수료율 |
|
||||||
|
| `bank_name` | string | 은행명 |
|
||||||
|
| `account_number` | string | 계좌번호 |
|
||||||
|
| `account_holder` | string | 예금주 |
|
||||||
|
| `status` | string | pending / active / inactive / suspended |
|
||||||
|
| `approved_at` | timestamp | 승인 일시 |
|
||||||
|
| `approved_by` | bigint (FK) | 승인자 ID |
|
||||||
|
| `total_contracts` | int | 총 계약 건수 (캐시) |
|
||||||
|
| `total_commission` | decimal | 총 수당 (캐시) |
|
||||||
|
|
||||||
|
- SoftDeletes 적용
|
||||||
|
|
||||||
|
### SalesManagerDocument
|
||||||
|
|
||||||
|
**테이블**: `sales_manager_documents`
|
||||||
|
|
||||||
|
- 파트너 등록 시 필수 서류 관리 (신분증, 통장사본 등)
|
||||||
|
- `DOCUMENT_TYPES` 상수로 서류 타입 정의
|
||||||
|
|
||||||
|
### 파트너 계층 구조
|
||||||
|
|
||||||
|
```
|
||||||
|
User 모델의 parent_id를 통한 다단계 구조:
|
||||||
|
|
||||||
|
추천인 (parent)
|
||||||
|
└── 영업파트너 (children)
|
||||||
|
└── 하위 파트너 (children)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 뷰 구성
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─ 페이지 헤더 ──────────────────────
|
||||||
|
│ 제목: "파트너관리"
|
||||||
|
│ [등록] 버튼
|
||||||
|
│
|
||||||
|
├─ 통계 카드 ────────────────────────
|
||||||
|
│ 전체 | 활성 | 대기중 | 비활성
|
||||||
|
│
|
||||||
|
├─ 필터 영역 ────────────────────────
|
||||||
|
│ 검색 (이름, 아이디) | 상태 필터 | 타입 필터
|
||||||
|
│
|
||||||
|
├─ 파트너 목록 테이블 ───────────────
|
||||||
|
│ 이름 | 파트너코드 | 타입 | 수수료율 | 계약수 | 상태 | 작업
|
||||||
|
│ └─ 작업: 상세, 수정, 역할관리, 승인/반려
|
||||||
|
│
|
||||||
|
├─ 등록 폼 ─────────────────────────
|
||||||
|
│ 사용자 정보, 파트너 타입, 수수료율
|
||||||
|
│ 계좌 정보, 서류 업로드
|
||||||
|
│
|
||||||
|
└─ 상세/수정 모달 ──────────────────
|
||||||
|
파트너 정보, 계층, 서류 목록, 역할 관리
|
||||||
|
```
|
||||||
|
|
||||||
|
## HTMX 호환성
|
||||||
|
|
||||||
|
- Blade + HTMX 기반으로 **HX-Redirect 불필요**
|
||||||
|
- 모달로 상세/수정 처리
|
||||||
|
- HTMX 또는 JavaScript AJAX 호출
|
||||||
175
features/sales/products.md
Normal file
175
features/sales/products.md
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
# 상품관리
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
|
||||||
|
상품관리는 영업에 사용되는 상품(프로그램)을 카테고리별로 등록하고 가격/수당률을 설정하는 기능입니다.
|
||||||
|
카테고리 관리, 상품 CRUD, 순서 조정, 가격/수당률 설정, 영업 시나리오 연동을 지원합니다.
|
||||||
|
|
||||||
|
- **라우트**: `GET /sales/products`
|
||||||
|
- **미들웨어**: `auth`, `hq.member` (본사 전용)
|
||||||
|
- **UI 기술**: Blade + Alpine.js + HTMX + Tailwind CSS
|
||||||
|
|
||||||
|
## 파일 구조
|
||||||
|
|
||||||
|
```
|
||||||
|
mng/
|
||||||
|
├── app/Http/Controllers/Sales/
|
||||||
|
│ └── SalesProductController.php # 메인 컨트롤러 (12개 메서드)
|
||||||
|
├── app/Models/Sales/
|
||||||
|
│ ├── SalesProduct.php # 상품 모델
|
||||||
|
│ └── SalesProductCategory.php # 카테고리 모델
|
||||||
|
└── resources/views/sales/products/
|
||||||
|
├── index.blade.php # 메인 페이지
|
||||||
|
└── partials/
|
||||||
|
└── product-list.blade.php # 상품 목록 파셜 (HTMX)
|
||||||
|
|
||||||
|
api/
|
||||||
|
└── database/migrations/
|
||||||
|
├── 2026_01_29_150000_create_sales_products_tables.php
|
||||||
|
├── 2026_01_29_161626_add_partner_manager_commission_to_sales_products_table.php
|
||||||
|
└── 2026_01_29_162847_add_registration_fee_to_sales_products_table.php
|
||||||
|
```
|
||||||
|
|
||||||
|
## 라우트
|
||||||
|
|
||||||
|
```php
|
||||||
|
// routes/web.php (sales/products prefix 그룹 내)
|
||||||
|
|
||||||
|
// 상품 관리
|
||||||
|
GET /products → index() 메인 페이지
|
||||||
|
GET /products/list → productList() 카테고리별 상품 목록 (HTMX)
|
||||||
|
POST /products → store() 상품 등록
|
||||||
|
PUT /products/{id} → update() 상품 수정
|
||||||
|
DELETE /products/{id} → destroy() 상품 삭제
|
||||||
|
POST /products/{id}/toggle → toggleActive() 활성화 토글
|
||||||
|
POST /products/reorder → reorder() 순서 변경
|
||||||
|
|
||||||
|
// 카테고리 관리
|
||||||
|
GET /products/categories → categories() 카테고리 목록
|
||||||
|
POST /products/categories → storeCategory() 카테고리 생성
|
||||||
|
PUT /products/categories/{id} → updateCategory() 카테고리 수정
|
||||||
|
DELETE /products/categories/{id} → deleteCategory() 카테고리 삭제
|
||||||
|
|
||||||
|
// API (영업 시나리오용)
|
||||||
|
GET /products/api/list → getProductsApi() 활성 상품 목록
|
||||||
|
```
|
||||||
|
|
||||||
|
## 컨트롤러
|
||||||
|
|
||||||
|
### SalesProductController
|
||||||
|
|
||||||
|
| 메서드 | HTTP | 설명 |
|
||||||
|
|--------|------|------|
|
||||||
|
| `index()` | GET | 메인 페이지 (HX-Redirect 처리) |
|
||||||
|
| `productList()` | GET | 카테고리별 상품 목록 (HTMX 파셜) |
|
||||||
|
| `store()` | POST | 상품 등록 (코드 중복 체크, 자동 순서) |
|
||||||
|
| `update()` | PUT | 상품 수정 (부분 업데이트 허용) |
|
||||||
|
| `destroy()` | DELETE | 상품 삭제 (Soft Delete) |
|
||||||
|
| `toggleActive()` | POST | 활성화/비활성화 토글 |
|
||||||
|
| `reorder()` | POST | 다중 상품 순서 변경 (배치) |
|
||||||
|
| `categories()` | GET | 활성 카테고리 목록 |
|
||||||
|
| `storeCategory()` | POST | 카테고리 생성 (코드 unique) |
|
||||||
|
| `updateCategory()` | PUT | 카테고리 수정 |
|
||||||
|
| `deleteCategory()` | DELETE | 카테고리 삭제 (하위 상품 있으면 실패) |
|
||||||
|
| `getProductsApi()` | GET | API: 활성 카테고리+상품 (영업 시나리오용) |
|
||||||
|
|
||||||
|
## 모델
|
||||||
|
|
||||||
|
### SalesProductCategory
|
||||||
|
|
||||||
|
**테이블**: `sales_product_categories`
|
||||||
|
|
||||||
|
| 필드 | 타입 | 설명 |
|
||||||
|
|------|------|------|
|
||||||
|
| `code` | string(50) | 카테고리 코드 (unique) |
|
||||||
|
| `name` | string(100) | 카테고리명 |
|
||||||
|
| `description` | text | 설명 |
|
||||||
|
| `base_storage` | string(20) | 기본 제공 용량 (기본: 100GB) |
|
||||||
|
| `display_order` | int | 표시 순서 |
|
||||||
|
| `is_active` | boolean | 활성화 |
|
||||||
|
|
||||||
|
- SoftDeletes 적용
|
||||||
|
- 관계: `products()`, `activeProducts()`
|
||||||
|
- Scope: `active()`, `ordered()`
|
||||||
|
|
||||||
|
### SalesProduct
|
||||||
|
|
||||||
|
**테이블**: `sales_products`
|
||||||
|
|
||||||
|
| 필드 | 타입 | 설명 |
|
||||||
|
|------|------|------|
|
||||||
|
| `category_id` | bigint (FK) | 카테고리 ID |
|
||||||
|
| `code` | string(50) | 상품 코드 (카테고리별 unique) |
|
||||||
|
| `name` | string(100) | 상품명 |
|
||||||
|
| `description` | text | 설명 (프로그램 타입) |
|
||||||
|
| `development_fee` | decimal(15,2) | 개발비 |
|
||||||
|
| `registration_fee` | decimal(15,2) | 가입비 (할인가) |
|
||||||
|
| `subscription_fee` | decimal(15,2) | 월 구독료 |
|
||||||
|
| `partner_commission_rate` | decimal(5,2) | 영업파트너 수당율 (기본 20%) |
|
||||||
|
| `manager_commission_rate` | decimal(5,2) | 매니저 수당율 (기본 5%) |
|
||||||
|
| `allow_flexible_pricing` | boolean | 재량권 허용 여부 |
|
||||||
|
| `is_required` | boolean | 필수 선택 여부 |
|
||||||
|
| `display_order` | int | 표시 순서 |
|
||||||
|
| `is_active` | boolean | 활성화 |
|
||||||
|
|
||||||
|
- SoftDeletes 적용
|
||||||
|
- Unique Key: `(category_id, code)`
|
||||||
|
- Scope: `active()`, `ordered()`
|
||||||
|
- Accessor: `total_commission_rate`, `commission`, `formatted_*_fee`
|
||||||
|
|
||||||
|
### SalesContractProduct (계약별 선택 상품)
|
||||||
|
|
||||||
|
**테이블**: `sales_contract_products`
|
||||||
|
|
||||||
|
| 필드 | 타입 | 설명 |
|
||||||
|
|------|------|------|
|
||||||
|
| `tenant_id` | bigint (FK, nullable) | 테넌트 ID |
|
||||||
|
| `management_id` | bigint (FK) | 영업관리 ID |
|
||||||
|
| `category_id` | bigint (FK) | 선택 카테고리 |
|
||||||
|
| `product_id` | bigint (FK) | 선택 상품 |
|
||||||
|
| `development_fee` | decimal(15,2) | 적용 개발비 |
|
||||||
|
| `registration_fee` | decimal(15,2) | 적용 가입비 |
|
||||||
|
| `subscription_fee` | decimal(15,2) | 적용 구독료 |
|
||||||
|
| `discount_rate` | decimal(5,2) | 할인율 (기본 0%) |
|
||||||
|
| `notes` | text | 비고 |
|
||||||
|
| `created_by` | bigint (FK) | 등록자 |
|
||||||
|
|
||||||
|
## 뷰 구성
|
||||||
|
|
||||||
|
### index.blade.php
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─ 페이지 헤더 ──────────────────────
|
||||||
|
│ 제목: "상품관리"
|
||||||
|
│ [카테고리 관리] 버튼
|
||||||
|
│
|
||||||
|
├─ 카테고리 탭 ──────────────────────
|
||||||
|
│ [카테고리A] [카테고리B] [카테고리C] ...
|
||||||
|
│ └─ 선택 시 HTMX로 상품 목록 갱신
|
||||||
|
│
|
||||||
|
├─ 상품 영역 ────────────────────────
|
||||||
|
│ 헤더: 카테고리명 + 기본 용량 + [상품 추가]
|
||||||
|
│
|
||||||
|
│ ┌─ 상품 카드 (그리드: 1/2/3열 반응형) ─┐
|
||||||
|
│ │ 상품명 + 필수/비활성 배지 + 코드 │
|
||||||
|
│ │ 프로그램 설명 │
|
||||||
|
│ │ 개발비(취소선) + 가입비(할인가) │
|
||||||
|
│ │ 월 구독료 │
|
||||||
|
│ │ 수당: 파트너 20%, 매니저 5% │
|
||||||
|
│ │ 재량권 허용/고정가 태그 + [삭제] │
|
||||||
|
│ └───────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
├─ 상품 등록/수정 모달 (Alpine.js) ──
|
||||||
|
│ 코드, 상품명, 설명
|
||||||
|
│ 개발비, 가입비, 구독료
|
||||||
|
│ 파트너 수당율, 매니저 수당율
|
||||||
|
│ 재량권 허용, 필수 선택
|
||||||
|
│
|
||||||
|
└─ 카테고리 관리 모달 ──────────────
|
||||||
|
코드, 카테고리명, 설명, 기본 용량
|
||||||
|
```
|
||||||
|
|
||||||
|
## HTMX 호환성
|
||||||
|
|
||||||
|
- Alpine.js 스크립트가 `@push('scripts')`에 있어 **HX-Redirect 필요**
|
||||||
|
- 카테고리 탭 전환은 HTMX `hx-get`으로 부분 로드
|
||||||
189
features/sales/prospects.md
Normal file
189
features/sales/prospects.md
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
# 영업파트너 고객관리
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
|
||||||
|
영업파트너 고객관리는 영업파트너가 명함을 등록하여 영업권을 확보하고,
|
||||||
|
고객과의 계약 진행을 관리하는 기능입니다.
|
||||||
|
명함 등록, 영업권 유효기간(2개월), 사업자번호 중복 체크, 테넌트 전환을 지원합니다.
|
||||||
|
|
||||||
|
- **라우트**: `GET /sales/prospects`
|
||||||
|
- **미들웨어**: `auth`, `hq.member`
|
||||||
|
- **UI 기술**: Blade + HTMX + Tailwind CSS
|
||||||
|
|
||||||
|
## 파일 구조
|
||||||
|
|
||||||
|
```
|
||||||
|
mng/
|
||||||
|
├── app/Http/Controllers/Sales/
|
||||||
|
│ └── TenantProspectController.php # 메인 컨트롤러 (12개 메서드)
|
||||||
|
├── app/Services/Sales/
|
||||||
|
│ └── TenantProspectService.php # 비즈니스 로직 서비스
|
||||||
|
├── app/Models/Sales/
|
||||||
|
│ └── TenantProspect.php # 가망고객 모델
|
||||||
|
└── resources/views/sales/prospects/
|
||||||
|
├── index.blade.php # 영업권 목록
|
||||||
|
├── create.blade.php # 명함 등록 폼
|
||||||
|
├── show.blade.php # 상세 페이지
|
||||||
|
├── edit.blade.php # 수정 폼
|
||||||
|
└── partials/
|
||||||
|
├── show-modal.blade.php # 상세 모달
|
||||||
|
└── edit-modal.blade.php # 수정 모달
|
||||||
|
|
||||||
|
api/
|
||||||
|
└── database/migrations/
|
||||||
|
├── 2026_01_27_221000_create_tenant_prospects_table.php
|
||||||
|
└── 2026_01_28_090000_add_attachments_to_tenant_prospects_table.php
|
||||||
|
```
|
||||||
|
|
||||||
|
## 라우트
|
||||||
|
|
||||||
|
```php
|
||||||
|
// routes/web.php (sales prefix 그룹 내)
|
||||||
|
|
||||||
|
// Resource 라우트
|
||||||
|
GET /prospects → index() 영업권 목록 (본인 기준)
|
||||||
|
GET /prospects/create → create() 명함 등록 폼
|
||||||
|
POST /prospects → store() 명함 등록 처리
|
||||||
|
GET /prospects/{id} → show() 상세 페이지
|
||||||
|
GET /prospects/{id}/edit → edit() 수정 폼
|
||||||
|
PUT /prospects/{id} → update() 수정 처리
|
||||||
|
DELETE /prospects/{id} → destroy() 삭제 (관리자)
|
||||||
|
|
||||||
|
// 추가 라우트
|
||||||
|
POST /prospects/{id}/convert → convert() 테넌트 전환
|
||||||
|
POST /prospects/check-business-number → checkBusinessNumber() 사업자번호 중복 체크
|
||||||
|
DELETE /prospects/{id}/attachment → deleteAttachment() 첨부파일 삭제
|
||||||
|
GET /prospects/{id}/modal-show → modalShow() 상세 모달
|
||||||
|
GET /prospects/{id}/modal-edit → modalEdit() 수정 모달
|
||||||
|
```
|
||||||
|
|
||||||
|
## 컨트롤러
|
||||||
|
|
||||||
|
### TenantProspectController
|
||||||
|
|
||||||
|
| 메서드 | HTTP | 설명 |
|
||||||
|
|--------|------|------|
|
||||||
|
| `index()` | GET | 영업권 목록 (현재 사용자 기준) |
|
||||||
|
| `create()` | GET | 명함 등록 폼 |
|
||||||
|
| `store()` | POST | 명함 등록 (등록자 = 현재 사용자) |
|
||||||
|
| `show()` | GET | 상세 페이지 |
|
||||||
|
| `edit()` | GET | 수정 폼 |
|
||||||
|
| `update()` | PUT | 정보 수정 |
|
||||||
|
| `destroy()` | DELETE | 삭제 (관리자 전용) |
|
||||||
|
| `convert()` | POST | 영업권 → 테넌트 전환 |
|
||||||
|
| `checkBusinessNumber()` | POST | 사업자번호 중복 체크 (AJAX) |
|
||||||
|
| `modalShow()` | GET | 상세 모달 |
|
||||||
|
| `modalEdit()` | GET | 수정 모달 |
|
||||||
|
| `deleteAttachment()` | DELETE | 첨부 이미지 삭제 |
|
||||||
|
|
||||||
|
### TenantProspectService
|
||||||
|
|
||||||
|
| 메서드 | 설명 |
|
||||||
|
|--------|------|
|
||||||
|
| `register()` | 명함 등록 (영업권 확보), expires_at = 등록일 + 2개월 |
|
||||||
|
| `update()` | 정보 수정 + 파일 업로드 (명함/신분증/통장) |
|
||||||
|
| `convertToTenant()` | 영업권 → 테넌트 전환 (Tenant + user_tenants 생성) |
|
||||||
|
| `expireOldProspects()` | 만료 영업권 자동 처리 (배치) |
|
||||||
|
| `canRegister()` | 사업자번호 등록 가능 여부 확인 |
|
||||||
|
| `getProspects()` | 목록 조회 (검색, 상태, 파트너 필터) |
|
||||||
|
| `getStats()` | 통계 (total, active, expired, converted) |
|
||||||
|
| `uploadAttachment()` | 파일 업로드 (tenant disk) |
|
||||||
|
| `deleteAttachment()` | 파일 삭제 |
|
||||||
|
|
||||||
|
## 모델
|
||||||
|
|
||||||
|
### TenantProspect
|
||||||
|
|
||||||
|
**테이블**: `tenant_prospects`
|
||||||
|
|
||||||
|
| 필드 | 타입 | 설명 |
|
||||||
|
|------|------|------|
|
||||||
|
| `business_number` | string(20) | 사업자번호 (중복 체크 키) |
|
||||||
|
| `company_name` | string(100) | 회사명 |
|
||||||
|
| `ceo_name` | string(50) | 대표자명 |
|
||||||
|
| `contact_phone` | string(20) | 연락처 |
|
||||||
|
| `contact_email` | string(100) | 이메일 |
|
||||||
|
| `address` | string(500) | 주소 |
|
||||||
|
| `registered_by` | bigint (FK) | 등록한 영업파트너 ID |
|
||||||
|
| `business_card_path` | string(500) | 명함 이미지 경로 |
|
||||||
|
| `id_card_path` | string(500) | 신분증 이미지 경로 |
|
||||||
|
| `bankbook_path` | string(500) | 통장 이미지 경로 |
|
||||||
|
| `status` | string(20) | active / expired / converted / completed |
|
||||||
|
| `registered_at` | timestamp | 등록일 |
|
||||||
|
| `expires_at` | timestamp | 만료일 (등록일 + 2개월) |
|
||||||
|
| `cooldown_ends_at` | timestamp | 재등록 가능일 (만료일 + 1개월) |
|
||||||
|
| `tenant_id` | bigint (FK, nullable) | 전환된 테넌트 ID |
|
||||||
|
| `converted_at` | timestamp | 전환일 |
|
||||||
|
| `converted_by` | bigint (FK) | 전환 처리자 ID |
|
||||||
|
| `memo` | text | 메모 |
|
||||||
|
|
||||||
|
- SoftDeletes 적용
|
||||||
|
|
||||||
|
#### 상태 흐름
|
||||||
|
|
||||||
|
```
|
||||||
|
명함 등록 → active (영업권 유효, 2개월)
|
||||||
|
│
|
||||||
|
├── convert() → converted (테넌트 전환 완료)
|
||||||
|
│ └→ completed (영업 완료)
|
||||||
|
│
|
||||||
|
└── (2개월 경과) → expired (만료)
|
||||||
|
└→ (1개월 쿨다운 후 재등록 가능)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 영업권 규칙
|
||||||
|
|
||||||
|
| 규칙 | 설명 |
|
||||||
|
|------|------|
|
||||||
|
| 유효기간 | 등록일로부터 2개월 |
|
||||||
|
| 쿨다운 | 만료 후 1개월간 재등록 불가 |
|
||||||
|
| 중복 체크 | 동일 사업자번호 중복 등록 방지 |
|
||||||
|
| 전환 | 영업권 → Tenant + user_tenants 자동 생성 |
|
||||||
|
|
||||||
|
#### 주요 속성/메서드
|
||||||
|
|
||||||
|
| 메서드 | 설명 |
|
||||||
|
|--------|------|
|
||||||
|
| `isActive()` | 영업권 유효 여부 |
|
||||||
|
| `isExpired()` | 만료 여부 |
|
||||||
|
| `isConverted()` | 테넌트 전환 완료 여부 |
|
||||||
|
| `canReRegister()` | 재등록 가능 여부 |
|
||||||
|
| `getStatusLabelAttribute()` | 상태 라벨 (영업중/완료/계약완료/대기중/만료) |
|
||||||
|
| `getStatusColorAttribute()` | Tailwind CSS 색상 |
|
||||||
|
| `getRemainingDaysAttribute()` | 남은 일수 |
|
||||||
|
|
||||||
|
## 뷰 구성
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─ 페이지 헤더 ──────────────────────
|
||||||
|
│ 제목: "고객관리 (영업권)"
|
||||||
|
│ [명함 등록] 버튼
|
||||||
|
│
|
||||||
|
├─ 통계 카드 ────────────────────────
|
||||||
|
│ 전체 | 영업중 | 만료 | 전환완료
|
||||||
|
│
|
||||||
|
├─ 필터 영역 ────────────────────────
|
||||||
|
│ 검색 (회사명, 사업자번호) | 상태 필터
|
||||||
|
│
|
||||||
|
├─ 영업권 목록 테이블 ──────────────
|
||||||
|
│ 회사명 | 사업자번호 | 대표자 | 연락처 | 상태 | 남은일수 | 작업
|
||||||
|
│ └─ 상태: 영업중(초록), 만료(빨강), 전환(파랑), 완료(회색) 배지
|
||||||
|
│ └─ 작업: 상세, 수정, 전환, 삭제
|
||||||
|
│
|
||||||
|
├─ 등록 폼 ─────────────────────────
|
||||||
|
│ 사업자번호 (중복 체크), 회사명, 대표자명
|
||||||
|
│ 연락처, 이메일, 주소
|
||||||
|
│ 명함 이미지 업로드
|
||||||
|
│ 신분증, 통장사본 (선택)
|
||||||
|
│
|
||||||
|
└─ 상세 모달 ───────────────────────
|
||||||
|
회사 정보 + 첨부파일 미리보기
|
||||||
|
영업권 상태 + 남은 기간
|
||||||
|
[테넌트 전환] 버튼
|
||||||
|
```
|
||||||
|
|
||||||
|
## HTMX 호환성
|
||||||
|
|
||||||
|
- Blade + HTMX 기반으로 **HX-Redirect 불필요**
|
||||||
|
- 사업자번호 중복 체크: AJAX 실시간 검증
|
||||||
|
- 모달로 상세/수정 처리
|
||||||
122
features/sales/sales-dashboard.md
Normal file
122
features/sales/sales-dashboard.md
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
# 영업관리 대시보드
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
|
||||||
|
영업관리 대시보드는 영업파트너/상담매니저의 수당 현황, 테넌트 진행률, 유치 파트너 활동을 종합적으로 보여주는 페이지입니다.
|
||||||
|
로그인한 사용자 기준의 실적 및 수당 정보를 실시간으로 제공합니다.
|
||||||
|
|
||||||
|
- **라우트**: `GET /sales/salesmanagement/dashboard`
|
||||||
|
- **미들웨어**: `auth`, `hq.member`
|
||||||
|
- **UI 기술**: Blade + HTMX + Alpine.js + Tailwind CSS
|
||||||
|
|
||||||
|
## 파일 구조
|
||||||
|
|
||||||
|
```
|
||||||
|
mng/
|
||||||
|
├── app/Http/Controllers/Sales/
|
||||||
|
│ └── SalesDashboardController.php # 메인 컨트롤러 (18개 메서드, 1,073줄)
|
||||||
|
└── resources/views/sales/dashboard/
|
||||||
|
├── index.blade.php # 메인 페이지
|
||||||
|
└── partials/
|
||||||
|
├── data-container.blade.php # HTMX 새로고침 컨테이너
|
||||||
|
├── stats.blade.php # 통계 카드
|
||||||
|
├── commission-by-role.blade.php # 역할별 수당
|
||||||
|
├── tenant-list.blade.php # 테넌트 목록
|
||||||
|
├── tenant-stats.blade.php # 테넌트 통계
|
||||||
|
├── partner-activity.blade.php # 유치 파트너 활동
|
||||||
|
├── my-commission.blade.php # 내 수당 정보
|
||||||
|
├── help-modal.blade.php # 도움말
|
||||||
|
└── prospect-row.blade.php # 가망고객 행
|
||||||
|
```
|
||||||
|
|
||||||
|
## 라우트
|
||||||
|
|
||||||
|
```php
|
||||||
|
// routes/web.php (sales prefix 그룹 내)
|
||||||
|
GET /salesmanagement/dashboard → index() 메인 페이지
|
||||||
|
GET /salesmanagement/dashboard/refresh → refresh() HTMX 부분 새로고침
|
||||||
|
GET /salesmanagement/dashboard/tenants → refreshTenantList() 테넌트 목록 갱신
|
||||||
|
GET /salesmanagement/dashboard/partner-activity → partnerActivity() 유치 파트너 활동
|
||||||
|
GET /salesmanagement/dashboard/help → helpGuide() 도움말 모달
|
||||||
|
GET /salesmanagement/dashboard/prospect/{id}/row → getProspectRow() 가망고객 행
|
||||||
|
GET /managers/list → getManagers() 매니저 목록
|
||||||
|
GET /managers/search → searchManagers() 매니저 검색
|
||||||
|
POST /tenants/{tenant}/assign-manager → assignManager() 매니저 지정
|
||||||
|
POST /prospects/{prospect}/assign-manager → assignProspectManager() 가망고객 매니저 지정
|
||||||
|
```
|
||||||
|
|
||||||
|
## 컨트롤러
|
||||||
|
|
||||||
|
### SalesDashboardController
|
||||||
|
|
||||||
|
| 메서드 | HTTP | 설명 |
|
||||||
|
|--------|------|------|
|
||||||
|
| `index()` | GET | 대시보드 메인 화면 |
|
||||||
|
| `refresh()` | GET | HTMX 부분 새로고침 |
|
||||||
|
| `getDashboardData()` | - | 대시보드 핵심 데이터 조회 (private) |
|
||||||
|
| `refreshTenantList()` | GET | 테넌트 목록 새로고침 |
|
||||||
|
| `getManagers()` | GET | 매니저 드롭다운 목록 |
|
||||||
|
| `searchManagers()` | GET | 매니저 검색 API |
|
||||||
|
| `partnerActivity()` | GET | 유치 파트너 활동 현황 |
|
||||||
|
| `getPartnerActivityData()` | - | 파트너 활동 데이터 (private) |
|
||||||
|
| `calculatePartnerSummaryStats()` | - | 파트너 요약 통계 (private) |
|
||||||
|
| `getPartnerActivitiesDetail()` | - | 파트너별 상세 활동 (private) |
|
||||||
|
| `getManagerOnlyProspects()` | - | 매니저 전용 가망고객 (private) |
|
||||||
|
| `getCommissionData()` | - | 수당 정보 조회 (private) |
|
||||||
|
| `getAllManagerUsers()` | - | 상담매니저 사용자 목록 (private) |
|
||||||
|
| `helpGuide()` | GET | 도움말 모달 |
|
||||||
|
| `getProspectRow()` | GET | 가망고객 개별 행 |
|
||||||
|
| `assignManager()` | POST | 테넌트 매니저 변경 |
|
||||||
|
| `assignProspectManager()` | POST | 가망고객 매니저 변경 |
|
||||||
|
| `calculateExpectedCommissionSummary()` | - | 예상 수당 계산 (private) |
|
||||||
|
|
||||||
|
### 수당 계산 로직
|
||||||
|
|
||||||
|
```
|
||||||
|
영업파트너 수당:
|
||||||
|
- 판매자 수당: 가입비 × 20%
|
||||||
|
- 협업지원금: 개발비 × 10% (인계 완료 시)
|
||||||
|
- 1차/2차 분할: 각 50%
|
||||||
|
|
||||||
|
매니저 수당:
|
||||||
|
- 1개월 구독료 (매니저 기본 수당)
|
||||||
|
- 1차/2차 분할: 각 50%
|
||||||
|
```
|
||||||
|
|
||||||
|
## 뷰 구성
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─ 페이지 헤더 ──────────────────────
|
||||||
|
│ 제목: "영업관리"
|
||||||
|
│ [새로고침] 버튼
|
||||||
|
│
|
||||||
|
├─ 탭 전환 (Alpine.js) ─────────────
|
||||||
|
│ [내 활동] | [유치 파트너 현황]
|
||||||
|
│
|
||||||
|
├─ 탭1: 내 활동 ─────────────────────
|
||||||
|
│ ├─ 통계 카드 (수당 요약)
|
||||||
|
│ │ 총 수당 | 지급완료 | 미지급 | 예상 수당
|
||||||
|
│ │
|
||||||
|
│ ├─ 역할별 수당 상세
|
||||||
|
│ │ 영업파트너 수당 | 매니저 수당
|
||||||
|
│ │
|
||||||
|
│ └─ 테넌트/가망고객 목록
|
||||||
|
│ 회사명 | 상태 | 진행률 | 수당 | 매니저 | 작업
|
||||||
|
│ └─ 매니저 지정 변경 (드롭다운)
|
||||||
|
│
|
||||||
|
├─ 탭2: 유치 파트너 현황 ────────────
|
||||||
|
│ ├─ 파트너 요약 통계
|
||||||
|
│ │ 총 파트너 | 활성 | 계약건수 | 총 수당
|
||||||
|
│ │
|
||||||
|
│ └─ 파트너별 활동 상세
|
||||||
|
│ 파트너명 | 등록 고객 | 계약 | 진행중 | 수당
|
||||||
|
│
|
||||||
|
└─ 도움말 모달 ──────────────────────
|
||||||
|
수당 계산 방식, 진행 단계 설명
|
||||||
|
```
|
||||||
|
|
||||||
|
## HTMX 호환성
|
||||||
|
|
||||||
|
- Blade + HTMX 기반으로 **HX-Redirect 불필요**
|
||||||
|
- `hx-get`으로 부분 새로고침 처리
|
||||||
|
- Alpine.js 탭 전환
|
||||||
Reference in New Issue
Block a user