## 품목관리 수정 버그 수정 - FG(제품) 수정 시 품목명 반영 안되는 문제 해결 - productName → name 필드 매핑 추가 - FG 품목코드 = 품목명 동기화 로직 추가 - Materials(SM, RM, CS) 수정페이지 진입 오류 해결 - UNIQUE 제약조건 위반 오류 해결 ## Sales 페이지 - 거래처관리 (client-management-sales-admin) 페이지 구현 - 견적관리 (quote-management) 페이지 구현 - 관련 컴포넌트 및 훅 추가 ## 기타 - 회원가입 페이지 차단 처리 - 디버깅용 콘솔 로그 추가 (PUT 요청/응답 확인용) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
676 lines
19 KiB
Markdown
676 lines
19 KiB
Markdown
# 견적관리 API 요청서
|
||
|
||
> **작성일**: 2025-12-04
|
||
> **목적**: 견적관리 기능을 위한 백엔드 API 요청
|
||
> **참조**: sam-design/QuoteManagement3Write.tsx, QuoteManagement3Detail.tsx
|
||
|
||
---
|
||
|
||
## 1. 개요
|
||
|
||
### 1.1 기능 요약
|
||
견적관리 시스템은 다음 기능을 지원해야 합니다:
|
||
- 견적 CRUD (등록, 조회, 수정, 삭제)
|
||
- 견적 상태 관리 (임시저장 → 확정 → 수주전환)
|
||
- 견적 수정 이력 관리 (버전 관리)
|
||
- 견적 품목(BOM) 관리
|
||
- 자동 견적 산출 (수식 기반 계산) ← **백엔드 구현**
|
||
|
||
### 1.2 특이사항
|
||
- **자동 견적 산출 로직**은 백엔드에서 구현 예정 (수식 계산 엔진)
|
||
- 프론트엔드는 입력값을 전달하고 계산 결과를 받아서 표시
|
||
|
||
---
|
||
|
||
## 2. 데이터 모델
|
||
|
||
### 2.1 Quote (견적) - 메인 엔티티
|
||
|
||
```typescript
|
||
interface Quote {
|
||
// === 기본 정보 ===
|
||
id: number;
|
||
tenant_id: number;
|
||
quote_number: string; // 견적번호 (예: KD-SC-251204-01)
|
||
registration_date: string; // 등록일 (YYYY-MM-DD)
|
||
receipt_date: string; // 접수일
|
||
author: string; // 작성자
|
||
|
||
// === 발주처 정보 ===
|
||
client_id: number | null; // 거래처 ID (FK)
|
||
client_name: string; // 거래처명 (직접입력 대응)
|
||
manager: string | null; // 담당자
|
||
contact: string | null; // 연락처
|
||
|
||
// === 현장 정보 ===
|
||
site_id: number | null; // 현장 ID (FK, 별도 테이블 필요시)
|
||
site_name: string | null; // 현장명
|
||
site_code: string | null; // 현장코드
|
||
|
||
// === 제품 정보 ===
|
||
product_category: 'SCREEN' | 'STEEL'; // 제품 카테고리
|
||
product_id: number | null; // 선택된 제품 ID (품목마스터 FK)
|
||
product_code: string | null; // 제품코드
|
||
product_name: string | null; // 제품명
|
||
|
||
// === 규격 정보 ===
|
||
open_size_width: number | null; // 오픈사이즈 폭 (mm)
|
||
open_size_height: number | null; // 오픈사이즈 높이 (mm)
|
||
quantity: number; // 수량 (기본값: 1)
|
||
unit_symbol: string | null; // 부호
|
||
floors: string | null; // 층수
|
||
|
||
// === 금액 정보 ===
|
||
material_cost: number; // 재료비 합계
|
||
labor_cost: number; // 노무비
|
||
install_cost: number; // 설치비
|
||
subtotal: number; // 소계
|
||
discount_rate: number; // 할인율 (%)
|
||
discount_amount: number; // 할인금액
|
||
total_amount: number; // 최종 금액
|
||
|
||
// === 상태 관리 ===
|
||
status: 'draft' | 'sent' | 'approved' | 'rejected' | 'finalized' | 'converted';
|
||
current_revision: number; // 현재 수정 차수 (0부터 시작)
|
||
is_final: boolean; // 최종확정 여부
|
||
finalized_at: string | null; // 확정일시
|
||
finalized_by: number | null; // 확정자 ID
|
||
|
||
// === 기타 정보 ===
|
||
completion_date: string | null; // 납기일
|
||
remarks: string | null; // 비고
|
||
memo: string | null; // 메모
|
||
notes: string | null; // 특이사항
|
||
|
||
// === 시스템 필드 ===
|
||
created_at: string;
|
||
updated_at: string;
|
||
created_by: number | null;
|
||
updated_by: number | null;
|
||
deleted_at: string | null; // Soft Delete
|
||
}
|
||
```
|
||
|
||
### 2.2 QuoteItem (견적 품목) - BOM 계산 결과
|
||
|
||
```typescript
|
||
interface QuoteItem {
|
||
id: number;
|
||
quote_id: number; // 견적 ID (FK)
|
||
tenant_id: number;
|
||
|
||
// === 품목 정보 ===
|
||
item_id: number | null; // 품목마스터 ID (FK)
|
||
item_code: string; // 품목코드
|
||
item_name: string; // 품명
|
||
specification: string | null; // 규격
|
||
unit: string; // 단위
|
||
|
||
// === 수량/금액 ===
|
||
base_quantity: number; // 기본수량
|
||
calculated_quantity: number; // 계산된 수량
|
||
unit_price: number; // 단가
|
||
total_price: number; // 금액 (수량 × 단가)
|
||
|
||
// === 수식 정보 ===
|
||
formula: string | null; // 수식 (예: "W/1000 + 0.1")
|
||
formula_source: string | null; // 수식 출처 (BOM템플릿, 제품BOM 등)
|
||
formula_category: string | null; // 수식 카테고리
|
||
data_source: string | null; // 데이터 출처
|
||
|
||
// === 기타 ===
|
||
delivery_date: string | null; // 품목별 납기일
|
||
note: string | null; // 비고
|
||
sort_order: number; // 정렬순서
|
||
|
||
created_at: string;
|
||
updated_at: string;
|
||
}
|
||
```
|
||
|
||
### 2.3 QuoteRevision (견적 수정 이력)
|
||
|
||
```typescript
|
||
interface QuoteRevision {
|
||
id: number;
|
||
quote_id: number; // 견적 ID (FK)
|
||
tenant_id: number;
|
||
|
||
revision_number: number; // 수정 차수 (1, 2, 3...)
|
||
revision_date: string; // 수정일
|
||
revision_by: number; // 수정자 ID
|
||
revision_by_name: string; // 수정자 이름
|
||
revision_reason: string | null; // 수정 사유
|
||
|
||
// 이전 버전 데이터 (JSON)
|
||
previous_data: object; // 수정 전 견적 전체 데이터 (스냅샷)
|
||
|
||
created_at: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 3. API 엔드포인트
|
||
|
||
### 3.1 견적 CRUD
|
||
|
||
| Method | Endpoint | 설명 | 비고 |
|
||
|--------|----------|------|------|
|
||
| `GET` | `/api/v1/quotes` | 목록 조회 | 페이지네이션, 필터, 검색 |
|
||
| `GET` | `/api/v1/quotes/{id}` | 단건 조회 | 품목(items), 이력(revisions) 포함 |
|
||
| `POST` | `/api/v1/quotes` | 생성 | 품목 배열 포함 |
|
||
| `PUT` | `/api/v1/quotes/{id}` | 수정 | 수정이력 자동 생성 |
|
||
| `DELETE` | `/api/v1/quotes/{id}` | 삭제 | Soft Delete |
|
||
| `DELETE` | `/api/v1/quotes` | 일괄 삭제 | `ids[]` 파라미터 |
|
||
|
||
### 3.2 견적 상태 관리
|
||
|
||
| Method | Endpoint | 설명 | 비고 |
|
||
|--------|----------|------|------|
|
||
| `PATCH` | `/api/v1/quotes/{id}/finalize` | 최종확정 | status → 'finalized', is_final → true |
|
||
| `PATCH` | `/api/v1/quotes/{id}/convert-to-order` | 수주전환 | status → 'converted', 수주 데이터 생성 |
|
||
| `PATCH` | `/api/v1/quotes/{id}/cancel-finalize` | 확정취소 | is_final → false (조건부) |
|
||
|
||
### 3.3 자동 견적 산출 (핵심 기능)
|
||
|
||
| Method | Endpoint | 설명 | 비고 |
|
||
|--------|----------|------|------|
|
||
| `POST` | `/api/v1/quotes/calculate` | 자동 산출 | **수식 계산 엔진** |
|
||
| `POST` | `/api/v1/quotes/{id}/recalculate` | 재계산 | 기존 견적 재산출 |
|
||
|
||
### 3.4 견적 문서 출력
|
||
|
||
| Method | Endpoint | 설명 | 비고 |
|
||
|--------|----------|------|------|
|
||
| `GET` | `/api/v1/quotes/{id}/document/quote` | 견적서 PDF | |
|
||
| `GET` | `/api/v1/quotes/{id}/document/calculation` | 산출내역서 PDF | |
|
||
| `GET` | `/api/v1/quotes/{id}/document/purchase-order` | 발주서 PDF | |
|
||
|
||
### 3.5 문서 발송 API ⭐ 신규 요청
|
||
|
||
| Method | Endpoint | 설명 | 비고 |
|
||
|--------|----------|------|------|
|
||
| `POST` | `/api/v1/quotes/{id}/send/email` | 이메일 발송 | 첨부파일 포함 |
|
||
| `POST` | `/api/v1/quotes/{id}/send/fax` | 팩스 발송 | 팩스 서비스 연동 |
|
||
| `POST` | `/api/v1/quotes/{id}/send/kakao` | 카카오톡 발송 | 알림톡/친구톡 |
|
||
|
||
### 3.6 견적번호 생성
|
||
|
||
| Method | Endpoint | 설명 | 비고 |
|
||
|--------|----------|------|------|
|
||
| `GET` | `/api/v1/quotes/generate-number` | 견적번호 생성 | `?category=SCREEN` |
|
||
|
||
---
|
||
|
||
## 4. 상세 API 명세
|
||
|
||
### 4.1 목록 조회 `GET /api/v1/quotes`
|
||
|
||
**Query Parameters:**
|
||
```
|
||
page: number (default: 1)
|
||
size: number (default: 20)
|
||
q: string (검색어 - 견적번호, 발주처, 담당자, 현장명)
|
||
status: string (상태 필터)
|
||
product_category: string (제품 카테고리)
|
||
client_id: number (발주처 ID)
|
||
date_from: string (등록일 시작)
|
||
date_to: string (등록일 종료)
|
||
sort_by: string (정렬 컬럼)
|
||
sort_order: 'asc' | 'desc'
|
||
```
|
||
|
||
**Response:**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"current_page": 1,
|
||
"data": [
|
||
{
|
||
"id": 1,
|
||
"quote_number": "KD-SC-251204-01",
|
||
"registration_date": "2025-12-04",
|
||
"client_name": "ABC건설",
|
||
"site_name": "강남 오피스텔 현장",
|
||
"product_category": "SCREEN",
|
||
"product_name": "전동스크린 A형",
|
||
"quantity": 10,
|
||
"total_amount": 15000000,
|
||
"status": "draft",
|
||
"current_revision": 0,
|
||
"is_final": false,
|
||
"created_at": "2025-12-04T10:00:00Z"
|
||
}
|
||
],
|
||
"last_page": 5,
|
||
"per_page": 20,
|
||
"total": 100
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.2 단건 조회 `GET /api/v1/quotes/{id}`
|
||
|
||
**Response:**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"id": 1,
|
||
"quote_number": "KD-SC-251204-01",
|
||
"registration_date": "2025-12-04",
|
||
"receipt_date": "2025-12-04",
|
||
"author": "김철수",
|
||
|
||
"client_id": 10,
|
||
"client_name": "ABC건설",
|
||
"manager": "이영희",
|
||
"contact": "010-1234-5678",
|
||
|
||
"site_id": 5,
|
||
"site_name": "강남 오피스텔 현장",
|
||
"site_code": "PJ-20251204-01",
|
||
|
||
"product_category": "SCREEN",
|
||
"product_id": 100,
|
||
"product_code": "SCR-001",
|
||
"product_name": "전동스크린 A형",
|
||
|
||
"open_size_width": 2000,
|
||
"open_size_height": 3000,
|
||
"quantity": 10,
|
||
"unit_symbol": "A",
|
||
"floors": "3층",
|
||
|
||
"material_cost": 12000000,
|
||
"labor_cost": 1500000,
|
||
"install_cost": 1500000,
|
||
"subtotal": 15000000,
|
||
"discount_rate": 0,
|
||
"discount_amount": 0,
|
||
"total_amount": 15000000,
|
||
|
||
"status": "draft",
|
||
"current_revision": 2,
|
||
"is_final": false,
|
||
|
||
"completion_date": "2025-12-31",
|
||
"remarks": "급하게 진행 필요",
|
||
"memo": "",
|
||
"notes": "",
|
||
|
||
"items": [
|
||
{
|
||
"id": 1,
|
||
"item_code": "SCR-MOTOR-001",
|
||
"item_name": "스크린 모터",
|
||
"specification": "220V, 1/4HP",
|
||
"unit": "EA",
|
||
"base_quantity": 1,
|
||
"calculated_quantity": 10,
|
||
"unit_price": 150000,
|
||
"total_price": 1500000,
|
||
"formula": "Q",
|
||
"formula_source": "제품BOM",
|
||
"sort_order": 1
|
||
}
|
||
],
|
||
|
||
"revisions": [
|
||
{
|
||
"revision_number": 2,
|
||
"revision_date": "2025-12-04",
|
||
"revision_by_name": "김철수",
|
||
"revision_reason": "고객 요청으로 수량 변경"
|
||
},
|
||
{
|
||
"revision_number": 1,
|
||
"revision_date": "2025-12-03",
|
||
"revision_by_name": "김철수",
|
||
"revision_reason": "단가 조정"
|
||
}
|
||
],
|
||
|
||
"created_at": "2025-12-04T10:00:00Z",
|
||
"updated_at": "2025-12-04T15:30:00Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.3 생성 `POST /api/v1/quotes`
|
||
|
||
**Request Body:**
|
||
```json
|
||
{
|
||
"registration_date": "2025-12-04",
|
||
"receipt_date": "2025-12-04",
|
||
|
||
"client_id": 10,
|
||
"client_name": "ABC건설",
|
||
"manager": "이영희",
|
||
"contact": "010-1234-5678",
|
||
|
||
"site_id": 5,
|
||
"site_name": "강남 오피스텔 현장",
|
||
"site_code": "PJ-20251204-01",
|
||
|
||
"product_category": "SCREEN",
|
||
"product_id": 100,
|
||
|
||
"open_size_width": 2000,
|
||
"open_size_height": 3000,
|
||
"quantity": 10,
|
||
"unit_symbol": "A",
|
||
"floors": "3층",
|
||
|
||
"completion_date": "2025-12-31",
|
||
"remarks": "급하게 진행 필요",
|
||
|
||
"items": [
|
||
{
|
||
"item_id": 50,
|
||
"item_code": "SCR-MOTOR-001",
|
||
"item_name": "스크린 모터",
|
||
"unit": "EA",
|
||
"base_quantity": 1,
|
||
"calculated_quantity": 10,
|
||
"unit_price": 150000,
|
||
"total_price": 1500000,
|
||
"formula": "Q",
|
||
"sort_order": 1
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 4.4 자동 산출 `POST /api/v1/quotes/calculate` ⭐ 핵심
|
||
|
||
**Request Body:**
|
||
```json
|
||
{
|
||
"product_id": 100,
|
||
"product_category": "SCREEN",
|
||
"open_size_width": 2000,
|
||
"open_size_height": 3000,
|
||
"quantity": 10,
|
||
"floors": "3층",
|
||
"unit_symbol": "A",
|
||
|
||
"options": {
|
||
"guide_rail_install_type": "벽부형",
|
||
"motor_power": "1/4HP",
|
||
"controller": "표준형",
|
||
"edge_wing_size": 50,
|
||
"inspection_fee": 0
|
||
}
|
||
}
|
||
```
|
||
|
||
**Response:**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"product_id": 100,
|
||
"product_name": "전동스크린 A형",
|
||
"product_category": "SCREEN",
|
||
|
||
"open_size": {
|
||
"width": 2000,
|
||
"height": 3000
|
||
},
|
||
"quantity": 10,
|
||
|
||
"items": [
|
||
{
|
||
"item_id": 50,
|
||
"item_code": "SCR-MOTOR-001",
|
||
"item_name": "스크린 모터",
|
||
"specification": "220V, 1/4HP",
|
||
"unit": "EA",
|
||
"base_quantity": 1,
|
||
"calculated_quantity": 10,
|
||
"unit_price": 150000,
|
||
"total_price": 1500000,
|
||
"formula": "Q",
|
||
"formula_result": "10 × 1 = 10",
|
||
"formula_source": "제품BOM: 전동스크린 A형",
|
||
"data_source": "품목마스터 [SCR-MOTOR-001]"
|
||
},
|
||
{
|
||
"item_id": 51,
|
||
"item_code": "SCR-RAIL-001",
|
||
"item_name": "가이드레일",
|
||
"specification": "알루미늄",
|
||
"unit": "M",
|
||
"base_quantity": 1,
|
||
"calculated_quantity": 60,
|
||
"unit_price": 15000,
|
||
"total_price": 900000,
|
||
"formula": "H/1000 × 2 × Q",
|
||
"formula_result": "(3000/1000) × 2 × 10 = 60",
|
||
"formula_source": "BOM템플릿: 스크린_표준",
|
||
"data_source": "품목마스터 [SCR-RAIL-001]"
|
||
}
|
||
],
|
||
|
||
"summary": {
|
||
"material_cost": 12000000,
|
||
"labor_cost": 1500000,
|
||
"install_cost": 1500000,
|
||
"subtotal": 15000000,
|
||
"total_amount": 15000000
|
||
},
|
||
|
||
"calculation_info": {
|
||
"bom_template_used": "스크린_표준",
|
||
"formula_variables": {
|
||
"W": 2000,
|
||
"H": 3000,
|
||
"Q": 10
|
||
},
|
||
"calculated_at": "2025-12-04T10:00:00Z"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 수식 계산 엔진 (백엔드 구현 요청)
|
||
|
||
### 5.1 수식 변수
|
||
|
||
| 변수 | 설명 | 예시 |
|
||
|------|------|------|
|
||
| `W` | 오픈사이즈 폭 (mm) | 2000 |
|
||
| `H` | 오픈사이즈 높이 (mm) | 3000 |
|
||
| `Q` | 수량 | 10 |
|
||
|
||
### 5.2 수식 예시
|
||
|
||
```
|
||
수량 그대로: Q
|
||
높이 기반: H/1000
|
||
폭+높이: (W + H) / 1000
|
||
가이드레일: H/1000 × 2 × Q
|
||
스크린원단: (W/1000 + 0.1) × (H/1000 + 0.3) × Q
|
||
```
|
||
|
||
### 5.3 반올림 규칙
|
||
|
||
| 규칙 | 설명 |
|
||
|------|------|
|
||
| `ceil` | 올림 |
|
||
| `floor` | 내림 |
|
||
| `round` | 반올림 |
|
||
|
||
### 5.4 BOM 템플릿 연동
|
||
|
||
- 제품별 BOM 템플릿에서 수식 조회
|
||
- 템플릿이 없으면 품목마스터 BOM 사용
|
||
- 수식 + 단가로 자동 금액 계산
|
||
|
||
---
|
||
|
||
## 6. 상태 흐름도
|
||
|
||
```
|
||
[신규등록]
|
||
↓
|
||
[draft] 임시저장
|
||
↓ (최종확정)
|
||
[finalized] 확정
|
||
↓ (수주전환)
|
||
[converted] 수주전환
|
||
```
|
||
|
||
### 6.1 상태별 제약
|
||
|
||
| 상태 | 수정 가능 | 삭제 가능 | 비고 |
|
||
|------|----------|----------|------|
|
||
| `draft` | O | O | 자유롭게 수정 |
|
||
| `sent` | O | O | 발송 후 수정 가능 (이력 기록) |
|
||
| `finalized` | X | X | 확정 후 수정 불가 |
|
||
| `converted` | X | X | 수주전환 후 불변 |
|
||
|
||
---
|
||
|
||
## 7. 프론트엔드 구현 현황 (2025-12-04 업데이트)
|
||
|
||
### 7.1 구현 완료된 파일
|
||
|
||
| 파일 | 설명 | 상태 |
|
||
|------|------|------|
|
||
| `quote-management/page.tsx` | 견적 목록 페이지 | ✅ 완료 (샘플 데이터) |
|
||
| `quote-management/new/page.tsx` | 견적 등록 페이지 | ✅ 완료 |
|
||
| `quote-management/[id]/page.tsx` | 견적 상세 페이지 | ✅ 완료 |
|
||
| `quote-management/[id]/edit/page.tsx` | 견적 수정 페이지 | ✅ 완료 |
|
||
| `components/quotes/QuoteRegistration.tsx` | 견적 등록/수정 컴포넌트 | ✅ 완료 |
|
||
| `components/quotes/QuoteDocument.tsx` | 견적서 문서 컴포넌트 | ✅ 완료 |
|
||
| `components/quotes/QuoteCalculationReport.tsx` | 산출내역서 문서 컴포넌트 | ✅ 완료 |
|
||
| `components/quotes/PurchaseOrderDocument.tsx` | 발주서 문서 컴포넌트 | ✅ 완료 |
|
||
|
||
### 7.2 UI 기능 구현 현황
|
||
|
||
| 기능 | 상태 | 비고 |
|
||
|------|------|------|
|
||
| 견적 목록 조회 | ✅ UI 완료 | 샘플 데이터, API 연동 필요 |
|
||
| 견적 검색/필터 | ✅ UI 완료 | 로컬 필터링, API 연동 필요 |
|
||
| 견적 등록 폼 | ✅ UI 완료 | API 연동 필요 |
|
||
| 견적 상세 페이지 | ✅ UI 완료 | API 연동 필요 |
|
||
| 견적 수정 폼 | ✅ UI 완료 | API 연동 필요 |
|
||
| 견적 삭제 | ✅ UI 완료 | 로컬 상태, API 연동 필요 |
|
||
| 견적 일괄 삭제 | ✅ UI 완료 | 로컬 상태, API 연동 필요 |
|
||
| 자동 견적 산출 | ⏳ 버튼만 | 백엔드 수식 엔진 필요 |
|
||
| 발주처 선택 | ⏳ 샘플 데이터 | `/api/v1/clients` 연동 필요 |
|
||
| 현장 선택 | ⏳ 샘플 데이터 | 발주처 연동 후 현장 API 필요 |
|
||
| 제품 선택 | ⏳ 샘플 데이터 | `/api/v1/item-masters` 연동 필요 |
|
||
| **견적서 모달** | ✅ UI 완료 | PDF/이메일/팩스/카톡 버튼, **발송 API 필요** |
|
||
| **산출내역서 모달** | ✅ UI 완료 | PDF/이메일/팩스/카톡 버튼, **발송 API 필요** |
|
||
| **발주서 모달** | ✅ UI 완료 | PDF/이메일/팩스/카톡 버튼, **발송 API 필요** |
|
||
| 최종확정 버튼 | ✅ UI 완료 | API 연동 필요 |
|
||
|
||
### 7.3 견적 등록/수정 폼 필드 (구현 완료)
|
||
|
||
**기본 정보 섹션:**
|
||
- 등록일 (readonly, 오늘 날짜)
|
||
- 작성자 (readonly, 로그인 사용자)
|
||
- 발주처 선택 * (필수)
|
||
- 현장명 (발주처 선택 시 연동)
|
||
- 발주 담당자
|
||
- 연락처
|
||
- 납기일
|
||
- 비고
|
||
|
||
**자동 견적 산출 섹션 (동적 항목):**
|
||
- 층수
|
||
- 부호
|
||
- 제품 카테고리 (PC) *
|
||
- 제품명 *
|
||
- 오픈사이즈 (W0) *
|
||
- 오픈사이즈 (H0) *
|
||
- 가이드레일 설치 유형 (GT) *
|
||
- 모터 전원 (MP) *
|
||
- 연동제어기 (CT) *
|
||
- 수량 (QTY) *
|
||
- 마구리 날개치수 (WS)
|
||
- 검사비 (INSP)
|
||
|
||
**기능:**
|
||
- 견적 항목 추가/복사/삭제
|
||
- 자동 견적 산출 버튼
|
||
- 샘플 데이터 생성 버튼
|
||
|
||
### 7.4 다음 단계 (API 연동)
|
||
|
||
```typescript
|
||
// useQuoteList 훅 (목록)
|
||
const {
|
||
quotes,
|
||
pagination,
|
||
isLoading,
|
||
fetchQuotes,
|
||
deleteQuote,
|
||
bulkDelete
|
||
} = useQuoteList();
|
||
|
||
// useQuote 훅 (단건 CRUD)
|
||
const {
|
||
quote,
|
||
isLoading,
|
||
fetchQuote,
|
||
createQuote,
|
||
updateQuote,
|
||
finalizeQuote,
|
||
convertToOrder
|
||
} = useQuote();
|
||
|
||
// useQuoteCalculation 훅 (자동 산출)
|
||
const {
|
||
calculationResult,
|
||
isCalculating,
|
||
calculate,
|
||
recalculate
|
||
} = useQuoteCalculation();
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 관련 참조
|
||
|
||
### 8.1 거래처 API 연동
|
||
- 발주처 선택 시 `/api/v1/clients` 연동
|
||
- 직접입력 시 자동 등록 가능
|
||
|
||
### 8.2 현장 API (추후)
|
||
- 현장 선택 시 `/api/v1/sites` 연동 (별도 API 필요시)
|
||
|
||
### 8.3 품목마스터 연동
|
||
- 제품 선택 시 `/api/v1/item-masters` 연동
|
||
- BOM 조회 시 품목마스터 BOM 활용
|
||
|
||
---
|
||
|
||
## 9. 요청 우선순위
|
||
|
||
| 순위 | API | 설명 |
|
||
|------|-----|------|
|
||
| P1 | 견적 CRUD | 기본 목록/등록/수정/삭제 |
|
||
| P1 | 자동 산출 | 수식 계산 엔진 (핵심) |
|
||
| P1 | 견적번호 생성 | 자동 채번 |
|
||
| P2 | 상태 관리 | 확정/수주전환 |
|
||
| P2 | 수정 이력 | 버전 관리 |
|
||
| P3 | 문서 출력 | PDF 생성 |
|
||
|
||
---
|
||
|
||
## 10. 질문사항
|
||
|
||
1. **현장(Site) 테이블**: 별도 테이블로 관리할지? (거래처 하위 개념)
|
||
2. **수식 계산**: BOM 템플릿 테이블 구조는?
|
||
3. **문서 출력**: PDF 라이브러리 선정 (TCPDF, Dompdf 등)
|
||
4. **알림**: 견적 발송 시 이메일/카카오톡 연동 계획?
|