Files
sam-docs/projects/mes/v2-analysis/order-analysis/05-api-spec.md
hskwon 764a6470c6 MES 분석 문서 구조 정리: v1/v2 분리
- v1-analysis: 5130 레거시 기반 견적 분석 추가
- v2-analysis: 기존 MES 분석 문서들 이동
  - customer, master-data, order, price
  - production, production-userflow, quote, site
2025-12-19 15:37:59 +09:00

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. 이벤트/후크

수주 생성 시

  • 변경 이력 기록
  • 견적 상태 업데이트 (수주전환)

생산지시 생성 시

  • 작업지시 자동 생성 (공정별)
  • 분할 상태 업데이트

상태 변경 시

  • 변경 이력 기록
  • 알림 발송 (설정된 경우)