# 견적 시스템 통합 분석 문서 **작성일:** 2025-11-12 (v1 분석) **원본 문서:** 00_baseline 폴더 내 14개 파일에서 견적 관련 내용 추출 **분석 범위:** 비즈니스 로직, 화면 설계, API 스펙, 구현 현황, Gap 분석 --- ## 1. 시스템 개요 ### 1.1 견적 시스템 핵심 기능 가변 크기 제품(셔터)의 견적을 자동 계산하는 ERP 시스템으로 4가지 핵심 자동화 기능 제공: | 기능 | 설명 | 구현 상태 | |------|------|----------| | 🔗 치수 자동 연결 | 상위 제품 치수 → 하위 제품 치수 자동 전달 | ❌ 미구현 | | 💰 단가 자동 연동 | 하위 품목 판매단가 → 상위 품목 원가 자동 반영 | ⚠️ 부분 | | 📊 BOM 전개 | 계층 구조 기반 구성품 자동 계산 | ✅ 프론트 구현 | | 💲 원가/판매가 자동 계산 | 치수 기반 실시간 견적 산출 | ✅ 프론트 구현 | ### 1.2 품목 코드 체계 ``` RM-XXX : 원자재 (Raw Material) - BOM 최하위, 가격만 정의 PT-XXX : 부품 (Part) - 구매/제작 구분 FG-XXX : 완제품 (Finished Goods) - 견적 대상 ``` --- ## 2. 비즈니스 프로세스 (6단계 Phase) ### Phase 1: 기초 데이터 설정 - **메뉴:** 기준정보 관리 > 사원 관리, 영업관리 > 매출처 관리 - **목적:** 견적서 작성을 위한 마스터 데이터 등록 - **항목:** 사원 정보, 매출처 정보 ### Phase 2: 원자재 등록 (RM) - **메뉴:** 생산관리 > 품목관리 (개선) - **등록 정보:** 품목명, 단위, 구매단가 - **예시:** RM-001 (알루미늄 압출재, 8,000원/M) ### Phase 3: 구매 부품 등록 (PT-구매) - **메뉴:** 생산관리 > 품목관리 (개선) - **등록 정보:** 품목명, 구매단가, 마진율 - **자동 계산:** `판매단가 = 구매단가 × (1 + 마진율/100)` - **예시:** PT-MOTOR-001 (구매 120,000원, 마진 50%, 판매 180,000원) ### Phase 4: 제작 부품 등록 (PT-제작, 가변 크기) - **중요 설정:** ✅ "가변 크기 제품" 체크 - **Step 1:** 치수 정의 (L: 길이, 기본값 3000mm) - **Step 2:** BOM 등록 (계산식: `L/1000` - 길이에 따른 자재 소요량) - **Step 3:** 원가 설정 (자재비 자동, 가공비 입력, 마진율 설정) ### Phase 5: 완제품 등록 (FG, 가변 크기 + 옵션) - **Step 1:** 기본 정보 + 가변 크기 체크 - **Step 2:** 치수 정의 (W, H) + 옵션 정의 (MOTOR, REMOTE) - **Step 3:** BOM 등록 (조건부 BOM: `MOTOR='Y'`) - **Step 4:** 원가 설정 (공임비, 설치비, 마진율) - **Step 5:** ⭐ **치수 연결 매핑** (세트.W → 레일.L, 세트.W → 커튼.W) ### Phase 6: 견적서 작성 (실시간 계산) - **메뉴:** 영업관리 > 견적관리 (개선) - **프로세스:** 품목 선택 → 치수/옵션 입력 → 실시간 계산 → 저장/출력 --- ## 3. 유저 스토리 (S1~S17) ### Phase 1: 자재/부품 마스터 등록 | Story | 역할 | 내용 | |-------|------|------| | S1 | 기준정보 담당자 | 원자재(RM) 등록 | | S2 | 기준정보 담당자 | 구매 부품(PT) 등록 | | S3 | 기준정보 담당자 | 제작 부품 등록 | ### Phase 2: 부품 BOM 및 원가 정의 | Story | 역할 | 내용 | |-------|------|------| | S4 | 생산기술 담당자 | 제작 부품 치수 정의 | | S5 | 생산기술 담당자 | 부품 BOM 생성 | | S6 | 생산기술 담당자 | BOM 소요량 수식 입력 (`G/1000*1.02`) | | S7 | 원가 관리팀 | 부품 매출 단가 설정 | ### Phase 3: 제품 BOM 및 최종 정책 정의 | Story | 역할 | 내용 | |-------|------|------| | S8 | 기준정보 담당자 | 최종 판매 제품(FG) 등록 | | S9 | 생산기술 담당자 | 제품 치수/옵션 정의 (W, H, MOTOR) | | S10 | 생산기술 담당자 | 제품 BOM 생성 (조건부: `MOTOR='Y'`) | | S11 | 생산기술 담당자 | ⭐ 치수 연결 매핑 정의 (W→G) | | S12 | 원가 관리팀 | 제품 최종 판매 정책 설정 | ### Phase 4: 견적 산출 | Story | 역할 | 내용 | |-------|------|------| | S13 | 영업 담당자 | 새 견적서 생성 | | S14 | 영업 담당자 | 가변 제품 견적서에 추가 | | S15 | 영업 담당자 | 고객 요구 사이즈/옵션 입력 | | S16 | 영업 담당자 | 실시간 견적 단가 확인 | | S17 | 영업 담당자 | 확정 견적 저장 및 PDF 출력 | --- ## 4. 원가 계산 로직 ### 4.1 제작 부품 원가 (PT-RAIL-VAR 예시, G=3500mm) ``` [자재비] 알루미늄: G/1000 × 1.02 × 8,000원 = 3.57M × 8,000 = 28,560원 브래킷: 8개 × 500원 = 4,000원 자재비 합계 = 32,560원 [총원가] 총원가 = 자재비 + 가공비 = 32,560 + 3,000 = 35,560원 [판매단가] 판매단가 = 총원가 × (1 + 마진율/100) = 35,560 × 1.2 = 42,672원 ``` ### 4.2 완제품 원가 (FG-SHUTTER-SET, W=3500, H=2500, MOTOR=Y) ``` [자재비 - 하위 구성품 판매단가 합계] 가이드레일 × 2: 42,672 × 2 = 85,344원 셔터 커튼 × 1: (면적 기반) = 291,664원 셔터 모터 × 1: 180,000원 (MOTOR=Y) 자재비 합계 = 557,008원 [총원가] 총원가 = 자재비 + 공임비 + 설치비 = 557,008 + 100,000 + 50,000 = 707,008원 [판매단가] 판매단가 = 총원가 × (1 + 마진율/100) = 707,008 × 1.25 = 883,760원 ``` ### 4.3 치수 자동 전달 흐름 ``` 견적 입력: 세트 W=3500, H=2500 ↓ 자동 전달 (치수 매핑) 가이드레일 G = 3500 (W→G 매핑) 셔터 커튼 W = 3500, H = 2500 ↓ 각 하위 품목 원가 자동 계산 상위 품목 자재비 = Σ(하위 판매단가) ``` --- ## 5. 화면 설계 ### 5.1 견적 관리 목록 (QuoteManagement3List.tsx) - **파일:** 788 lines - **StatCards:** 총 견적서, 수주 전환, 최종 확정, 총 견적금액 - **테이블 컬럼:** 견적번호, 작성일, 거래처, 담당자, 견적금액, 상태, 유효기한 - **기능:** 검색/필터, 수정 이력 조회, 산출내역서 보기 ### 5.2 견적 작성 (QuoteManagement3Write.tsx) - **파일:** 1,644 lines - **섹션:** 기본 정보, 견적 품목, 합계 정보, 특이사항 (Collapsible) - **핵심 기능:** - BOM 기반 자동 견적 계산 ⭐ - 수식 편집 UI (W, H 변수 지원) - 견적 수정 이력 관리 (Revision) - 견적번호 자동 생성 (KD-PR-250717-02) - 거래처/현장 자동 등록 ### 5.3 견적 계산 미리보기 UI ``` ┌─────────────────────────────────────┐ │ 구성품 목록 (BOM 전개) │ ├─────────────────────────────────────┤ │ • 가이드레일 (3.5m) × 2 85,344원 │ │ • 셔터 커튼 (8.75㎡) × 1 291,664원 │ │ • 셔터 모터 × 1 180,000원 │ ├─────────────────────────────────────┤ │ 원가 내역 │ ├─────────────────────────────────────┤ │ 자재비: 557,008원 │ │ 공임비: 100,000원 │ │ 설치비: 50,000원 │ │ 총 원가: 707,008원 │ ├─────────────────────────────────────┤ │ 견적 금액 │ ├─────────────────────────────────────┤ │ 판매단가: 883,760원 (마진 25%) │ │ 부가세: 88,376원 (10%) │ │ 총액: 972,136원 │ └─────────────────────────────────────┘ ``` --- ## 6. API 스펙 (필요/현황) ### 6.1 필요한 API 엔드포인트 | 엔드포인트 | 용도 | 구현 상태 | |------------|------|----------| | `POST /api/v1/quotes` | 견적서 생성 | ❓ 확인 필요 | | `POST /api/v1/quotes/{id}/items` | 품목 추가 | ❓ 확인 필요 | | `POST /api/v1/quotes/calculate` | 실시간 견적 계산 | ❌ 미구현 | | `GET /api/v1/quotes/{id}/pdf` | PDF 출력 | ❓ 확인 필요 | | `POST /api/v1/boms/{id}/dimension-mappings` | 치수 연결 매핑 | ❌ 미구현 | ### 6.2 견적 계산 API 스펙 (제안) ```json // POST /api/v1/quotes/calculate // Request { "product_id": 123, "dimensions": { "W": 3500, "H": 2500 }, "options": { "MOTOR": "Y", "REMOTE": "Y" }, "quantity": 1 } // Response { "bom_breakdown": [ { "item_code": "PT-RAIL-VAR", "quantity": 2, "unit_price": 42672, "amount": 85344 }, { "item_code": "PT-CURTAIN-VAR", "quantity": 1, "unit_price": 291664, "amount": 291664 }, { "item_code": "PT-MOTOR-001", "quantity": 1, "unit_price": 180000, "amount": 180000 } ], "cost_breakdown": { "material_cost": 557008, "labor_cost": 100000, "installation_cost": 50000, "total_cost": 707008 }, "pricing": { "unit_price": 883760, "margin_rate": 25, "vat": 88376, "total": 972136 } } ``` --- ## 7. 데이터 모델 ### 7.1 필요한 테이블/필드 | 테이블 | 필드 | 용도 | 상태 | |--------|------|------|------| | products | dimensions (JSON) | 치수 정의 | ❌ 없음 | | products | options (JSON) | 옵션 정의 | ⚠️ Material만 | | product_components | formula | BOM 소요량 계산식 | ❌ 없음 | | product_components | condition | 조건부 BOM | ❌ 없음 | | dimension_mappings | - | 치수 연결 매핑 | ❌ 테이블 없음 | | quotes | - | 견적서 | ✅ 존재 추정 | | quote_items | - | 견적 품목 | ✅ 존재 추정 | ### 7.2 치수 연결 매핑 테이블 (제안) ```sql CREATE TABLE dimension_mappings ( id BIGINT PRIMARY KEY, bom_id BIGINT NOT NULL, parent_product_id BIGINT NOT NULL, child_product_id BIGINT NOT NULL, parent_dimension VARCHAR(50) NOT NULL, -- 'W', 'H' child_dimension VARCHAR(50) NOT NULL, -- 'G', 'L' created_at TIMESTAMP, updated_at TIMESTAMP, FOREIGN KEY (bom_id) REFERENCES boms(id), FOREIGN KEY (parent_product_id) REFERENCES products(id), FOREIGN KEY (child_product_id) REFERENCES products(id) ); ``` --- ## 8. Gap 분석 (견적 관련) ### 8.1 Critical Gaps (P0) | Gap # | 항목 | 상태 | 예상 작업량 | |-------|------|------|------------| | #2 | 치수 연결 매핑 시스템 | ❌ 백엔드+프론트 미구현 | 1-2주 | | #3 | 주문 기반 견적 계산 API | ⚠️ 설계 BOM만 존재 | 1-2주 | | #4 | BOM formula 필드 | ❌ 프론트 로컬만 | 1주 | | #5 | BOM condition 필드 | ❌ 미구현 | 1-2주 | ### 8.2 현재 구현 상태 **✅ 프론트엔드 구현 완료:** - BOM 기반 자동 견적 계산 (QuoteManagement3Write.tsx) - 수식 편집 UI (W, H 변수 지원) - 견적 수정 이력 관리 (Revision) - 견적번호 자동 생성 **❌ 백엔드 미구현:** - 치수 연결 매핑 (dimension_mappings) - BOM formula/condition 필드 - 주문 기반 견적 계산 API - 프론트엔드에서 중복 구현 중 (백엔드 연동 필요) ### 8.3 해결 우선순위 ``` Week 1-2: 백엔드 핵심 기능 ├── dimension_mappings 테이블 생성 ├── product_components.formula 필드 추가 ├── product_components.condition 필드 추가 └── POST /api/v1/quotes/calculate API 개발 Week 3-4: 프론트엔드 연동 ├── 백엔드 API 연동 (중복 로직 제거) ├── 치수 매핑 UI 개발 └── BOM 에디터 리팩토링 ``` --- ## 9. 프론트엔드 컴포넌트 ### 9.1 견적 관련 컴포넌트 | 컴포넌트 | 파일 | 크기 | 상태 | |----------|------|------|------| | QuoteManagement3List | QuoteManagement3List.tsx | 788 lines | ✅ 완료 | | QuoteManagement3Write | QuoteManagement3Write.tsx | 1,644 lines | ⚠️ 리팩토링 필요 | | QuoteCalculationReport | QuoteCalculationReport.tsx | - | ✅ 존재 | | QuoteSimulation | QuoteSimulation.tsx | - | ✅ 기존 버전 | ### 9.2 리팩토링 제안 (QuoteManagement3Write.tsx) ``` QuoteManagement3Write.tsx (1,644 lines) ↓ 리팩토링 ├── pages/QuoteWritePage.tsx (100-150 lines) ├── organisms/QuoteFormSection.tsx (200-300 lines) ├── organisms/ProductSelectionSection.tsx (200-300 lines) ├── organisms/BOMCalculationTable.tsx (300-400 lines) ⭐ ├── hooks/useQuoteForm.ts (200-300 lines) ├── hooks/useBOMCalculation.ts (200-300 lines) ⭐ ├── hooks/useFormulaCalculator.ts (100-150 lines) ⭐ ├── hooks/useQuoteRevision.ts (150-200 lines) └── utils/quoteNumberGenerator.ts (50-100 lines) ``` --- ## 10. 견적 수정 이력 (Revision) 시스템 ### 10.1 데이터 구조 ```typescript interface QuoteRevision { revisionNumber: number; // 수정 차수 revisionDate: string; // 수정 일자 revisionReason: string; // 수정 사유 data: Partial; // 해당 시점 데이터 스냅샷 } interface QuoteData { currentRevision?: number; // 현재 수정 차수 isFinal?: boolean; // 최종 확정 여부 revisions?: QuoteRevision[]; // 수정 이력 배열 finalizedDate?: string; finalizedBy?: string; } ``` ### 10.2 견적번호 생성 규칙 ``` KD-{제품타입}-{날짜}-{순번} 예: KD-PR-250717-02 - KD: 회사 코드 - PR: 제품 타입 (SC: 스크린, PR: 철재) - 250717: 날짜 (YYMMDD) - 02: 당일 순번 ``` --- ## 11. 메뉴 구조 ``` 영업관리 ├── 리드 관리 ├── 매출처 관리 ├── 거래처 관리 ├── 견적 관리 (개선) ⭐ │ ├── 견적 목록 (QuoteManagement3List.tsx) │ └── 견적 작성 (QuoteManagement3Write.tsx) ├── 견적 관리 (기존 - 시뮬레이션) ├── 수주 관리 └── 영업 실적 생산관리 ├── 품목 관리 (개선) ⭐ ├── BOM 관리 (개선) ⭐ │ └── 치수 연결 탭 (신규 필요) └── ... ``` --- ## 12. 결론 ### 12.1 현재 상태 요약 | 영역 | 상태 | 설명 | |------|------|------| | 비즈니스 로직 | ✅ 정의 완료 | 6단계 Phase, 17개 유저 스토리 | | 화면 설계 | ✅ 구현 완료 | 견적 목록/작성 화면 | | 프론트엔드 | ⚠️ 부분 완료 | BOM 계산 구현, 리팩토링 필요 | | 백엔드 API | ❌ 미흡 | 치수 매핑, 계산 API 부재 | | DB 스키마 | ❌ 미흡 | dimension_mappings 등 부재 | ### 12.2 우선 작업 항목 1. **백엔드 (3-4주)** - dimension_mappings 테이블 생성 - BOM formula/condition 필드 추가 - 견적 계산 API 개발 2. **프론트엔드 (2-3주)** - 백엔드 API 연동 - 치수 매핑 UI 개발 - 컴포넌트 리팩토링 --- **문서 버전:** v1.0 (통합 분석본) **원본:** 00_baseline 폴더 14개 파일 **다음 단계:** v2 분석 (2025-12-18) 진행 중