- v1-analysis: 5130 레거시 기반 견적 분석 추가 - v2-analysis: 기존 MES 분석 문서들 이동 - customer, master-data, order, price - production, production-userflow, quote, site
12 KiB
12 KiB
수주(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:
{
"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:
{
"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:
{
"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
{
"data": {
"id": 1,
"order_no": "KD-SO-241218-01",
"status": "수주등록",
...
},
"message": "수주가 등록되었습니다."
}
1.4 수주 수정
PUT /api/orders/{id}
Request Body: (변경할 필드만)
{
"due_date": "2024-12-31",
"delivery_method": "상차(선불)",
"note": "수정된 메모"
}
1.5 수주 삭제
DELETE /api/orders/{id}
1.6 수주 일괄 삭제
DELETE /api/orders
Request Body:
{
"ids": [1, 2, 3]
}
2. 견적→수주 전환 API
2.1 견적에서 수주 전환
POST /api/orders/from-quote/{quoteId}
Request Body:
{
"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
{
"data": {
"order": { ... },
"quote": {
"id": 10,
"status": "수주전환",
"converted_order_no": "KD-SO-241218-01"
}
},
"message": "견적이 수주로 전환되었습니다."
}
2.2 추가분 수주 등록
POST /api/orders/{orderId}/additional
Request Body:
{
"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:
{
"split_type": "개소별",
"due_date": "2024-12-25",
"item_ids": [1, 2, 3]
}
자동 처리:
split_no: {order_no}-{순번2자리}production_status: '작업대기'shipment_status: '출고대기'
Response:
{
"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:
{
"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
자동 계산 규칙
// 제작 사이즈
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. 이벤트/후크
수주 생성 시
- 변경 이력 기록
- 견적 상태 업데이트 (수주전환)
생산지시 생성 시
- 작업지시 자동 생성 (공정별)
- 분할 상태 업데이트
상태 변경 시
- 변경 이력 기록
- 알림 발송 (설정된 경우)