- v1-analysis: 5130 레거시 기반 견적 분석 추가 - v2-analysis: 기존 MES 분석 문서들 이동 - customer, master-data, order, price - production, production-userflow, quote, site
574 lines
12 KiB
Markdown
574 lines
12 KiB
Markdown
# 수주(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. 이벤트/후크
|
|
|
|
### 수주 생성 시
|
|
- 변경 이력 기록
|
|
- 견적 상태 업데이트 (수주전환)
|
|
|
|
### 생산지시 생성 시
|
|
- 작업지시 자동 생성 (공정별)
|
|
- 분할 상태 업데이트
|
|
|
|
### 상태 변경 시
|
|
- 변경 이력 기록
|
|
- 알림 발송 (설정된 경우) |