# 재고생산관리 React 구현 요청서

> **작성일**: 2026-03-16
> **요청자**: R&D 실장
> **대상**: 프론트엔드 개발자
> **우선순위**: 🟡 중요
> **API 상태**: ✅ 구현 완료 (개발서버 배포됨)

---

## 1. 개요

수주 없이 **재고 목적으로 생산**하는 경우를 관리하는 메뉴를 추가한다.
기존 수주관리 API를 그대로 사용하며, `order_type_code = 'STOCK'`으로 구분한다.

### 1.1 구현 대상

| 메뉴 | 위치 | 설명 | 난이도 |
|------|------|------|:------:|
| **재고생산관리** | 판매관리 > 재고생산관리 | 재고생산 등록/목록/상세/수정/삭제 | **낮음** (수주 화면 복제 후 단순화) |

### 1.2 참고 문서

| 문서 | 경로 | 용도 |
|------|------|------|
| **API 명세** (필독) | `docs/frontend/api-specs/stock-production-api.md` | 전체 엔드포인트, 요청/응답 형식 |
| 기능 설명 | `docs/features/sales/stock-production.md` | 비즈니스 개념, 수주와의 관계 |

### 1.3 핵심 원칙

```
✅ 수주관리 화면을 복제한 뒤 불필요한 필드 제거
✅ API는 기존 /api/v1/orders 그대로 사용 (order_type=STOCK 필터)
✅ 생성 시 order_type_code: 'STOCK' 필수 전송
❌ 별도 API 엔드포인트 없음
❌ 거래처, 견적, 배송, 할인, 개소(Node) 관련 UI 불필요
```

---

## 2. 파일 구조 (제안)

기존 수주관리 구조를 따른다.

```
src/
├── app/[locale]/(protected)/sales/order-management-sales/
│   └── stocks/                              # 재고생산관리 (신규)
│       ├── page.tsx                         # 목록 페이지
│       └── [id]/
│           ├── page.tsx                     # 상세 페이지
│           └── production-order/
│               └── page.tsx                 # 생산지시 생성 페이지
│
├── components/orders/
│   └── StockProductionRegistration.tsx      # 재고생산 등록/수정 폼 (신규)
│   └── (기존 actions.ts에 함수 추가 또는 별도 stockActions.ts)
```

> **대안**: `stocks/` 대신 기존 수주관리 페이지에서 `order_type` 탭으로 분리하는 방식도 가능. 실장 판단에 따름.

---

## 3. 화면별 구현 가이드

### 3.1 재고생산 목록 페이지

**경로**: `/sales/order-management-sales/stocks`

**수주관리 목록 페이지를 복제**한 뒤 다음을 변경:

| 항목 | 수주관리 (현재) | 재고생산 (변경) |
|------|---------------|---------------|
| 페이지 제목 | 수주관리 | **재고생산관리** |
| API 호출 | `getOrders()` | `getOrders({ order_type: 'STOCK' })` |
| 통계 API | `getOrderStats()` | `getOrderStats({ order_type: 'STOCK' })` → `GET /api/v1/orders/stats?order_type=STOCK` |
| 표시 컬럼 | 수주번호, 거래처, 현장명, 수량, 납기, 금액... | **생산번호, 품목, 수량, 생산사유, 등록일, 상태** |
| 통계 카드 | 이번달 수주금액, 분할대기... | 전체, 등록, 확정, 진행중, 완료 (또는 간소화) |

**목록 테이블 컬럼**:

| 컬럼 | 데이터 | 비고 |
|------|--------|------|
| 번호 | 글로벌 인덱스 | |
| 생산번호 | `order_no` (STK...) | 배지 스타일 |
| 품목 | 대표 `items[0].item_name` + (외 N건) | |
| 수량 | 총 수량 | |
| 생산 사유 | `options.production_reason` | 없으면 `-` |
| 등록일 | `created_at` | YYYY-MM-DD |
| 상태 | `status_code` | 배지 (수주와 동일 색상) |
| 작업 | 상세보기, 삭제 | |

**제거할 컬럼**: 거래처, 현장명, 납기, 금액

### 3.2 재고생산 등록/수정 폼

**수주 등록 폼(`OrderRegistration.tsx`)을 복제**한 뒤 다음을 변경:

#### 제거할 섹션

```
❌ 거래처 선택 (client_id, client_name, client_contact)
❌ 현장명 (site_name) — API가 '재고생산'으로 자동 설정
❌ 견적 선택 (quote_id) / 견적에서 가져오기
❌ 배송 정보 (delivery_date, delivery_method_code)
❌ 운임비용 (options.shipping_cost_code)
❌ 수신자 정보 (options.receiver, receiver_contact, shipping_address)
❌ 할인 (discount_rate, discount_amount)
❌ 금액 계산 (supply_amount, tax_amount, total_amount)
❌ 매출 인식 (sales_recognition)
❌ 개소/구역 (OrderNode) 트리 구조
```

#### 유지할 섹션

```
✅ 생산 사유 (options.production_reason) — 텍스트 입력
✅ 목표 재고 수량 (options.target_stock_qty) — 숫자 입력
✅ 비고 (memo) — 텍스트 입력
✅ 품목 목록 (items[]) — 품목 선택 + 수량 입력
```

#### 품목 입력 테이블

| 필드 | 타입 | 필수 | 비고 |
|------|------|:----:|------|
| 품목 | 품목 선택 (ItemAddDialog) | ✅ | item_id, item_name, item_code |
| 규격 | 텍스트 | - | specification |
| 수량 | 숫자 | ✅ | quantity |
| 단위 | 텍스트 | - | unit (기본: EA) |

> **단가/금액은 불필요**하지만, API validation에서 `unit_price`가 required이므로 `0`을 전송

#### API 요청 예시

```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"
    }
  ]
}
```

### 3.3 재고생산 상세 페이지

**수주 상세(`OrderSalesDetailView.tsx`)를 복제**한 뒤 단순화:

| 섹션 | 표시 |
|------|------|
| 생산번호 (order_no) | ✅ |
| 상태 (status_code) | ✅ 배지 |
| 생산 사유 | ✅ `options.production_reason` |
| 목표 재고 수량 | ✅ `options.target_stock_qty` |
| 비고 | ✅ `memo` |
| 품목 목록 | ✅ 테이블 (품목명, 규격, 수량) |
| 거래처/현장/납기/금액 | ❌ 제거 |
| 개소/구역 트리 | ❌ 제거 |

**액션 버튼**:
- 수정 (DRAFT 상태만)
- 삭제 (DRAFT 상태만)
- 확정 (`PATCH /api/v1/orders/{id}/status` → `{ "status": "CONFIRMED" }`)
- 생산지시 생성 (CONFIRMED 상태만) → 기존 생산지시 생성 페이지 재사용

### 3.4 생산지시 생성 페이지

**기존 `[id]/production-order/page.tsx`를 재사용** 가능.

STOCK 수주의 생산지시는 API가 자동 처리하므로 프론트에서 특별한 분기 불필요:

| 항목 | API 자동 처리 |
|------|-------------|
| 공정 선택 | 절곡 공정 자동 선택 (process_ids 전달 불필요) |
| 현장명 | `'재고생산'` 고정 |
| 작업예정일 | `now()` 자동 (scheduled_date 전달 불필요) |

> 단, 공정 매칭 미리보기 UI에서 STOCK 수주가 BOM 없이도 "절곡" 공정으로 표시되도록 조건 분기 필요할 수 있음.

### 3.5 생산지시 목록 — STOCK 건 표시 (기존 페이지 수정)

**경로**: `/sales/order-management-sales/production-orders/page.tsx`

STOCK 타입 재고생산의 생산지시도 이 목록에 표시된다. 변경 필요 사항:

| 컬럼 | 현재 | STOCK 건 표시 |
|------|------|-------------|
| 현장명 | `siteName` | `'재고생산'` (API가 자동 설정하므로 변경 불필요) |
| 거래처 | `clientName` | 빈 값 또는 `-` |
| 납기 | `deliveryDate` | `-` 표시 (STOCK은 delivery_date 없음) |
| 생산지시일 | `productionOrderedAt` | 정상 표시 |

**구현 방법**: API 응답에 `order_type_code`가 이미 포함됨. 프론트 types에 추가:

```typescript
// types.ts 수정
interface ApiProductionOrder {
  // ... 기존 필드
  order_type_code?: string;  // 추가
}

// transform 함수에서
orderTypeCode: data.order_type_code || 'ORDER',
```

테이블 렌더링에서:

```typescript
// 납기 컬럼
{item.orderTypeCode === 'STOCK' ? '-' : item.deliveryDate}

// 거래처 컬럼
{item.orderTypeCode === 'STOCK' ? '-' : item.clientName}
```

---

## 4. 메뉴 등록

메뉴 위치:

```
판매관리
├── 거래처관리
├── 견적관리
├── 수주관리
├── 재고생산관리  ← 신규 (수주관리 아래)
└── 단가관리
```

> 메뉴 등록은 MNG 메뉴 동기화 기능으로 별도 처리. 프론트에서는 라우트만 구현.

---

## 5. 수주관리와의 차이 요약

```
┌─ 수주관리 ──────────────────┐    ┌─ 재고생산관리 ───────────────┐
│                              │    │                              │
│ 거래처 선택                  │    │ 생산 사유 (텍스트)           │
│ 현장명                       │    │ 목표 재고 수량              │
│ 견적 연결                    │    │ 비고                        │
│ 배송/납기/운임               │    │                              │
│ 할인/금액 계산               │    ├──────────────────────────────┤
│ 매출 인식 방식               │    │ 품목 목록                   │
│                              │    │  - 품목 선택                │
│ 개소/구역 트리 (OrderNode)   │    │  - 수량만 입력              │
│ 품목 목록 (상세)             │    │  (단가/금액/할인 불필요)    │
│  - 단가, 할인, 금액 계산     │    │  (개소/구역 불필요)         │
│  - floor_code, symbol_code   │    │                              │
│                              │    └──────────────────────────────┘
└──────────────────────────────┘
```

---

## 6. API 빠른 참조

### 6.1 목록 조회

```
GET /api/v1/orders?order_type=STOCK&page=1&size=20
```

### 6.2 통계

```
GET /api/v1/orders/stats?order_type=STOCK
```

### 6.3 생성

```
POST /api/v1/orders
Content-Type: application/json

{
  "order_type_code": "STOCK",
  "memo": "...",
  "options": { "production_reason": "...", "target_stock_qty": 500 },
  "items": [{ "item_name": "...", "quantity": 100, "unit_price": 0 }]
}
```

### 6.4 상태 변경

```
PATCH /api/v1/orders/{id}/status
{ "status": "CONFIRMED" }
```

### 6.5 생산지시 생성

```
POST /api/v1/orders/{id}/production-order
{ "priority": "normal" }
```

> 공정/예정일은 API가 자동 처리 (절곡 공정, scheduled_date=now())

### 6.6 수정/삭제

```
PUT /api/v1/orders/{id}     — 수정
DELETE /api/v1/orders/{id}  — 삭제
```

---

## 7. 구현 체크리스트

- [ ] `stocks/page.tsx` — 재고생산 목록 페이지
- [ ] `stocks/[id]/page.tsx` — 재고생산 상세 페이지
- [ ] `StockProductionRegistration.tsx` — 등록/수정 폼 (수주 폼 단순화)
- [ ] Server Actions — `getOrders({ order_type: 'STOCK' })` 등 (기존 actions.ts 활용)
- [ ] 생산지시 목록 — STOCK 건 납기 `-` 표시, `order_type_code` 타입 추가
- [ ] 메뉴 라우트 등록

---

## 관련 문서

- [API 명세 (상세)](../frontend/api-specs/stock-production-api.md)
- [기능 설명](../features/sales/stock-production.md)
- [개발 변경이력](../dev/changes/20260316_stock_production_order.md)

---

**최종 업데이트**: 2026-03-16
