docs: 수주관리 기획 분석 문서 및 UI 스크린샷 추가

- 메뉴 구조, 데이터 스키마, UI 분석, API 스펙 문서화
- 수주 목록/상세/등록/수정 화면 캡처 (11개)
- 생산지시 생성 화면 포함 (우선순위, 자재소요량, BOM)
This commit is contained in:
2025-12-18 15:37:18 +09:00
parent f32ec6a552
commit cf82d98258
18 changed files with 1622 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
# 수주 관련 메뉴 구조 분석
> 분석 일시: 2024-12-18
> 소스: design/mes기획서_리액트/src/configs/menuDefinitions.js
## 메뉴 그룹 구조
### 1. 판매관리 (salesMenus)
| 메뉴 ID | 라벨 | 아이콘 | 수주 관련도 |
|---------|------|--------|------------|
| customer | 거래처관리 | Users | 연관 (거래처 정보) |
| quote | 견적관리 | FileText | **핵심** (견적→수주 전환) |
| order | 수주관리 | Package | **핵심** |
| site | 현장관리 | Building | 연관 (납품 현장) |
| price | 단가관리 | DollarSign | 연관 (단가 적용) |
### 2. 기준정보 (masterMenus)
| 메뉴 ID | 라벨 | 아이콘 | 수주 관련도 |
|---------|------|--------|------------|
| order-master | 수주기준관리 | Package | **핵심** (수주 설정) |
| quote-formula | 견적수식관리 | Calculator | 연관 (견적 계산) |
| document-template | 문서양식관리 | FileText | 연관 (수주 문서) |
| number-rule | 채번관리 | ClipboardList | 연관 (수주번호 규칙) |
### 3. 회계관리 (accountingMenus)
| 메뉴 ID | 라벨 | screenId | 수주 관련도 |
|---------|------|----------|------------|
| sales-account | 매출관리 | A1 | 연관 (수주→매출) |
| sales-list | 매출 목록 | A1 | 출하 완료된 매출 건 조회 |
| sales-statement | 거래명세서 | A1-1 | 출하 건 거래명세서 발행 |
| sales-tax-invoice | 세금계산서 | A1-2 | 전자세금계산서 발행 |
| cost-analysis | 원가관리 | A5 | 수주별 원가 집계 |
| cost-detail | 원가 상세 | A5-1 | 수주별 원가 상세 분석 |
## 수주 핵심 화면 목록
### 필수 분석 대상
1. **견적관리** (`quote`) - 견적 목록/등록/상세
2. **수주관리** (`order`) - 수주 목록/등록/상세
3. **수주기준관리** (`order-master`) - 수주 설정
### 연관 화면
- 거래처관리 (`customer`)
- 현장관리 (`site`)
- 단가관리 (`price`)
- 채번관리 (`number-rule`)
## 비즈니스 흐름
```
견적(quote) → 수주전환 → 수주(order) → 생산지시 → 출하 → 매출(sales-account)
```
## 다음 분석 단계
1. orderMasterConfig.js - 수주 데이터 스키마
2. QuoteDetailNew.jsx - 견적 UI 구조
3. App.jsx 내 수주 섹션 - 비즈니스 로직

View File

@@ -0,0 +1,154 @@
# 수주 데이터 스키마 분석
> 분석 일시: 2024-12-18
> 소스: design/mes기획서_리액트/src/configs/orderMasterConfig.js
## 수주 유형 (entityTypes)
| ID | 코드 | 이름 | 설명 |
|----|------|------|------|
| 1 | NORMAL | 일반수주 | 견적 기반 일반 수주 |
| 2 | ADDITIONAL | 추가수주 | 기존 수주 추가분 |
| 3 | DIRECT | 직접수주 | 견적 없이 직접 입력 |
## 제품 카테고리 (생산공정 분류)
| ID | 코드 | 이름 |
|----|------|------|
| 1 | SCREEN | 스크린 |
| 2 | FOLD | 절곡 |
| 3 | SLAT | 슬랫 |
| 4 | ASSY | 조립 |
## 섹션 구조 (masterSections)
| ID | 키 | 이름 | 타입 | 설명 |
|----|-----|------|------|------|
| 1 | basicInfo | 기본정보 | general | 수주 기본 정보 |
| 2 | deliveryInfo | 납품정보 | general | 납품 관련 정보 |
| 3 | itemInfo | 품목정보 | **multiRow** | 수주 품목 목록 |
| 4 | productionSpec | 제작사양 | **multiRow** | 제작 상세 사양 |
| 5 | amountInfo | 금액정보 | general | 금액 합계 |
| 6 | etcInfo | 기타정보 | general | 기타 정보 |
---
## 필드 상세 (masterFields)
### 기본정보 (basicInfo)
| ID | 필드키 | 필드명 | 입력타입 | 필수 | 자동생성 | 설명 |
|----|--------|--------|----------|------|----------|------|
| 1 | orderNo | 수주번호 | text | ✅ | ✅ | 수주 식별 번호 |
| 2 | orderDate | 수주일 | date | ✅ | - | 수주 등록일 |
| 3 | quoteNo | 견적번호 | text | - | - | 연결된 견적번호 |
| 4 | customerName | 거래처명 | text | ✅ | - | 거래처명 |
| 5 | customerId | 거래처ID | text | - | - | 거래처 식별자 |
| 6 | siteName | 현장명 | text | ✅ | - | 설치 현장명 |
| 7 | manager | 담당자 | text | - | - | 거래처 담당자 |
| 8 | contact | 연락처 | text | - | - | 담당자 연락처 |
### 납품정보 (deliveryInfo)
| ID | 필드키 | 필드명 | 입력타입 | 필수 | 옵션 |
|----|--------|--------|----------|------|------|
| 10 | dueDate | 납기일 | date | ✅ | - |
| 11 | deliveryMethod | 배송방법 | select | - | 직접배차, 상차, 택배, 화물, 직접배송 |
| 12 | deliveryAddress | 납품주소 | text | - | - |
| 13 | receiverName | 수령자명 | text | - | - |
| 14 | receiverPhone | 수령자연락처 | text | - | - |
### 품목정보 (itemInfo) - 다중행
| ID | 필드키 | 필드명 | 입력타입 | 필수 | 옵션/검증 |
|----|--------|--------|----------|------|----------|
| 20 | productCode | 품목코드 | text | - | - |
| 21 | productName | 품목명 | select | ✅ | 국민방화스크린셔터, 방화셔터, 방연셔터 |
| 22 | category | 카테고리 | select | - | 스크린, 절곡, 슬랫, 조립 |
| 23 | floor | 층 | text | - | - |
| 24 | location | 위치 | text | - | - |
| 25 | openWidth | 개구폭(mm) | number | ✅ | min:500, max:15000 |
| 26 | openHeight | 개구높이(mm) | number | ✅ | min:500, max:10000 |
| 27 | qty | 수량 | number | ✅ | min:1 |
| 28 | unitPrice | 단가 | number | - | - |
| 29 | amount | 금액 | number | - | **자동계산** |
### 제작사양 (productionSpec) - 다중행
| ID | 필드키 | 필드명 | 입력타입 | 자동계산 | 옵션 |
|----|--------|--------|----------|----------|------|
| 30 | prodWidth | 제작폭(mm) | number | ✅ | 개구폭+140 |
| 31 | prodHeight | 제작높이(mm) | number | ✅ | MAX(개구높이+400, 2950) |
| 32 | guideRailType | 가이드레일형태 | select | - | 백면형, 양면형, 편면형 |
| 33 | guideRailSpec | 가이드레일규격 | select | - | 120-70, 150-80, 180-90 |
| 34 | finish | 마감 | select | - | SUS마감, 분체도장, 용융아연 |
| 35 | shaft | 샤프트 | number | ✅ | 폭>6000:5인치, 그외:4인치 |
| 36 | capacity | 전동용량 | number | ✅ | 폭>6000:300kg, 그외:160kg |
### 금액정보 (amountInfo)
| ID | 필드키 | 필드명 | 입력타입 | 자동계산 |
|----|--------|--------|----------|----------|
| 40 | totalAmount | 총금액 | number | ✅ (품목 금액 합계) |
### 기타정보 (etcInfo)
| ID | 필드키 | 필드명 | 입력타입 |
|----|--------|--------|----------|
| 50 | note | 비고 | textarea |
---
## 자동계산 규칙 (calculations)
| 필드 | 수식 | 설명 |
|------|------|------|
| prodWidth | `openWidth + 140` | 제작폭 = 개구폭 + 140 |
| prodHeight | `MAX(openHeight + 400, 2950)` | 제작높이 = MAX(개구높이+400, 2950) |
| shaft | `openWidth > 6000 ? 5 : 4` | 샤프트 인치 |
| capacity | `openWidth > 6000 ? 300 : 160` | 전동용량 kg |
| amount | `qty * unitPrice` | 금액 = 수량 × 단가 |
| totalAmount | `SUM(items.amount)` | 총금액 = 품목 금액 합계 |
---
## 페이지 템플릿
### 일반 수주 (order_normal)
- 경로: `/판매관리/수주_등록`
- 유형: NORMAL
- 섹션: 기본정보 → 납품정보 → 품목정보 → 제작사양 → 금액정보 → 기타정보
### 추가 수주 (order_additional)
- 경로: `/판매관리/수주_추가`
- 유형: ADDITIONAL
- 섹션: 기본정보(간소화) → 추가 품목 → 기타정보
---
## API 엔드포인트 추정
### 수주 CRUD
```
GET /api/orders - 수주 목록
GET /api/orders/{id} - 수주 상세
POST /api/orders - 수주 등록
PUT /api/orders/{id} - 수주 수정
DELETE /api/orders/{id} - 수주 삭제
```
### 관련 API
```
GET /api/orders/{id}/items - 수주 품목 목록
POST /api/orders/{id}/items - 품목 추가
PUT /api/orders/{id}/items/{itemId} - 품목 수정
DELETE /api/orders/{id}/items/{itemId} - 품목 삭제
POST /api/orders/from-quote/{quoteId} - 견적에서 수주 전환
```
---
## 다음 분석 단계
1. QuoteDetailNew.jsx, QuoteDocumentDialogs.jsx - UI 구조 및 액션
2. App.jsx 수주 섹션 - 비즈니스 로직, 상태 관리

View File

@@ -0,0 +1,245 @@
# 견적/수주 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. 비즈니스 로직 통합 분석

View File

@@ -0,0 +1,313 @@
# App.jsx 수주 섹션 분석
> 분석 일시: 2024-12-18
> 소스: design/mes기획서_리액트/src/App.jsx (52768~56357줄)
## 컴포넌트 위치
| 컴포넌트 | 라인 | 설명 |
|----------|------|------|
| OrderList | 52768 | 수주 목록 |
| OrderDetail | 53479 | 수주 상세 |
| OrderCreate | 55280 | 수주 등록 |
| OrderEdit | 56357 | 수주 수정 |
---
## 1. OrderList (수주 목록)
### Props
```javascript
{
orders, // 수주 배열
shipments, // 출하 배열 (연결용)
workOrders, // 작업지시 배열 (연결용)
onNavigate, // 화면 이동
onCreateWorkOrders, // 작업지시 생성
onDeleteOrders // 수주 삭제
}
```
### 탭 필터
| 탭 ID | 라벨 | 필터 조건 |
|-------|------|-----------|
| all | 전체 | - |
| registered | 수주등록 | status === '수주등록' |
| confirmed | 수주확정 | status === '수주확정' |
| production-complete | 생산지시완료 | status === '생산지시완료' |
### 리포트 카드 (4개)
| 항목 | 계산 |
|------|------|
| 이번 달 수주 | `orders.reduce(sum + totalAmount)` |
| 분할 대기 | 수주확정 && splits 없음 |
| 생산지시 대기 | splits 있으나 productionStatus 미지시 |
| 출하 대기 | 출하진행률 0% |
### 테이블 컬럼
```
체크박스 | 번호 | 로트번호 | 견적번호 | 발주처 | 현장명 | 상태 | 출고예정일 | 배송방식 | (작업)
```
### 검색 필드
- 로트번호 (orderNo)
- 견적번호 (quoteNo)
- 발주처 (customerName)
- 현장명 (siteName)
### 정렬
```javascript
.sort((a, b) => b.id - a.id) // ID 기준 내림차순 (최신 등록 최상단)
```
---
## 2. OrderDetail (수주 상세)
### Props
```javascript
{
order, // 수주 데이터
productionOrders, // 생산지시 배열
customers, // 거래처 배열 (결제조건 확인)
onNavigate,
onBack,
onUpdate, // 수주 업데이트
onCreateWorkOrder, // 작업지시 생성
onCreateProductionOrder
}
```
### 문서 탭
| 탭 ID | 라벨 | 용도 |
|-------|------|------|
| contract | 계약서 | 수주 계약 문서 |
| statement | 거래명세서 | 납품 시 발행 |
| purchaseOrder | 발주서 | 발주처 제출용 |
### 분할(Split) 관리
**분할 데이터 구조:**
```javascript
{
id: number,
splitNo: string, // "{orderNo}-{순번2자리}"
splitOrder: number,
splitType: string, // '개소별'
dueDate: string,
itemIds: number[], // 분할 품목 ID 배열
productionStatus: string, // '작업대기', '작업지시'
shipmentStatus: string, // '출고대기', ...
productionOrderNo: string,
totalQty: number,
completedQty: number,
remainingQty: number
}
```
### 생산지시 생성 로직
**공정별 작업지시 자동 분리:**
1. **스크린 공정**: 스크린 카테고리 품목
2. **슬랫 공정**: 슬랫/철재 카테고리 품목
3. **절곡 공정**: BOM 데이터 기반 절곡물
**작업지시 번호 생성:**
```javascript
const woNo = `KD-PL-${dateCode}-${순번2자리}`;
// 예: KD-PL-241218-01
```
**공정별 작업 단계:**
```javascript
{
'스크린': ['원단절단', '미싱', '앤드락작업', '중간검사', '포장'],
'슬랫': ['코일절단', '중간검사', '미미작업', '포장'],
'절곡': ['절단', '절곡', '중간검사', '포장'],
}
```
**팀 자동 배정:**
```javascript
{
'스크린': { assignee: '스크린팀', assignees: ['김스크린', '이스크린', '박스크린'] },
'슬랫': { assignee: '슬랫팀', assignees: ['김슬랫', '이슬랫', '박슬랫'] },
'절곡': { assignee: '절곡팀', assignees: ['김절곡', '이절곡'] },
}
```
---
## 3. OrderCreate (수주 등록)
### Props
```javascript
{
quotes, // 견적 배열 (선택용)
fromQuote, // 전환된 견적
additionalItems, // 추가분 품목
relatedOrders, // 관련 수주 (추가분용)
isAdditional, // 추가분 여부
onNavigate,
onBack,
onSave
}
```
### 수주 유형
| 유형 | orderType | 설명 |
|------|-----------|------|
| 견적전환 | from-quote | 견적에서 수주 전환 |
| 직접입력 | direct | 견적 없이 직접 등록 |
| 추가분 | additional | 기존 수주에 추가 |
### 수주번호 생성 규칙
```javascript
// 신규: KD-SO-YYMMDD-순번
const orderNo = `KD-SO-${dateCode}-${seq}`;
// 예: KD-SO-241218-01
// 추가분: 원수주번호-A, B, C...
const additionalOrderNo = `${baseOrderNo}-${suffix}`;
// 예: KD-SO-241218-01-A
```
### 폼 필드
**기본 정보:**
| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| orderDate | date | - | 수주일 (기본: 오늘) |
| customerName | text | ✅ | 발주처 |
| customerId | text | - | 거래처 ID |
| siteName | text | ✅ | 현장명 |
| manager | text | - | 담당자 |
| contact | text | - | 연락처 |
**납품 정보:**
| 필드 | 타입 | 필수 | 옵션 |
|------|------|------|------|
| dueDate | date | ✅ | 납기일 |
| deliveryMethod | select | - | 배송방법 (12종) |
| deliveryAddress | text | - | 납품주소 |
| receiverName | text | - | 수령자명 |
| receiverPhone | text | - | 수령자연락처 |
**배송방법 옵션 (12종):**
```
상차(선불), 상차(착불), 직접배차, 직접수령,
경동화물(선불/착불), 경동택배(선불/착불),
대신화물(선불/착불), 대신택배(선불/착불)
```
### 품목 추가/수정 폼
**품목 필드:**
| 필드 | 타입 | 설명 |
|------|------|------|
| productCode | text | 품목코드 |
| productName | select | 품목명 |
| floor | text | 층 |
| location | text | 위치 |
| openWidth | number | 개구폭(mm) |
| openHeight | number | 개구높이(mm) |
| qty | number | 수량 |
| unitPrice | number | 단가 |
| guideRailType | select | 가이드레일형태 |
| guideRailSpec | select | 가이드레일규격 |
| finish | select | 마감 |
### 제작 스펙 자동 계산
```javascript
const prodWidth = openWidth + 140;
const prodHeight = Math.max(openHeight + 400, 2950);
const shaft = openWidth > 6000 ? 5 : 4;
const capacity = openWidth > 6000 ? 300 : 160;
```
### 저장 시 생성되는 데이터
```javascript
const newOrder = {
id,
orderNo,
orderDate,
quoteId, quoteNo,
orderType, // 'from-quote' | 'direct' | 'additional'
parentOrderNo, // 추가분일 경우
customerId, customerName,
creditGrade, // 거래처 신용등급
siteName, siteCode,
manager, contact,
dueDate,
status: '수주등록',
paymentStatus: '미입금',
accountingStatus: '미확인',
deliveryMethod,
totalAmount,
deliveryAddress,
receiverName, receiverPhone,
items, // 품목 배열
motorSpec, // 모터/전장품 스펙
bomData, // 절곡물 BOM
calculatedItems, // 견적 산출 품목
splits: [],
documentHistory: [],
changeHistory: [],
createdAt, createdBy,
note
};
```
---
## 4. 수주 상태 흐름
```
수주등록 → 수주확정 → 생산중 → 생산완료 → 출하완료
분할 관리
생산지시 (공정별)
작업지시 생성
```
---
## 5. 관련 API 추정
### 수주 CRUD
```
GET /api/orders - 수주 목록
GET /api/orders/{id} - 수주 상세
POST /api/orders - 수주 등록
PUT /api/orders/{id} - 수주 수정
DELETE /api/orders/{id} - 수주 삭제
DELETE /api/orders (bulk) - 수주 일괄 삭제
```
### 분할 관리
```
POST /api/orders/{id}/splits - 분할 추가
PUT /api/orders/{id}/splits/{splitId} - 분할 수정
DELETE /api/orders/{id}/splits/{splitId} - 분할 삭제
```
### 생산지시
```
POST /api/orders/{id}/production-order - 전체 생산지시
POST /api/orders/{id}/splits/{splitId}/production-order - 분할 생산지시
```
### 작업지시
```
POST /api/work-orders - 작업지시 생성
GET /api/work-orders?orderNo={orderNo} - 수주별 작업지시 조회
```
### 문서 출력
```
GET /api/orders/{id}/documents/contract - 계약서
GET /api/orders/{id}/documents/statement - 거래명세서
GET /api/orders/{id}/documents/purchase-order - 발주서
```

View File

@@ -0,0 +1,574 @@
# 수주(Order) API 스펙
> 작성 일시: 2024-12-18
> 분석 기반: design/mes기획서_리액트 사이트
## 개요
수주 관리 API는 견적→수주→분할→생산지시→출하 프로세스를 지원합니다.
---
## 1. 수주 CRUD API
### 1.1 수주 목록 조회
```
GET /api/orders
```
**Query Parameters:**
| 파라미터 | 타입 | 필수 | 설명 |
|----------|------|------|------|
| status | string | - | 상태 필터 (수주등록, 수주확정, 생산지시완료) |
| search | string | - | 검색어 (로트번호, 견적번호, 발주처, 현장명) |
| page | number | - | 페이지 번호 (기본: 1) |
| per_page | number | - | 페이지당 개수 (기본: 20) |
| sort | string | - | 정렬 기준 (기본: -id, 최신순) |
**Response:**
```json
{
"data": [
{
"id": 1,
"order_no": "KD-SO-241218-01",
"order_date": "2024-12-18",
"quote_no": "QT-241215-01",
"customer_name": "ABC건설",
"site_name": "강남 타워",
"status": "수주확정",
"total_amount": 85000000,
"due_date": "2024-12-30",
"delivery_method": "직접배차",
"split_count": 2,
"production_status": "대기",
"shipment_progress": 0
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 100,
"this_month_amount": 500000000,
"split_pending_count": 5,
"production_pending_count": 3,
"shipment_pending_count": 8
}
}
```
### 1.2 수주 상세 조회
```
GET /api/orders/{id}
```
**Response:**
```json
{
"data": {
"id": 1,
"order_no": "KD-SO-241218-01",
"order_date": "2024-12-18",
"order_type": "from-quote",
"quote_id": 10,
"quote_no": "QT-241215-01",
"parent_order_no": null,
"customer_id": 5,
"customer_name": "ABC건설",
"credit_grade": "A",
"site_name": "강남 타워",
"site_code": "S-001",
"manager": "김담당",
"contact": "010-1234-5678",
"due_date": "2024-12-30",
"status": "수주확정",
"payment_status": "미입금",
"accounting_status": "미확인",
"delivery_method": "직접배차",
"delivery_address": "서울시 강남구 테헤란로 123",
"receiver_name": "박수령",
"receiver_phone": "010-9876-5432",
"total_amount": 85000000,
"note": "특이사항 없음",
"items": [
{
"id": 1,
"product_code": "SCR-001",
"product_name": "국민방화스크린셔터",
"category": "스크린",
"floor": "B2",
"location": "주차장 입구",
"open_width": 5000,
"open_height": 3500,
"prod_width": 5140,
"prod_height": 3900,
"qty": 2,
"unit_price": 8000000,
"amount": 16000000,
"production_spec": {
"guide_rail_type": "백면형",
"guide_rail_spec": "120-70",
"shaft": 4,
"capacity": 160,
"finish": "SUS마감"
}
}
],
"splits": [
{
"id": 1,
"split_no": "KD-SO-241218-01-01",
"split_order": 1,
"split_type": "개소별",
"due_date": "2024-12-25",
"item_ids": [1, 2],
"production_status": "작업지시",
"shipment_status": "출고대기",
"production_order_no": "KD-PL-241218-01",
"total_qty": 2,
"completed_qty": 0
}
],
"motor_spec": { ... },
"bom_data": { ... },
"calculated_items": [ ... ],
"change_history": [ ... ],
"created_at": "2024-12-18 10:00:00",
"created_by": "admin"
}
}
```
### 1.3 수주 등록
```
POST /api/orders
```
**Request Body:**
```json
{
"order_date": "2024-12-18",
"order_type": "from-quote",
"quote_id": 10,
"customer_id": 5,
"customer_name": "ABC건설",
"site_name": "강남 타워",
"manager": "김담당",
"contact": "010-1234-5678",
"due_date": "2024-12-30",
"delivery_method": "직접배차",
"delivery_address": "서울시 강남구 테헤란로 123",
"receiver_name": "박수령",
"receiver_phone": "010-9876-5432",
"note": "특이사항",
"items": [
{
"product_name": "국민방화스크린셔터",
"category": "스크린",
"floor": "B2",
"location": "주차장 입구",
"open_width": 5000,
"open_height": 3500,
"qty": 2,
"unit_price": 8000000,
"guide_rail_type": "백면형",
"guide_rail_spec": "120-70",
"finish": "SUS마감"
}
]
}
```
**자동 처리:**
- `order_no`: 자동 생성 (KD-SO-YYMMDD-##)
- `site_code`: 자동 생성
- `status`: '수주등록' 초기화
- `payment_status`: '미입금' 초기화
- `prod_width`, `prod_height`, `shaft`, `capacity`: 자동 계산
- `motor_spec`, `bom_data`: 자동 생성
**Response:** 201 Created
```json
{
"data": {
"id": 1,
"order_no": "KD-SO-241218-01",
"status": "수주등록",
...
},
"message": "수주가 등록되었습니다."
}
```
### 1.4 수주 수정
```
PUT /api/orders/{id}
```
**Request Body:** (변경할 필드만)
```json
{
"due_date": "2024-12-31",
"delivery_method": "상차(선불)",
"note": "수정된 메모"
}
```
### 1.5 수주 삭제
```
DELETE /api/orders/{id}
```
### 1.6 수주 일괄 삭제
```
DELETE /api/orders
```
**Request Body:**
```json
{
"ids": [1, 2, 3]
}
```
---
## 2. 견적→수주 전환 API
### 2.1 견적에서 수주 전환
```
POST /api/orders/from-quote/{quoteId}
```
**Request Body:**
```json
{
"ship_date": "2024-12-25",
"ship_date_undecided": false,
"due_date": "2024-12-30",
"due_date_undecided": false,
"delivery_method": "상차",
"freight_cost": "선불",
"receiver_name": "박수령",
"receiver_phone": "010-9876-5432",
"delivery_address": "서울시 강남구",
"delivery_address_detail": "테헤란로 123",
"note": "수주전환 메모"
}
```
**Response:** 201 Created
```json
{
"data": {
"order": { ... },
"quote": {
"id": 10,
"status": "수주전환",
"converted_order_no": "KD-SO-241218-01"
}
},
"message": "견적이 수주로 전환되었습니다."
}
```
### 2.2 추가분 수주 등록
```
POST /api/orders/{orderId}/additional
```
**Request Body:**
```json
{
"items": [
{
"product_name": "국민방화스크린셔터",
"floor": "1F",
"location": "로비",
"open_width": 4000,
"open_height": 3000,
"qty": 1,
"unit_price": 7500000
}
],
"note": "추가 발주"
}
```
**자동 처리:**
- `order_no`: 원수주번호-A, B, C... 형식
- `order_type`: 'additional'
- `parent_order_no`: 원 수주번호
---
## 3. 분할 관리 API
### 3.1 분할 추가
```
POST /api/orders/{id}/splits
```
**Request Body:**
```json
{
"split_type": "개소별",
"due_date": "2024-12-25",
"item_ids": [1, 2, 3]
}
```
**자동 처리:**
- `split_no`: {order_no}-{순번2자리}
- `production_status`: '작업대기'
- `shipment_status`: '출고대기'
**Response:**
```json
{
"data": {
"id": 1,
"split_no": "KD-SO-241218-01-01",
"split_order": 1,
...
}
}
```
### 3.2 분할 수정
```
PUT /api/orders/{id}/splits/{splitId}
```
### 3.3 분할 삭제
```
DELETE /api/orders/{id}/splits/{splitId}
```
---
## 4. 생산지시 API
### 4.1 전체 생산지시 (분할 없이)
```
POST /api/orders/{id}/production-orders
```
**자동 처리:**
- 품목 카테고리별 작업지시 자동 분리 (스크린/슬랫/절곡)
- 작업지시번호 자동 생성 (KD-PL-YYMMDD-##)
- 공정별 팀 자동 배정
**Response:**
```json
{
"data": {
"work_orders": [
{
"id": 1,
"work_order_no": "KD-PL-241218-01",
"process_type": "스크린",
"status": "작업대기",
"assignee": "스크린팀"
},
{
"id": 2,
"work_order_no": "KD-PL-241218-02",
"process_type": "절곡",
"status": "작업대기",
"assignee": "절곡팀"
}
]
},
"message": "생산지시가 생성되었습니다."
}
```
### 4.2 분할 단위 생산지시
```
POST /api/orders/{id}/splits/{splitId}/production-orders
```
---
## 5. 문서 출력 API
### 5.1 계약서 출력
```
GET /api/orders/{id}/documents/contract
```
### 5.2 거래명세서 출력
```
GET /api/orders/{id}/documents/statement
```
**조건:**
- 입금후출고 거래처는 입금 확인 후에만 발행 가능
### 5.3 발주서 출력
```
GET /api/orders/{id}/documents/purchase-order
```
**Query Parameters:**
| 파라미터 | 타입 | 설명 |
|----------|------|------|
| format | string | 출력 형식 (pdf, html) |
---
## 6. 수주 상태 값
### 수주 상태 (status)
| 상태 | 설명 | 다음 상태 |
|------|------|-----------|
| 수주등록 | 초기 등록 | 수주확정 |
| 수주확정 | 확정 완료 | 생산중 |
| 생산중 | 생산 진행 | 생산완료 |
| 생산완료 | 생산 완료 | 출하완료 |
| 생산지시완료 | 생산지시 완료 | - |
| 출하완료 | 출하 완료 | - |
### 결제 상태 (payment_status)
| 상태 | 설명 |
|------|------|
| 미입금 | 입금 전 |
| 입금완료 | 입금 확인됨 |
### 회계 상태 (accounting_status)
| 상태 | 설명 |
|------|------|
| 미확인 | 확인 전 |
| 입금확인 | 경리 확인 완료 |
---
## 7. 데이터 모델
### Order (수주)
```
orders
├── id (PK)
├── tenant_id (FK)
├── order_no (UNIQUE)
├── order_date
├── order_type (enum: from-quote, direct, additional)
├── quote_id (FK, nullable)
├── parent_order_id (FK, nullable)
├── customer_id (FK)
├── site_id (FK)
├── manager
├── contact
├── due_date
├── status
├── payment_status
├── accounting_status
├── delivery_method
├── delivery_address
├── receiver_name
├── receiver_phone
├── total_amount
├── note
├── motor_spec (JSON)
├── bom_data (JSON)
├── created_by
├── created_at
├── updated_at
└── deleted_at
```
### OrderItem (수주 품목)
```
order_items
├── id (PK)
├── order_id (FK)
├── product_code
├── product_name
├── category (enum: 스크린, 슬랫, 절곡, 조립)
├── floor
├── location
├── open_width
├── open_height
├── prod_width (계산)
├── prod_height (계산)
├── qty
├── unit_price
├── amount
├── production_spec (JSON)
├── created_at
└── updated_at
```
### OrderSplit (수주 분할)
```
order_splits
├── id (PK)
├── order_id (FK)
├── split_no
├── split_order
├── split_type
├── due_date
├── production_status
├── shipment_status
├── production_order_no
├── total_qty
├── completed_qty
├── created_at
└── updated_at
```
### OrderSplitItem (분할 품목 연결)
```
order_split_items
├── id (PK)
├── split_id (FK)
└── item_id (FK)
```
---
## 8. 검증 규칙
### 수주 등록 시
```
customer_name: required
site_name: required
due_date: required, date, after:order_date
items: required, array, min:1
items.*.product_name: required
items.*.open_width: required, integer, min:500, max:15000
items.*.open_height: required, integer, min:500, max:10000
items.*.qty: required, integer, min:1
```
### 자동 계산 규칙
```javascript
// 제작 사이즈
prod_width = open_width + 140
prod_height = MAX(open_height + 400, 2950)
// 샤프트/용량
shaft = open_width > 6000 ? 5 : 4 // 인치
capacity = open_width > 6000 ? 300 : 160 // kg
// 금액
amount = qty * unit_price
total_amount = SUM(items.amount)
```
---
## 9. 이벤트/후크
### 수주 생성 시
- 변경 이력 기록
- 견적 상태 업데이트 (수주전환)
### 생산지시 생성 시
- 작업지시 자동 생성 (공정별)
- 분할 상태 업데이트
### 상태 변경 시
- 변경 이력 기록
- 알림 발송 (설정된 경우)

View File

@@ -0,0 +1,180 @@
# 수주관리 UI 스크린샷
> 캡처 일시: 2024-12-18
> 소스: http://localhost:3002/ (design/mes기획서_리액트)
## 스크린샷 목록
### 1. 수주 목록 페이지
![수주 목록](screenshots/01-order-list.png)
**주요 요소:**
- 상단 요약 카드: 이번 달 수주, 분할 대기, 생산지시 대기, 출하 대기
- 탭 필터: 전체, 수주등록, 수주확정, 생산지시완료
- 검색: 로트번호, 견적번호, 발주처, 현장명
- 테이블 컬럼: 체크박스, 번호, 로트번호, 견적번호, 발주처, 현장명, 상태, 출고예정일, 배송방식
---
### 2. 수주 상세 페이지
![수주 상세](screenshots/02-order-detail-top.png)
**주요 요소:**
- 헤더 버튼: 계약서, 거래명세서, 발주서 / 목록, 수정, 생산지시 생성
- 기본 정보: 발주처, 현장명, 담당자, 연락처
- 수주/배송 정보: 수주일자, 출고예정일, 납품요청일, 배송방식, 운임비용, 수신처
- 제품 내역: 순번, 품목코드, 품목명, 층, 부호, 규격, 수량, 단위, 단가, 금액
---
### 3. 계약서 모달
![계약서 모달](screenshots/03-contract-modal.png)
**주요 요소:**
- 문서 미리보기 영역
- 출력 옵션: PDF 다운로드, 이메일 발송, FAX 발송, 카카오톡, 프린트
---
### 4. 거래명세서 모달
![거래명세서 모달](screenshots/04-statement-modal.png)
**주요 요소:**
- 거래명세서 문서 미리보기
- 출력 옵션 (계약서와 동일)
---
### 5. 발주서 모달
![발주서 모달](screenshots/05-purchase-order-modal.png)
**주요 요소:**
- 발주서 문서 미리보기
- 출력 옵션 (계약서와 동일)
---
### 6. 수주 등록 폼
![수주 등록 폼](screenshots/06-order-create-form.png)
**주요 섹션:**
1. **견적 불러오기**: 확정된 견적 선택 버튼
2. **기본 정보**: 발주처(필수), 현장명(필수), 담당자, 연락처
3. **수주/배송 정보**:
- 출고예정일 (미정 체크 가능)
- 납품요청일 (필수, 미정 체크 가능)
- 배송방식: 상차, 직접배차, 직접수령, 경동화물, 경동택배, 대신화물, 대신택배
- 운임비용: 선불, 착불, 무료
- 수신(반장/업체)(필수), 수신처 연락처(필수)
- 수신처 주소(필수): 우편번호 찾기 + 기본/상세 주소
- 비고
4. **품목 내역**: 테이블 + 품목 추가 버튼
---
### 7. 품목 추가 모달
![품목 추가 모달](screenshots/07-item-add-modal.png)
**입력 필드:**
- 층, 도면부호
- 품목명 (선택)
- 오픈사이즈: 폭(mm), 높이(mm)
- 가이드레일 타입: 백면형, 양면형, 편면형
- 가이드레일 규격: 120-70, 150-80, 180-90
- 마감: SUS마감, 분체도장, 용융아연
- 단가
---
### 8. 견적 선택 모달
![견적 선택 모달](screenshots/08-quote-select-modal.png)
**주요 요소:**
- 검색: 견적번호, 거래처, 현장명
- 견적 목록: 최종확정 상태인 견적만 표시
- 각 견적 정보: 견적번호, 신용등급, 거래처, 현장명, 금액, 품목 수
---
### 9-11. 생산지시 생성 화면
#### 상단 (수주 정보 + 옵션)
![생산지시 생성 상단](screenshots/09-production-order-create-top.png)
**수주 정보:**
- 수주번호, 거래처, 현장명, 납기일, 품목 수, 총수량, 신용등급, 상태
**생산지시 옵션:**
- 우선순위 (영업): 긴급, 높음, 일반, 낮음
- 우선순위 매핑 테이블:
| 생산지시(영업) | 작업지시 기본값(공장) | 비고 |
|---------------|---------------------|------|
| 긴급 | 1순위 | 무조건 제일 먼저 |
| 높음 | 3순위 | 2순위는 현장 새치기용 |
| 일반 | 5순위 | 4순위 비워둠 |
| 낮음 | 9순위 | 뒤로 밀어둠 |
- 메모 입력
**생성될 작업지시:**
- 스크린 공정: 원단절단 → 미싱 → 앤드락작업 → 중간검사 → 포장
- 절곡 공정: 절단 → 절곡 → 중간검사 → 포장
---
#### 중간 (자재 소요량 + 품목 상세)
![생산지시 생성 중간](screenshots/10-production-order-create-mid.png)
**자재 소요량 및 재고 현황:**
| 자재코드 | 자재명 | 단위 | 소요량 | 현재고 | 상태 |
|---------|--------|------|--------|--------|------|
| SCR-MAT-001 | 스크린 원단 | ㎡ | 30 | 500 | 충분 |
| SCR-MAT-002 | 앤드락 | EA | 4 | 800 | 충분 |
| BND-MAT-001 | 철판 | KG | 60 | 2,000 | 충분 |
| BND-MAT-002 | 가이드레일 | M | 12 | 300 | 충분 |
| BND-MAT-003 | 케이스 | EA | 2 | 100 | 충분 |
**스크린 품목 상세:**
- No, 품목명, 도번/위치, 개구폭, 개구높이, 제작폭, 제작높이, 가이드레일, 샤프트, 용량, 마감, 수량
---
#### 하단 (모터/전장품 + BOM)
![생산지시 생성 하단](screenshots/11-production-order-create-bottom.png)
**모터/전장품 사양:**
- 모터 사양 (380V): KD-300K 2대
- 모터 브라켓: 380-180 [2-5"] 2개
**절곡물 BOM:**
- 가이드레일: 형태, 규격, 코드, 길이, 수량
- 케이스(셔터박스): 케이스 본체, 측면 덮개
- 하단 마감재: 품목, 규격, 길이, 수량
---
## UI 패턴 요약
### 상태 배지 색상
| 상태 | 색상 |
|------|------|
| 수주등록 | 회색 |
| 수주확정 | 파랑 |
| 생산중 | 노랑 |
| 생산지시완료 | 파랑 |
| 출하완료 | 초록 |
| 재작업중 | 빨강 |
| 작업대기 | 회색 |
| 작업완료 | 초록 |
### 공통 UI 컴포넌트
1. **카드형 요약**: 상단 리포트 카드 (4개)
2. **탭 필터**: 상태별 필터링
3. **테이블**: 체크박스 + 정렬 + 페이지네이션
4. **모달**: 문서 출력, 품목 추가, 견적 선택
5. **폼**: 섹션별 그룹화, 필수 필드 표시(*)
### 자동 계산 필드 (확인됨)
- 제작폭 = 개구폭 + 140
- 제작높이 = MAX(개구높이 + 400, 2950)
- 샤프트: 폭 > 6000 → 5인치, 그 외 4인치
- 용량: 폭 > 6000 → 300kg, 그 외 160kg

View File

@@ -0,0 +1,98 @@
# 수주 페이지 분석 결과
> 분석 일시: 2024-12-18
> 분석 대상: design/mes기획서_리액트 (디자인팀 기획 사이트)
## 분석 목적
디자인팀에서 제작한 기획 사이트를 분석하여 API 개발에 필요한 스펙을 추출합니다.
---
## 분석 문서 목록
| 순서 | 문서 | 설명 |
|------|------|------|
| 01 | [메뉴 구조](01-menu-structure.md) | 수주 관련 메뉴 구조 및 화면 목록 |
| 02 | [수주 스키마](02-order-schema.md) | 수주 데이터 스키마, 필드 정의, 자동계산 규칙 |
| 03 | [견적/수주 UI](03-quote-ui.md) | 견적 상세 → 수주 전환 UI 및 문서 출력 |
| 04 | [App.jsx 수주 섹션](04-app-order-section.md) | OrderList, OrderDetail, OrderCreate 컴포넌트 분석 |
| 05 | [API 스펙](05-api-spec.md) | **최종 API 엔드포인트 및 데이터 모델** |
| 06 | [UI 스크린샷](06-screenshots.md) | **수주관리 전체 화면 캡처 (11개)** |
---
## 핵심 발견 사항
### 1. 수주 유형 (3가지)
- **일반수주 (from-quote)**: 견적에서 전환
- **직접수주 (direct)**: 견적 없이 직접 등록
- **추가수주 (additional)**: 기존 수주에 품목 추가
### 2. 수주 프로세스
```
견적(최종확정) → 수주전환 → 수주등록 → 수주확정 → 분할 → 생산지시 → 작업지시 → 출하
```
### 3. 분할 관리
- 대형 현장은 분할 출하 필요
- 분할번호: `{수주번호}-{순번2자리}` (예: KD-SO-241218-01-01)
- 분할 단위로 생산지시/출하 관리
### 4. 생산지시 자동화
- 품목 카테고리별 작업지시 자동 분리
- 스크린 → 스크린팀
- 슬랫/철재 → 슬랫팀
- 절곡 → 절곡팀
- BOM 데이터 기반 절곡물 작업지시 자동 생성
### 5. 자동 계산 규칙
```
제작폭 = 개구폭 + 140
제작높이 = MAX(개구높이 + 400, 2950)
샤프트 = 폭 > 6000 ? 5인치 : 4인치
전동용량 = 폭 > 6000 ? 300kg : 160kg
```
### 6. 채번 규칙
| 문서 | 형식 | 예시 |
|------|------|------|
| 수주번호 | KD-SO-YYMMDD-## | KD-SO-241218-01 |
| 분할번호 | {수주번호}-## | KD-SO-241218-01-01 |
| 작업지시번호 | KD-PL-YYMMDD-## | KD-PL-241218-01 |
| 추가분수주 | {수주번호}-A,B,C | KD-SO-241218-01-A |
---
## API 개발 우선순위
### Phase 1: 기본 CRUD
1. 수주 목록/상세/등록/수정/삭제
2. 수주 품목 관리
3. 채번 자동 생성
### Phase 2: 견적 연동
1. 견적 → 수주 전환
2. 추가분 수주 등록
### Phase 3: 분할/생산지시
1. 분할 관리
2. 생산지시 생성
3. 작업지시 연동
### Phase 4: 문서/통계
1. 계약서/거래명세서/발주서 출력
2. 대시보드 통계 API
---
## 참고 파일
**분석 대상 파일:**
- `design/mes기획서_리액트/src/configs/menuDefinitions.js` (7KB)
- `design/mes기획서_리액트/src/configs/orderMasterConfig.js` (14KB)
- `design/mes기획서_리액트/src/components/QuoteDetailNew.jsx` (18KB)
- `design/mes기획서_리액트/src/components/QuoteDocumentDialogs.jsx` (23KB)
- `design/mes기획서_리액트/src/App.jsx` (3.9MB) - 수주 섹션만 추출 분석
**주의:** App.jsx는 80,049줄의 대형 파일로, 수주 관련 섹션(52768~56357줄)만 분석했습니다.

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB