2026-03-17 13:08:23 +09:00
|
|
|
|
# 절곡품 재고생산 LOT API 명세
|
|
|
|
|
|
|
|
|
|
|
|
> **작성일**: 2026-03-17
|
|
|
|
|
|
> **상태**: 개발 완료 (백엔드)
|
|
|
|
|
|
> **대상**: React 프론트엔드 개발자
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 개요
|
|
|
|
|
|
|
|
|
|
|
|
재고생산(STOCK) 등록 시 절곡품 전용 입력 폼을 위한 API이다.
|
|
|
|
|
|
**캐스케이딩 드롭다운**(품목→종류→모양&길이)으로 품목을 선택하고, **LOT 번호를 자동 생성**한다.
|
|
|
|
|
|
|
|
|
|
|
|
### 1.1 API 엔드포인트 요약
|
|
|
|
|
|
|
|
|
|
|
|
| Method | Path | 설명 |
|
|
|
|
|
|
|--------|------|------|
|
|
|
|
|
|
| `GET` | `/api/v1/bending/code-map` | 드롭다운 코드 체계 전체 조회 |
|
|
|
|
|
|
| `GET` | `/api/v1/bending/resolve-item` | 선택 조합 → 품목 매핑 조회 |
|
|
|
|
|
|
| `POST` | `/api/v1/bending/generate-lot` | LOT 번호 생성 (일련번호 포함) |
|
2026-03-17 14:21:36 +09:00
|
|
|
|
| `GET` | `/api/v1/bending/material-lots` | 원자재 LOT 목록 (수입검사 완료 입고) |
|
2026-03-17 13:08:23 +09:00
|
|
|
|
| `POST` | `/api/v1/orders` | 재고생산 저장 (기존 API, options 확장) |
|
2026-03-17 14:21:36 +09:00
|
|
|
|
| `PATCH` | `/api/v1/orders/{id}/status` | 상태 변경 (취소→등록 복원 포함) |
|
2026-03-17 13:08:23 +09:00
|
|
|
|
|
|
|
|
|
|
### 1.2 인증
|
|
|
|
|
|
|
|
|
|
|
|
모든 엔드포인트: `X-API-KEY` + `Bearer Token` (기존과 동일)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 코드맵 조회
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
GET /api/v1/bending/code-map
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
캐스케이딩 드롭다운 구성에 필요한 전체 코드 체계를 반환한다.
|
|
|
|
|
|
앱 초기 로드 시 1회 호출하여 캐싱한다.
|
|
|
|
|
|
|
|
|
|
|
|
### 응답
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"success": true,
|
|
|
|
|
|
"data": {
|
|
|
|
|
|
"products": [
|
|
|
|
|
|
{ "code": "R", "name": "가이드레일(벽면형)" },
|
|
|
|
|
|
{ "code": "S", "name": "가이드레일(측면형)" },
|
|
|
|
|
|
{ "code": "G", "name": "연기차단재" },
|
|
|
|
|
|
{ "code": "B", "name": "하단마감재(스크린)" },
|
|
|
|
|
|
{ "code": "T", "name": "하단마감재(철재)" },
|
|
|
|
|
|
{ "code": "L", "name": "L-Bar" },
|
|
|
|
|
|
{ "code": "C", "name": "케이스" }
|
|
|
|
|
|
],
|
|
|
|
|
|
"specs": [
|
|
|
|
|
|
{ "code": "M", "name": "본체", "products": ["R", "S"] },
|
|
|
|
|
|
{ "code": "T", "name": "본체(철재)", "products": ["R", "S"] },
|
|
|
|
|
|
{ "code": "C", "name": "C형", "products": ["R", "S"] },
|
|
|
|
|
|
{ "code": "D", "name": "D형", "products": ["R", "S"] },
|
|
|
|
|
|
{ "code": "S", "name": "SUS(마감)", "products": ["R", "S", "B", "T"] },
|
|
|
|
|
|
{ "code": "U", "name": "SUS(마감)2", "products": ["S"] },
|
|
|
|
|
|
{ "code": "E", "name": "EGI(마감)", "products": ["R", "S", "B", "T"] },
|
|
|
|
|
|
{ "code": "I", "name": "화이바원단", "products": ["G"] },
|
|
|
|
|
|
{ "code": "A", "name": "스크린용", "products": ["L"] },
|
|
|
|
|
|
{ "code": "F", "name": "전면부", "products": ["C"] },
|
|
|
|
|
|
{ "code": "P", "name": "점검구", "products": ["C"] },
|
|
|
|
|
|
{ "code": "L", "name": "린텔부", "products": ["C"] },
|
|
|
|
|
|
{ "code": "B", "name": "후면코너부", "products": ["C"] }
|
|
|
|
|
|
],
|
|
|
|
|
|
"lengths": {
|
|
|
|
|
|
"smoke_barrier": [
|
|
|
|
|
|
{ "code": "53", "name": "W50 × 3000" },
|
|
|
|
|
|
{ "code": "54", "name": "W50 × 4000" },
|
|
|
|
|
|
{ "code": "83", "name": "W80 × 3000" },
|
|
|
|
|
|
{ "code": "84", "name": "W80 × 4000" }
|
|
|
|
|
|
],
|
|
|
|
|
|
"general": [
|
|
|
|
|
|
{ "code": "12", "name": "1219" },
|
|
|
|
|
|
{ "code": "24", "name": "2438" },
|
|
|
|
|
|
{ "code": "30", "name": "3000" },
|
|
|
|
|
|
{ "code": "35", "name": "3500" },
|
|
|
|
|
|
{ "code": "40", "name": "4000" },
|
|
|
|
|
|
{ "code": "41", "name": "4150" },
|
|
|
|
|
|
{ "code": "42", "name": "4200" },
|
|
|
|
|
|
{ "code": "43", "name": "4300" }
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
"material_map": {
|
|
|
|
|
|
"G:I": "화이바원단",
|
|
|
|
|
|
"B:S": "SUS 1.2T",
|
|
|
|
|
|
"B:E": "EGI 1.55T",
|
|
|
|
|
|
"R:S": "SUS 1.2T",
|
|
|
|
|
|
"R:M": "EGI 1.55T"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 프론트엔드 사용법
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
// 1. 품목(prod) 선택 → 종류(spec) 필터링
|
|
|
|
|
|
const availableSpecs = codeMap.specs.filter(s => s.products.includes(selectedProd));
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 품목 코드가 'G'(연기차단재)이면 smoke_barrier 길이, 아니면 general 길이
|
|
|
|
|
|
const lengths = selectedProd === 'G'
|
|
|
|
|
|
? codeMap.lengths.smoke_barrier
|
|
|
|
|
|
: codeMap.lengths.general;
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 원자재 재질 결정
|
|
|
|
|
|
const material = codeMap.material_map[`${selectedProd}:${selectedSpec}`];
|
|
|
|
|
|
// 예: 'G:I' → '화이바원단', 'R:S' → 'SUS 1.2T'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 품목 매핑 조회
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
GET /api/v1/bending/resolve-item?prod={prodCode}&spec={specCode}&length={lengthCode}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
드롭다운에서 3개를 모두 선택했을 때 호출한다.
|
|
|
|
|
|
`bending_item_mappings` 테이블에서 대응하는 `items` 레코드를 반환한다.
|
|
|
|
|
|
|
|
|
|
|
|
### 파라미터
|
|
|
|
|
|
|
|
|
|
|
|
| 파라미터 | 필수 | 설명 | 예시 |
|
|
|
|
|
|
|---------|------|------|------|
|
|
|
|
|
|
| `prod` | O | 제품 코드 | `R` |
|
|
|
|
|
|
| `spec` | O | 종류 코드 | `M` |
|
|
|
|
|
|
| `length` | O | 모양&길이 코드 | `42` |
|
|
|
|
|
|
|
|
|
|
|
|
### 성공 응답 (200)
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"success": true,
|
|
|
|
|
|
"data": {
|
|
|
|
|
|
"item_id": 15604,
|
|
|
|
|
|
"item_code": "BD-RM-42",
|
|
|
|
|
|
"item_name": "가이드레일(벽면) 본체 4200mm",
|
|
|
|
|
|
"specification": "EGI 1.55T 4200mm",
|
|
|
|
|
|
"unit": "EA"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 매핑 없음 응답 (404)
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"success": false,
|
|
|
|
|
|
"message": "[404] 해당 조합에 매핑된 품목이 없습니다."
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
> **참고**: 매핑이 없으면 품목 없이도 저장 가능하다 (item_id=null). 추후 관리자가 MNG에서 매핑을 등록하면 연결된다.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. LOT 번호 생성
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
POST /api/v1/bending/generate-lot
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
저장 직전에 호출하여 일련번호가 확정된 LOT 번호를 받는다.
|
|
|
|
|
|
|
|
|
|
|
|
### 요청
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"prod_code": "G",
|
|
|
|
|
|
"spec_code": "I",
|
|
|
|
|
|
"length_code": "53",
|
|
|
|
|
|
"reg_date": "2026-03-17"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
| 필드 | 필수 | 설명 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| `prod_code` | O | 제품 코드 |
|
|
|
|
|
|
| `spec_code` | O | 종류 코드 |
|
|
|
|
|
|
| `length_code` | O | 모양&길이 코드 |
|
|
|
|
|
|
| `reg_date` | △ | 등록일 (미입력 시 오늘) |
|
|
|
|
|
|
|
|
|
|
|
|
### 응답
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"success": true,
|
|
|
|
|
|
"data": {
|
|
|
|
|
|
"lot_base": "GI6317-53",
|
|
|
|
|
|
"lot_number": "GI6317-53-001",
|
|
|
|
|
|
"date_code": "6317",
|
|
|
|
|
|
"material": "화이바원단"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### LOT 번호 구조
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
GI6317-53-001
|
|
|
|
|
|
││││││ ││ └── 일련번호 (같은 날 같은 조합의 순번)
|
|
|
|
|
|
││││││ └┴── 모양&길이 코드
|
|
|
|
|
|
││││└┴────── 일 (17일)
|
|
|
|
|
|
│││└──────── 월 (3월)
|
|
|
|
|
|
││└───────── 년 (2026 → 6)
|
|
|
|
|
|
│└────────── 종류 (화이바원단)
|
|
|
|
|
|
└─────────── 제품 (연기차단재)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
> **날짜코드 월 변환**: 1~9 그대로, 10=A, 11=B, 12=C
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-03-17 14:21:36 +09:00
|
|
|
|
## 5. 원자재 LOT 목록 조회
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
GET /api/v1/bending/material-lots?material={재질명}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
수입검사가 완료된(`status=completed`) 입고 건 중 재질이 일치하는 LOT 목록을 반환한다.
|
|
|
|
|
|
원자재 LOT 선택 모달에서 사용한다.
|
|
|
|
|
|
|
|
|
|
|
|
### 파라미터
|
|
|
|
|
|
|
|
|
|
|
|
| 파라미터 | 필수 | 설명 | 예시 |
|
|
|
|
|
|
|---------|------|------|------|
|
|
|
|
|
|
| `material` | △ | 원자재 재질명 (부분 일치 검색) | `SUS 1.2T`, `EGI 1.55T`, `화이바원단` |
|
|
|
|
|
|
|
|
|
|
|
|
### 응답
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"success": true,
|
|
|
|
|
|
"data": [
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": 42,
|
|
|
|
|
|
"lot_no": "RM-20260301-001",
|
|
|
|
|
|
"supplier_lot": "SUP-2026-A123",
|
|
|
|
|
|
"item_name": "SUS 1.2T",
|
|
|
|
|
|
"specification": "1219 × 2438",
|
|
|
|
|
|
"receiving_qty": "500.00",
|
|
|
|
|
|
"receiving_date": "2026-03-01",
|
|
|
|
|
|
"supplier": "○○철강",
|
|
|
|
|
|
"options": {
|
|
|
|
|
|
"inspection_status": "적",
|
|
|
|
|
|
"inspection_result": "합격"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 프론트엔드 사용법
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
// 원자재 재질은 code-map의 material_map에서 결정
|
|
|
|
|
|
const material = codeMap.material_map[`${prodCode}:${specCode}`];
|
|
|
|
|
|
// 예: 'SUS 1.2T', 'EGI 1.55T', '화이바원단'
|
|
|
|
|
|
|
|
|
|
|
|
// 해당 재질의 입고 LOT 목록 조회
|
|
|
|
|
|
const lots = await fetchMaterialLots(material);
|
|
|
|
|
|
// → 모달에서 사용자가 LOT 선택
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 취소 → 등록 복원
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
PATCH /api/v1/orders/{id}/status
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
기존 상태 변경 API를 사용한다. `CANCELLED → DRAFT` 전환이 허용된다.
|
|
|
|
|
|
|
|
|
|
|
|
### 요청
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"status": "DRAFT"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 상태 전환 규칙
|
|
|
|
|
|
|
|
|
|
|
|
| 현재 상태 | 가능한 전환 |
|
|
|
|
|
|
|----------|-----------|
|
|
|
|
|
|
| `DRAFT` | `CONFIRMED`, `CANCELLED` |
|
|
|
|
|
|
| `CONFIRMED` | `IN_PROGRESS`, `CANCELLED` |
|
|
|
|
|
|
| `IN_PROGRESS` | `COMPLETED`, `CANCELLED` |
|
|
|
|
|
|
| `COMPLETED` | (변경 불가) |
|
|
|
|
|
|
| **`CANCELLED`** | **`DRAFT` (복원)** |
|
|
|
|
|
|
|
|
|
|
|
|
### 프론트엔드 구현
|
|
|
|
|
|
|
|
|
|
|
|
취소 상태일 때 "수정" 버튼 또는 "복원" 버튼을 표시하고, 클릭 시 `updateStockOrderStatus(id, 'draft')`를 호출한다.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 담당자 기본값
|
|
|
|
|
|
|
|
|
|
|
|
STOCK 주문 생성 시 `options.manager_name`이 비어 있으면 **로그인 사용자 이름이 자동 설정**된다.
|
|
|
|
|
|
프론트엔드에서 별도 처리 불필요. 저장 후 응답에서 `manager_name`이 채워져 돌아온다.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 8. 재고생산 저장 (기존 API 확장)
|
2026-03-17 13:08:23 +09:00
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
POST /api/v1/orders
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
기존 수주 생성 API를 사용한다. `options.bending_lot`에 LOT 정보를 추가한다.
|
|
|
|
|
|
|
|
|
|
|
|
### 요청 예시
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"order_type_code": "STOCK",
|
|
|
|
|
|
"memo": "절곡품 재고생산",
|
|
|
|
|
|
"options": {
|
|
|
|
|
|
"production_reason": "절곡품 재고생산",
|
|
|
|
|
|
"target_stock_qty": 100,
|
|
|
|
|
|
"bending_lot": {
|
|
|
|
|
|
"lot_number": "GI6317-53-001",
|
|
|
|
|
|
"prod_code": "G",
|
|
|
|
|
|
"spec_code": "I",
|
|
|
|
|
|
"length_code": "53",
|
|
|
|
|
|
"raw_lot_no": "RM-20260301-001",
|
|
|
|
|
|
"fabric_lot_no": "FB-20260215-003",
|
|
|
|
|
|
"material": "화이바원단"
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
"items": [
|
|
|
|
|
|
{
|
|
|
|
|
|
"item_id": 15604,
|
|
|
|
|
|
"item_code": "BD-GI-53",
|
|
|
|
|
|
"item_name": "연기차단재 화이바원단 W50×3000",
|
|
|
|
|
|
"specification": "화이바원단",
|
|
|
|
|
|
"quantity": 100,
|
|
|
|
|
|
"unit": "EA",
|
|
|
|
|
|
"unit_price": 0
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### `options.bending_lot` 필드
|
|
|
|
|
|
|
|
|
|
|
|
| 필드 | 타입 | 필수 | 설명 |
|
|
|
|
|
|
|------|------|------|------|
|
|
|
|
|
|
| `lot_number` | string | O | 확정된 LOT 번호 (generate-lot API 결과) |
|
|
|
|
|
|
| `prod_code` | string | O | 제품 코드 |
|
|
|
|
|
|
| `spec_code` | string | O | 종류 코드 |
|
|
|
|
|
|
| `length_code` | string | O | 모양&길이 코드 |
|
|
|
|
|
|
| `raw_lot_no` | string | △ | 원자재(철판) LOT 번호 (선택) |
|
|
|
|
|
|
| `fabric_lot_no` | string | △ | 원단 LOT 번호 — 연기차단재(G)만 해당 (선택) |
|
|
|
|
|
|
| `material` | string | △ | 원자재 재질명 |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 프론트엔드 구현 가이드
|
|
|
|
|
|
|
|
|
|
|
|
### 6.1 화면 구성 (레거시 5130 참고)
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
┌──────────────────────────────────────────────┐
|
|
|
|
|
|
│ 절곡품 재고생산 등록 │
|
|
|
|
|
|
├──────────────────────────────────────────────┤
|
|
|
|
|
|
│ 등록일 [날짜피커] 작성자 [자동표시] │
|
|
|
|
|
|
│ │
|
|
|
|
|
|
│ 생산품 LOT [GI6317-53-001] (자동, readonly) │
|
|
|
|
|
|
│ │
|
|
|
|
|
|
│ 품목명 [Select ▾] 종류 [Select ▾] │
|
|
|
|
|
|
│ │
|
|
|
|
|
|
│ 모양&길이 [Select ▾] 수량 [숫자입력] │
|
|
|
|
|
|
│ │
|
|
|
|
|
|
│ 원자재(철판) LOT [선택 버튼 → 모달] │
|
|
|
|
|
|
│ 원단 LOT(연기차단재) [선택 버튼 → 모달] │
|
|
|
|
|
|
│ ↑ 품목이 G(연기차단재)일 때만 표시 │
|
|
|
|
|
|
│ │
|
|
|
|
|
|
│ 메모 [텍스트 입력] │
|
|
|
|
|
|
├──────────────────────────────────────────────┤
|
|
|
|
|
|
│ ← 목록 [저장] [취소] │
|
|
|
|
|
|
└──────────────────────────────────────────────┘
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 6.2 동작 흐름
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
1. 페이지 로드
|
|
|
|
|
|
└→ GET /bending/code-map 호출 → 드롭다운 옵션 세팅
|
|
|
|
|
|
|
|
|
|
|
|
2. 품목명 Select 변경
|
|
|
|
|
|
└→ specs 필터링: codeMap.specs.filter(s => s.products.includes(prod))
|
|
|
|
|
|
└→ lengths 결정: prod === 'G' ? smoke_barrier : general
|
|
|
|
|
|
└→ 종류/모양&길이 초기화
|
|
|
|
|
|
|
|
|
|
|
|
3. 종류 Select 변경
|
|
|
|
|
|
└→ LOT 프리뷰 갱신 (프론트 날짜코드 생성)
|
|
|
|
|
|
└→ material 결정: codeMap.material_map[`${prod}:${spec}`]
|
|
|
|
|
|
|
|
|
|
|
|
4. 모양&길이 Select 변경
|
|
|
|
|
|
└→ GET /bending/resolve-item?prod=&spec=&length= 호출
|
|
|
|
|
|
└→ 매핑된 품목 정보 표시 (또는 "매핑 없음" 안내)
|
|
|
|
|
|
|
|
|
|
|
|
5. 저장 버튼 클릭
|
|
|
|
|
|
└→ POST /bending/generate-lot 호출 → lot_number 확정
|
|
|
|
|
|
└→ POST /orders 호출 (STOCK + bending_lot + items)
|
|
|
|
|
|
└→ 상세 페이지로 이동
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 6.3 LOT 프리뷰 (프론트 날짜코드 생성)
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
function generateDateCode(date: Date): string {
|
|
|
|
|
|
const year = date.getFullYear() % 10;
|
|
|
|
|
|
const month = date.getMonth() + 1;
|
|
|
|
|
|
const day = date.getDate();
|
|
|
|
|
|
const monthCode = month >= 10
|
|
|
|
|
|
? String.fromCharCode(55 + month) // A=10, B=11, C=12
|
|
|
|
|
|
: String(month);
|
|
|
|
|
|
return `${year}${monthCode}${String(day).padStart(2, '0')}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 프리뷰: GI6317-53 (일련번호 제외)
|
|
|
|
|
|
const lotPreview = `${prodCode}${specCode}${generateDateCode(regDate)}-${lengthCode}`;
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 6.4 원자재/원단 LOT 선택
|
|
|
|
|
|
|
|
|
|
|
|
원자재 LOT 목록은 기존 재고 API를 활용한다:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
GET /api/v1/stock-lots?material={재질명}&status=available
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
> 이 엔드포인트가 아직 없으면 `stocks` 관련 API에서 item_name 검색으로 대체 가능하다.
|
|
|
|
|
|
|
|
|
|
|
|
### 6.5 상세 페이지 LOT 정보 표시
|
|
|
|
|
|
|
|
|
|
|
|
`StockProductionDetail.tsx`에서 `order.options.bending_lot`이 있으면 LOT 정보를 추가 표시한다:
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
const bendingLot = order.options?.bending_lot;
|
|
|
|
|
|
if (bendingLot) {
|
|
|
|
|
|
// 생산품 LOT: GI6317-53-001
|
|
|
|
|
|
// 원자재 LOT: RM-20260301-001
|
|
|
|
|
|
// 원단 LOT: FB-20260215-003
|
|
|
|
|
|
// 원자재: 화이바원단
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 기존 폼과의 관계
|
|
|
|
|
|
|
|
|
|
|
|
**기존 `StockProductionForm.tsx`를 전면 교체한다.**
|
|
|
|
|
|
|
|
|
|
|
|
- 기존: `ItemAddDialog`로 수동 품목 입력 (수주 폼 재활용)
|
|
|
|
|
|
- 변경: `BendingLotForm`으로 캐스케이딩 드롭다운 + LOT 자동 생성
|
|
|
|
|
|
|
|
|
|
|
|
일반 재고생산 모드는 고려하지 않는다. 재고생산 = 절곡품 LOT 입력으로 통일.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 관련 문서
|
|
|
|
|
|
|
|
|
|
|
|
- [재고생산 개편 기획서](../../dev/dev_plans/stock-production-lot-form-plan.md)
|
|
|
|
|
|
- [재고생산관리 기능 설명](../../features/sales/stock-production.md)
|
|
|
|
|
|
- [기존 재고생산 API 명세](stock-production-api.md)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-03-17 14:27:08 +09:00
|
|
|
|
**최종 업데이트**: 2026-03-17
|