# 영업파트너 고객관리 ## 개요 영업파트너 고객관리는 영업파트너가 명함을 등록하여 영업권을 확보하고, 고객과의 계약 진행을 관리하는 기능입니다. 명함 등록, 영업권 유효기간(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 실시간 검증 - 모달로 상세/수정 처리