Files
sam-docs/features/sales/products.md
김보곤 b6edc6db27 docs: [영업] 최저가 정책 및 개발비-구독료 연동 문서 반영
- customer-pricing.md: 최저가 정책, 개발비-구독료 연동 비율 섹션 추가
- partner-commission.md: 최저가와 수당 관계, 시뮬레이터 안내 섹션 추가
- products.md: min_development_fee/min_subscription_fee 필드, 시뮬레이터 연동 섹션 추가
2026-03-14 15:25:51 +09:00

10 KiB
Raw Blame History

상품관리

개요

상품관리는 영업에 사용되는 상품(프로그램)을 카테고리별로 등록하고 가격/수당률을 설정하는 기능입니다. 카테고리 관리, 상품 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
    ├── 2026_03_14_100000_add_min_fees_to_sales_product_categories_table.php
    └── 2026_03_14_100001_add_min_fees_to_sales_products_table.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)
min_development_fee decimal(15,2) 최저 개발비 (카테고리 레벨, 기본 0)
min_subscription_fee decimal(15,2) 최저 구독료 (카테고리 레벨, 기본 0)
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) 월 구독료
min_development_fee decimal(15,2) 최저 개발비 (이 금액 이하 설정 불가, 기본 0)
min_subscription_fee decimal(15,2) 최저 구독료 (이 금액 이하 설정 불가, 기본 0)
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) ──
│  코드, 상품명, 설명
│  개발비(원가), 개발비(적용가), 구독료
│  ┌─ 최저가 설정 (빨간 박스) ────────┐
│  │  최저 개발비, 최저 구독료          │
│  │  "절대 이 금액 이하로 내릴 수 없음"│
│  └──────────────────────────────────┘
│  파트너 수당율, 매니저 수당율
│  재량권 허용, 필수 선택
│
└─ 카테고리 관리 모달 ──────────────
   코드, 카테고리명, 설명, 기본 용량

최저가 정책

상품별로 최저 개발비최저 구독료를 설정할 수 있다. 설정된 최저가 이하로는 절대 가격을 내릴 수 없다.

적용 범위

영역 최저 개발비 최저 구독료
상품 등록/수정 (MNG) 서버 검증 서버 검증
가격 시뮬레이터 슬라이더 슬라이더 min 제한 연동 시 min 제한
프로모션 개발비 할인 할인 max 제한
프로모션 구독료 할인 할인 max 제한
개발비 전액 면제 최저가 설정 시 비활성화

검증 로직

  • 컨트롤러: store(), update()registration_fee >= min_development_fee, subscription_fee >= min_subscription_fee 검증
  • 시뮬레이터: setAdjustedFee()에서 Math.max(minDevFee, value) 적용
  • 프로모션: promoDevDiscountMax(), promoSubDiscountMaxPercent()로 슬라이더 max 제한

가격 시뮬레이터 연동

라우트: GET /sales/price-simulator

가격 시뮬레이터는 상품관리의 데이터를 기반으로 실시간 비용/수당 시뮬레이션을 제공한다.

개발비-구독료 연동 조절

토글 스위치로 활성화하는 기능이다. 개발비 슬라이더를 조정하면 구독료가 원래 비율을 유지하며 자동 연동된다.

비율 계산:

ratio = 원래 구독료 / 원래 개발비(할인가)
연동 구독료 = 조정된 개발비 × ratio (만원 단위 반올림)

예시 (개발비 2,000만원, 구독료 50만원인 상품):

조정된 개발비 비율 연동 구독료
2,000만원 2.5% 50만원
1,500만원 2.5% 38만원
1,000만원 2.5% 25만원
500만원 2.5% 13만원

제한사항:

  • 최저 구독료 이하로는 내려가지 않음
  • 연동 OFF 시 구독료가 원래값으로 즉시 복원
  • 프로모션 할인과 독립적으로 동작 (연동 → 프로모션 순서로 적용)

프로모션 할인과 최저가

프로모션 영역의 모든 할인 슬라이더는 최저가를 초과하지 않도록 max가 자동 제한된다.

프로모션 항목 max 산정 기준
개발비 할인 (%) (적용가 합계 - 최저 개발비 합계) / 적용가 합계 × 100
개발비 할인 (원) 적용가 합계 - 최저 개발비 합계
개발비 전액 면제 최저 개발비 > 0이면 체크박스 비활성화
구독료 할인 (%) (1 - 최저 구독료 합계 / 구독료 합계) × 100

HTMX 호환성

  • Alpine.js 스크립트가 @push('scripts')에 있어 HX-Redirect 필요
  • 카테고리 탭 전환은 HTMX hx-get으로 부분 로드