2026-03-16 21:27:17 +09:00
|
|
|
# 재고생산관리 API 명세
|
|
|
|
|
|
|
|
|
|
> **작성일**: 2026-03-16
|
|
|
|
|
> **상태**: 설계 확정
|
|
|
|
|
> **대상**: React 프론트엔드 개발자
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 1. 개요
|
|
|
|
|
|
|
|
|
|
### 1.1 목적
|
|
|
|
|
|
|
|
|
|
재고생산관리는 **수주 없이 재고 목적으로 생산**하는 경우를 위한 기능이다.
|
|
|
|
|
기존 수주관리(Order) API를 **그대로 사용**하되, `order_type_code: 'STOCK'`으로 구분한다.
|
|
|
|
|
|
|
|
|
|
### 1.2 핵심 원칙
|
|
|
|
|
|
|
|
|
|
- 별도 API 엔드포인트 없음 — 기존 `/api/v1/orders` 사용
|
|
|
|
|
- `order_type_code` 필터로 수주(`ORDER`)와 재고생산(`STOCK`)을 분리
|
|
|
|
|
- 화면은 수주관리를 **단순화**한 형태 (거래처, 견적, 배송, 할인 등 불필요)
|
|
|
|
|
- 하류 시스템(작업지시, 생산, 출하)은 **동일하게 동작**
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 2. API 엔드포인트
|
|
|
|
|
|
|
|
|
|
> **기본 URL**: `/api/v1/orders`
|
|
|
|
|
> **인증**: `Bearer Token` (Sanctum) + `API Key`
|
|
|
|
|
|
|
|
|
|
### 2.1 목록 조회
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
GET /api/v1/orders?order_type=STOCK
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
| 파라미터 | 타입 | 필수 | 설명 |
|
|
|
|
|
|----------|------|:----:|------|
|
|
|
|
|
| `order_type` | string | ✅ | `STOCK` 고정 |
|
|
|
|
|
| `page` | int | - | 페이지 (기본: 1) |
|
|
|
|
|
| `size` | int | - | 페이지 크기 (기본: 20) |
|
|
|
|
|
| `q` | string | - | 검색어 (생산번호, 메모) |
|
|
|
|
|
| `status` | string | - | 상태 필터 (`DRAFT`, `CONFIRMED` 등) |
|
|
|
|
|
| `date_from` | date | - | 등록일 시작 |
|
|
|
|
|
| `date_to` | date | - | 등록일 종료 |
|
|
|
|
|
|
|
|
|
|
**응답 예시**:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"success": true,
|
|
|
|
|
"message": "message.order.fetched",
|
|
|
|
|
"data": {
|
|
|
|
|
"data": [
|
|
|
|
|
{
|
|
|
|
|
"id": 42,
|
|
|
|
|
"order_no": "STK202603160001",
|
|
|
|
|
"order_type_code": "STOCK",
|
|
|
|
|
"status_code": "DRAFT",
|
|
|
|
|
"quantity": "100.0000",
|
|
|
|
|
"memo": "봄 시즌 대비 재고 확보",
|
|
|
|
|
"options": {
|
|
|
|
|
"production_reason": "시즌 대비",
|
|
|
|
|
"target_stock_qty": 500
|
|
|
|
|
},
|
|
|
|
|
"items": [
|
|
|
|
|
{
|
|
|
|
|
"id": 1,
|
|
|
|
|
"item_name": "25mm 알루미늄 블라인드",
|
|
|
|
|
"specification": "W1000 x H2000",
|
|
|
|
|
"quantity": "100.0000",
|
|
|
|
|
"unit_price": "15000.00"
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
"created_at": "2026-03-16T10:30:00Z"
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
"current_page": 1,
|
|
|
|
|
"last_page": 1,
|
|
|
|
|
"total": 1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 2.2 통계 조회
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
GET /api/v1/orders/stats?order_type=STOCK
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
| 파라미터 | 타입 | 필수 | 설명 |
|
|
|
|
|
|----------|------|:----:|------|
|
|
|
|
|
| `order_type` | string | ✅ | `STOCK` 고정 |
|
|
|
|
|
|
|
|
|
|
**응답 예시**:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"success": true,
|
|
|
|
|
"data": {
|
|
|
|
|
"total": 15,
|
|
|
|
|
"draft": 3,
|
|
|
|
|
"confirmed": 5,
|
|
|
|
|
"in_progress": 4,
|
|
|
|
|
"completed": 2,
|
|
|
|
|
"cancelled": 1,
|
|
|
|
|
"total_amount": 0,
|
|
|
|
|
"confirmed_amount": 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 2.3 생성
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
POST /api/v1/orders
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**요청 본문**:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"order_type_code": "STOCK",
|
|
|
|
|
"memo": "봄 시즌 대비 재고 확보",
|
|
|
|
|
"options": {
|
|
|
|
|
"production_reason": "시즌 대비",
|
|
|
|
|
"target_stock_qty": 500
|
|
|
|
|
},
|
|
|
|
|
"items": [
|
|
|
|
|
{
|
|
|
|
|
"item_id": 10,
|
|
|
|
|
"item_name": "25mm 알루미늄 블라인드",
|
|
|
|
|
"specification": "W1000 x H2000",
|
|
|
|
|
"quantity": 100,
|
|
|
|
|
"unit_price": 0,
|
|
|
|
|
"unit": "EA"
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**필수 필드**:
|
|
|
|
|
|
|
|
|
|
| 필드 | 타입 | 필수 | 설명 |
|
|
|
|
|
|------|------|:----:|------|
|
|
|
|
|
| `order_type_code` | string | ✅ | `STOCK` 고정 |
|
|
|
|
|
| `items` | array | ✅ | 생산할 품목 목록 |
|
|
|
|
|
| `items[].item_name` | string | ✅ | 품목명 |
|
|
|
|
|
| `items[].quantity` | number | ✅ | 수량 |
|
|
|
|
|
| `items[].unit_price` | number | ✅ | 단가 (재고생산은 `0` 가능) |
|
|
|
|
|
|
|
|
|
|
**선택 필드**:
|
|
|
|
|
|
|
|
|
|
| 필드 | 타입 | 설명 |
|
|
|
|
|
|------|------|------|
|
|
|
|
|
| `memo` | string | 비고 |
|
|
|
|
|
| `options.production_reason` | string | 생산 사유 |
|
|
|
|
|
| `options.target_stock_qty` | number | 목표 재고 수량 |
|
|
|
|
|
| `items[].item_id` | int | 품목 마스터 ID |
|
|
|
|
|
| `items[].specification` | string | 규격 |
|
|
|
|
|
| `items[].unit` | string | 단위 |
|
|
|
|
|
|
|
|
|
|
**사용하지 않는 필드** (수주 전용):
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
❌ client_id, client_name, client_contact → 거래처 없음
|
2026-03-16 22:24:24 +09:00
|
|
|
❌ site_name → API가 '재고생산'으로 자동 설정
|
2026-03-16 21:27:17 +09:00
|
|
|
❌ quote_id → 견적 없음
|
|
|
|
|
❌ delivery_date, delivery_method_code → 납기/배송 불필요
|
|
|
|
|
❌ discount_rate, discount_amount → 할인 없음
|
|
|
|
|
❌ sales_recognition → 매출 인식 불필요
|
|
|
|
|
❌ options.shipping_cost_code → 운임비용 불필요
|
|
|
|
|
❌ options.receiver, receiver_contact → 수신자 불필요
|
|
|
|
|
❌ options.shipping_address → 배송지 불필요
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
> **자동 생성**: `order_no`는 `STK{YYYYMMDD}{NNNN}` 형식으로 서버에서 자동 생성
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 2.4 단건 조회
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
GET /api/v1/orders/{id}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
기존 수주 조회와 동일. `order_type_code`가 `STOCK`인지 프론트에서 확인.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 2.5 수정
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
PUT /api/v1/orders/{id}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
생성과 동일한 필드 사용. `order_type_code`는 변경하지 않는다.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 2.6 삭제
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
DELETE /api/v1/orders/{id}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
기존 수주 삭제와 동일.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 2.7 상태 변경
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
PATCH /api/v1/orders/{id}/status
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"status": "CONFIRMED"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**상태 흐름** (수주와 동일):
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
DRAFT → CONFIRMED → IN_PROGRESS → COMPLETED
|
|
|
|
|
└─────→ CANCELLED ──→ DRAFT (복구)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
> **재고생산 특수**: `CONFIRMED` 상태 진입 시 매출 자동 생성이 **발생하지 않음**
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 2.8 생산지시 생성
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
POST /api/v1/orders/{id}/production-order
|
|
|
|
|
```
|
|
|
|
|
|
2026-03-16 22:24:24 +09:00
|
|
|
재고생산은 **절곡 공정이 자동 선택**된다 (API에서 처리). `process_ids` 전달 불필요.
|
2026-03-16 21:27:17 +09:00
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"priority": "normal",
|
|
|
|
|
"memo": "재고생산 작업"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-03-16 22:24:24 +09:00
|
|
|
**API 자동 처리 항목** (STOCK 타입):
|
|
|
|
|
|
|
|
|
|
| 항목 | 일반 수주 | 재고생산 (자동) |
|
|
|
|
|
|------|----------|---------------|
|
|
|
|
|
| 현장명 (`project_name`) | `site_name` 또는 `client_name` | `'재고생산'` 고정 |
|
|
|
|
|
| 공정 | BOM item_id → process_items 매칭 | **절곡 공정 자동 선택** |
|
|
|
|
|
| 작업예정일 (`scheduled_date`) | `delivery_date` | **생성일 (now())** |
|
|
|
|
|
| 매출 생성 | `sales_recognition` 정책 적용 | **생성 안 함** |
|
|
|
|
|
|
|
|
|
|
> 프론트에서 `process_ids`, `scheduled_date`를 전달하지 않아도 API가 자동 처리
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-03-16 21:27:17 +09:00
|
|
|
## 3. 채번 규칙
|
|
|
|
|
|
|
|
|
|
| 주문 유형 | 접두사 | 예시 |
|
|
|
|
|
|----------|--------|------|
|
|
|
|
|
| 수주 (ORDER) | `ORD` | `ORD202603160001` |
|
|
|
|
|
| 재고생산 (STOCK) | `STK` | `STK202603160001` |
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 4. 화면 설계 가이드
|
|
|
|
|
|
|
|
|
|
### 4.1 수주관리 화면 vs 재고생산관리 화면
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
┌─ 수주관리 ──────────────────┐ ┌─ 재고생산관리 ───────────────┐
|
|
|
|
|
│ │ │ │
|
|
|
|
|
│ [거래처 정보] │ │ [생산 정보] │
|
|
|
|
|
│ - 거래처 선택 │ │ - 생산 사유 (텍스트) │
|
|
|
|
|
│ - 현장명 │ │ - 목표 재고 수량 │
|
|
|
|
|
│ - 배송/납기일 │ │ - 비고 │
|
|
|
|
|
│ - 운임비용 │ │ │
|
|
|
|
|
│ - 견적 연결 │ ├──────────────────────────────┤
|
|
|
|
|
│ - 할인 │ │ [품목 목록] │
|
|
|
|
|
│ - 매출 인식 방식 │ │ - 품목 선택 │
|
|
|
|
|
│ │ │ - 수량 │
|
|
|
|
|
│ [개소/구역 (OrderNode)] │ │ - 규격 │
|
|
|
|
|
│ - N-depth 트리 구조 │ │ │
|
|
|
|
|
│ │ │ (단가/금액/할인 불필요) │
|
|
|
|
|
│ [품목 목록] │ │ (개소/구역 불필요) │
|
|
|
|
|
│ - 품목, 수량, 단가, 할인 │ │ │
|
|
|
|
|
│ - floor_code, symbol_code │ └──────────────────────────────┘
|
|
|
|
|
│ - 금액 계산 │
|
|
|
|
|
│ │
|
|
|
|
|
└──────────────────────────────┘
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 4.2 목록 페이지 표시 컬럼
|
|
|
|
|
|
|
|
|
|
| 컬럼 | 설명 |
|
|
|
|
|
|------|------|
|
|
|
|
|
| 생산번호 | `order_no` (STK...) |
|
|
|
|
|
| 상태 | `status_code` (상태 배지) |
|
|
|
|
|
| 품목 | 대표 품목명 + (외 N건) |
|
|
|
|
|
| 수량 | 총 수량 |
|
|
|
|
|
| 생산 사유 | `options.production_reason` |
|
|
|
|
|
| 등록일 | `created_at` |
|
|
|
|
|
|
|
|
|
|
### 4.3 상태 배지 색상 (수주와 동일)
|
|
|
|
|
|
|
|
|
|
| 상태 | 라벨 | 색상 |
|
|
|
|
|
|------|------|------|
|
|
|
|
|
| `DRAFT` | 등록 | gray |
|
|
|
|
|
| `CONFIRMED` | 확정 | blue |
|
|
|
|
|
| `IN_PROGRESS` | 진행중 | yellow |
|
|
|
|
|
| `IN_PRODUCTION` | 생산중 | orange |
|
|
|
|
|
| `PRODUCED` | 생산완료 | green |
|
|
|
|
|
| `COMPLETED` | 완료 | green |
|
|
|
|
|
| `CANCELLED` | 취소 | red |
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 5. 구현 체크리스트
|
|
|
|
|
|
|
|
|
|
### 프론트엔드 (React)
|
|
|
|
|
|
|
|
|
|
- [ ] 재고생산관리 메뉴/라우트 추가
|
|
|
|
|
- [ ] 목록 페이지: `GET /api/v1/orders?order_type=STOCK`
|
|
|
|
|
- [ ] 통계 카드: `GET /api/v1/orders/stats?order_type=STOCK`
|
|
|
|
|
- [ ] 생성 폼: `order_type_code: 'STOCK'` 필수 전송
|
|
|
|
|
- [ ] 상세/수정 페이지: 수주 화면 단순화 (거래처/견적/배송/할인 제거)
|
|
|
|
|
- [ ] 생산지시 생성 버튼: `POST /api/v1/orders/{id}/production-order`
|
|
|
|
|
- [ ] 상태 변경: `PATCH /api/v1/orders/{id}/status`
|
|
|
|
|
|
2026-03-16 22:24:24 +09:00
|
|
|
### 프론트엔드 — 생산지시 목록 수정
|
|
|
|
|
|
|
|
|
|
- [ ] 생산지시 목록에서 `order_type_code`가 `STOCK`인 건: 납기 컬럼 `-` 표시
|
|
|
|
|
- [ ] 생산지시 생성 UI: STOCK 수주는 공정 선택 불필요 (API가 절곡 자동 선택)
|
|
|
|
|
|
2026-03-16 21:27:17 +09:00
|
|
|
### 백엔드 (API) — 완료
|
|
|
|
|
|
|
|
|
|
- [x] `Order::TYPE_STOCK = 'STOCK'` 상수 추가
|
|
|
|
|
- [x] StoreOrderRequest에 `STOCK` validation 추가
|
|
|
|
|
- [x] UpdateOrderRequest에 `STOCK` validation 추가
|
|
|
|
|
- [x] 재고생산 채번: `STK{YYYYMMDD}{NNNN}`
|
|
|
|
|
- [x] stats()에 `order_type` 필터 추가
|
|
|
|
|
- [x] STOCK 타입 확정 시 매출 자동 생성 스킵
|
|
|
|
|
- [x] options에 `production_reason`, `target_stock_qty` 필드 추가
|
2026-03-16 22:24:24 +09:00
|
|
|
- [x] store()에서 STOCK 타입 `site_name = '재고생산'` 자동 설정
|
|
|
|
|
- [x] createProductionOrder()에서 STOCK: `project_name = '재고생산'` 고정
|
|
|
|
|
- [x] createProductionOrder()에서 STOCK: 절곡 공정 자동 선택
|
|
|
|
|
- [x] createProductionOrder()에서 STOCK: `scheduled_date = now()` 자동 설정
|
2026-03-16 21:27:17 +09:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 관련 문서
|
|
|
|
|
|
|
|
|
|
- 수주관리: 기존 수주 API는 동일 엔드포인트 (`/api/v1/orders`)
|
|
|
|
|
- 작업지시: `POST /api/v1/orders/{id}/production-order`
|
|
|
|
|
- 품목관리: `rules/item-policy.md`
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
**최종 업데이트**: 2026-03-16
|