245 lines
8.3 KiB
Markdown
245 lines
8.3 KiB
Markdown
|
|
# 견적/수주 UI 분석
|
||
|
|
|
||
|
|
> 분석 일시: 2024-12-18
|
||
|
|
> 소스:
|
||
|
|
> - design/mes기획서_리액트/src/components/QuoteDetailNew.jsx
|
||
|
|
> - design/mes기획서_리액트/src/components/QuoteDocumentDialogs.jsx
|
||
|
|
|
||
|
|
## QuoteDetailNew.jsx - 견적 상세
|
||
|
|
|
||
|
|
### Props
|
||
|
|
| Prop | 타입 | 설명 |
|
||
|
|
|------|------|------|
|
||
|
|
| quote | Object | 견적 데이터 |
|
||
|
|
| orders | Array | 수주 목록 (관련 수주 찾기용) |
|
||
|
|
| onNavigate | Function | 화면 이동 |
|
||
|
|
| onBack | Function | 목록으로 돌아가기 |
|
||
|
|
| onConvertToOrder | Function | 수주 전환 콜백 |
|
||
|
|
| onUpdateQuote | Function | 견적 업데이트 콜백 |
|
||
|
|
| onCreateOrder | Function | 수주 생성 콜백 |
|
||
|
|
|
||
|
|
### 견적 상태 (StatusBadge)
|
||
|
|
| 상태 | 스타일 | 설명 |
|
||
|
|
|------|--------|------|
|
||
|
|
| 최초작성 | gray | 초기 상태 |
|
||
|
|
| 최종확정 | blue | 견적 확정 |
|
||
|
|
| 수주전환 | green | 수주로 전환됨 |
|
||
|
|
| 수정중 | yellow | 수정 진행 중 |
|
||
|
|
|
||
|
|
### 화면 구성
|
||
|
|
|
||
|
|
```
|
||
|
|
┌─────────────────────────────────────────────────────────────┐
|
||
|
|
│ [헤더] │
|
||
|
|
│ 좌: 견적 상세 + [견적서] [산출내역서] [발주서] 버튼 │
|
||
|
|
│ 우: [목록] [수정] [최종확정] [수주전환] 버튼 │
|
||
|
|
├─────────────────────────────────────────────────────────────┤
|
||
|
|
│ [기본 정보] Card │
|
||
|
|
│ - 견적번호, 작성자, 발주처, 담당자, 연락처 │
|
||
|
|
│ - 현장명, 현장코드, 상태, 접수일, 납기일, 비고 │
|
||
|
|
├─────────────────────────────────────────────────────────────┤
|
||
|
|
│ [자동 견적 산출 정보] Card │
|
||
|
|
│ - 품목, 수량, 단가, 공급가액, 부가세, 총 견적금액 │
|
||
|
|
├─────────────────────────────────────────────────────────────┤
|
||
|
|
│ [특이사항] Card │
|
||
|
|
│ - 특이사항 텍스트 │
|
||
|
|
└─────────────────────────────────────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
### 수주전환 모달 (convertForm)
|
||
|
|
|
||
|
|
| 필드 | 타입 | 필수 | 설명 |
|
||
|
|
|------|------|------|------|
|
||
|
|
| shipDate | date | - | 출하예정일 |
|
||
|
|
| shipDateUndecided | boolean | - | 출하일 미정 여부 |
|
||
|
|
| dueDate | date | - | 납기일 |
|
||
|
|
| dueDateUndecided | boolean | - | 납기일 미정 여부 |
|
||
|
|
| deliveryMethod | select | - | 배송방법 (상차/택배/직접배송) |
|
||
|
|
| freightCost | select | - | 운임비 (선불/착불/무료) |
|
||
|
|
| receiverName | text | - | 수령자명 |
|
||
|
|
| receiverPhone | text | - | 수령자연락처 |
|
||
|
|
| deliveryAddress | text | - | 납품주소 |
|
||
|
|
| deliveryAddressDetail | text | - | 상세주소 |
|
||
|
|
| note | textarea | - | 비고 |
|
||
|
|
|
||
|
|
### 수주전환 비즈니스 로직
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// 수주번호 생성 규칙
|
||
|
|
const dateCode = new Date().toISOString().slice(2,10).replace(/-/g, '');
|
||
|
|
const newOrderNo = `KD-SO-${dateCode}-${순번2자리}`;
|
||
|
|
// 예: KD-SO-241218-01
|
||
|
|
|
||
|
|
// 생성되는 수주 데이터
|
||
|
|
const newOrder = {
|
||
|
|
id: Date.now(),
|
||
|
|
orderNo: newOrderNo, // 자동생성 수주번호
|
||
|
|
quoteNo: quote.quoteNo, // 원본 견적번호
|
||
|
|
quoteId: quote.id, // 원본 견적 ID
|
||
|
|
orderDate: '오늘 날짜',
|
||
|
|
customerName: quote.customerName,
|
||
|
|
siteName: quote.siteName,
|
||
|
|
siteAddress: quote.deliveryAddress,
|
||
|
|
manager: quote.manager,
|
||
|
|
contact: quote.contact,
|
||
|
|
productName: quote.productName,
|
||
|
|
qty: quote.qty,
|
||
|
|
totalAmount: quote.finalAmount || quote.totalAmount,
|
||
|
|
status: '수주확정', // 초기 상태
|
||
|
|
dueDate: convertForm.dueDate,
|
||
|
|
shipDate: convertForm.shipDate,
|
||
|
|
deliveryMethod: convertForm.deliveryMethod,
|
||
|
|
freightCost: convertForm.freightCost,
|
||
|
|
receiverName: convertForm.receiverName,
|
||
|
|
receiverPhone: convertForm.receiverPhone,
|
||
|
|
deliveryAddress: convertForm.deliveryAddress,
|
||
|
|
deliveryAddressDetail: convertForm.deliveryAddressDetail,
|
||
|
|
note: convertForm.note,
|
||
|
|
creditGrade: quote.creditGrade,
|
||
|
|
items: quote.items || [],
|
||
|
|
history: [{
|
||
|
|
id: Date.now(),
|
||
|
|
changedAt: '현재시간',
|
||
|
|
changeType: '수주등록',
|
||
|
|
description: `견적(${quote.quoteNo})에서 수주전환`,
|
||
|
|
changedBy: '현재 사용자',
|
||
|
|
}],
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## QuoteDocumentDialogs.jsx - 문서 출력
|
||
|
|
|
||
|
|
### 1. QuoteSheetDialog (견적서)
|
||
|
|
|
||
|
|
**구성:**
|
||
|
|
- 수신자 정보: 상호, 담당자, 연락처, 현장명
|
||
|
|
- 발신자 정보: 상호, 대표자, 사업자번호, 연락처
|
||
|
|
- 견적 요약: 견적번호, 견적일, 유효기간(30일), 견적금액
|
||
|
|
- 품목 테이블: No, 품목명, 규격, 수량, 단가, 금액
|
||
|
|
- 합계: 공급가액, 부가세(10%), 총 견적금액
|
||
|
|
- 비고
|
||
|
|
|
||
|
|
**액션 버튼:**
|
||
|
|
- 인쇄 (Printer)
|
||
|
|
- 다운로드 (Download)
|
||
|
|
- 이메일 (Mail)
|
||
|
|
|
||
|
|
### 2. CalculationSheetDialog (산출내역서)
|
||
|
|
|
||
|
|
**구성:**
|
||
|
|
- 견적번호, 현장명, 작성일
|
||
|
|
- 산출 테이블: No, 품목, 층/부호, 가로, 세로, 면적(m²), 수량, 단가, 금액
|
||
|
|
- 합계
|
||
|
|
- 산출 기준 안내
|
||
|
|
|
||
|
|
**면적 계산:**
|
||
|
|
```javascript
|
||
|
|
const area = ((item.width || 0) * (item.height || 0) / 1000000).toFixed(2);
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. PurchaseOrderDialog (발주서)
|
||
|
|
|
||
|
|
**구성:**
|
||
|
|
- 발주처 정보 (귀하): 상호, 담당자, 연락처, 현장
|
||
|
|
- 수주처 정보: 상호, 대표자, 사업자번호, 연락처
|
||
|
|
- 발주 요약: 발주번호, 발주일, 납기일, 발주금액
|
||
|
|
- 품목 테이블: No, 품목명, 규격, 수량, 단가, 금액
|
||
|
|
- 발주 합계
|
||
|
|
- 특기사항
|
||
|
|
- 서명란: 발주자(인), 수주자(인)
|
||
|
|
|
||
|
|
**발주번호 생성:**
|
||
|
|
```javascript
|
||
|
|
// 견적번호에서 변환
|
||
|
|
const purchaseOrderNo = `PO-${quote.quoteNo?.replace('QT', '')}`;
|
||
|
|
// 예: QT-2024-001 → PO-2024-001
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Quote 데이터 구조
|
||
|
|
|
||
|
|
### quote 객체
|
||
|
|
|
||
|
|
| 필드 | 타입 | 설명 |
|
||
|
|
|------|------|------|
|
||
|
|
| id | number | 견적 ID |
|
||
|
|
| quoteNo | string | 견적번호 (QT-YYMMDD-##) |
|
||
|
|
| quoteDate | string | 견적일 |
|
||
|
|
| customerName | string | 발주처명 |
|
||
|
|
| manager | string | 담당자 |
|
||
|
|
| contact | string | 연락처 |
|
||
|
|
| siteName | string | 현장명 |
|
||
|
|
| siteCode | string | 현장코드 |
|
||
|
|
| deliveryAddress | string | 납품주소 |
|
||
|
|
| productName | string | 대표 품목명 |
|
||
|
|
| qty | number | 수량 |
|
||
|
|
| unitPrice | number | 단가 |
|
||
|
|
| totalAmount | number | 총금액 (공급가액) |
|
||
|
|
| finalAmount | number | 최종금액 |
|
||
|
|
| status | string | 상태 |
|
||
|
|
| dueDate | string | 납기일 |
|
||
|
|
| createdBy | string | 작성자 |
|
||
|
|
| note | string | 비고 |
|
||
|
|
| specialNote | string | 특이사항 |
|
||
|
|
| creditGrade | string | 신용등급 |
|
||
|
|
| items | Array | 품목 목록 |
|
||
|
|
|
||
|
|
### items[] 객체
|
||
|
|
|
||
|
|
| 필드 | 타입 | 설명 |
|
||
|
|
|------|------|------|
|
||
|
|
| id | number | 품목 ID |
|
||
|
|
| productName | string | 품목명 |
|
||
|
|
| category | string | 카테고리 |
|
||
|
|
| floor | string | 층 |
|
||
|
|
| location | string | 위치 |
|
||
|
|
| width | number | 가로(mm) |
|
||
|
|
| height | number | 세로(mm) |
|
||
|
|
| qty | number | 수량 |
|
||
|
|
| unitPrice | number | 단가 |
|
||
|
|
| amount | number | 금액 |
|
||
|
|
| orderStatus | string | 수주 상태 (pending/ordered) |
|
||
|
|
| orderId | number | 연결된 수주 ID |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## API 추정
|
||
|
|
|
||
|
|
### 견적 → 수주 전환 API
|
||
|
|
```
|
||
|
|
POST /api/orders/from-quote/{quoteId}
|
||
|
|
Body: {
|
||
|
|
shipDate: string | null,
|
||
|
|
dueDate: string | null,
|
||
|
|
deliveryMethod: string,
|
||
|
|
freightCost: string,
|
||
|
|
receiverName: string,
|
||
|
|
receiverPhone: string,
|
||
|
|
deliveryAddress: string,
|
||
|
|
deliveryAddressDetail: string,
|
||
|
|
note: string
|
||
|
|
}
|
||
|
|
|
||
|
|
Response: {
|
||
|
|
order: { ... }, // 생성된 수주
|
||
|
|
quote: { ... } // 업데이트된 견적 (status: '수주전환')
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 문서 출력 API
|
||
|
|
```
|
||
|
|
GET /api/quotes/{id}/documents/quote-sheet - 견적서 PDF
|
||
|
|
GET /api/quotes/{id}/documents/calculation - 산출내역서 PDF
|
||
|
|
GET /api/quotes/{id}/documents/purchase-order - 발주서 PDF
|
||
|
|
POST /api/quotes/{id}/documents/email - 이메일 발송
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 다음 분석 단계
|
||
|
|
|
||
|
|
1. App.jsx 수주 섹션 추출 - 수주 목록/등록/상세 UI
|
||
|
|
2. 비즈니스 로직 통합 분석
|