docs: [plans] 재고생산 기획 결정 사항 반영
- LOT 일련번호 suffix 전략 확정 (-001, -002) - items 매핑: 매핑 테이블(bending_item_mappings) 확정 - 일반 재고생산 모드 분기 제거 (절곡품 전용)
This commit is contained in:
@@ -30,16 +30,17 @@
|
||||
### 2.1 구조
|
||||
|
||||
```
|
||||
[제품코드][종류코드][날짜코드]-[모양&길이코드]
|
||||
1자리 1자리 4자리 2자리
|
||||
[제품코드][종류코드][날짜코드]-[모양&길이코드]-[일련번호]
|
||||
1자리 1자리 4자리 2자리 3자리
|
||||
|
||||
예시: GI6C17-53
|
||||
G = 연기차단재
|
||||
I = 화이바원단
|
||||
6 = 2026년
|
||||
C = 12월
|
||||
17 = 17일
|
||||
53 = W50 × 3000
|
||||
예시: GI6317-53-001
|
||||
G = 연기차단재
|
||||
I = 화이바원단
|
||||
6 = 2026년
|
||||
3 = 3월
|
||||
17 = 17일
|
||||
53 = W50 × 3000
|
||||
001 = 일련번호 (같은 날 같은 조합의 순번)
|
||||
```
|
||||
|
||||
### 2.2 날짜 코드 (4자리)
|
||||
@@ -249,8 +250,7 @@ GET /api/v1/bending/resolve-item?prod={prodCode}&spec={specCode}&length={lengthC
|
||||
}
|
||||
```
|
||||
|
||||
**매핑 로직**: `item_category = 'BENDING'` + `options->prefix` + `options->length_code`로 검색한다.
|
||||
매핑 테이블이 없으면 코드 규칙 기반으로 유추한다.
|
||||
**매핑 로직**: `bending_item_mappings` 테이블에서 `prod_code + spec_code + length_code → item_id`로 조회한다.
|
||||
|
||||
#### 4.1.3 원자재 LOT 목록 조회
|
||||
|
||||
@@ -313,12 +313,54 @@ GET /api/v1/stock-lots?material={materialName}&status=available
|
||||
'options.bending_lot.fabric_lot_no' => 'nullable|string|max:50',
|
||||
```
|
||||
|
||||
### 4.3 백엔드 파일 목록
|
||||
### 4.3 LOT 일련번호 생성 (백엔드)
|
||||
|
||||
같은 날 같은 조합의 LOT가 여러 건 등록될 수 있으므로, 저장 시 백엔드에서 일련번호를 부여한다.
|
||||
|
||||
```php
|
||||
// BendingCodeService::generateLotNumber()
|
||||
public function generateLotNumber(string $base): string
|
||||
{
|
||||
// base = 'GI6317-53'
|
||||
// orders.options->bending_lot->lot_number 에서 같은 base로 시작하는 건 수 조회
|
||||
$count = Order::where('tenant_id', $this->tenantId())
|
||||
->where('order_type_code', Order::TYPE_STOCK)
|
||||
->where('options->bending_lot->lot_number', 'LIKE', $base . '-%')
|
||||
->count();
|
||||
|
||||
$seq = str_pad($count + 1, 3, '0', STR_PAD_LEFT);
|
||||
return "{$base}-{$seq}"; // GI6317-53-001
|
||||
}
|
||||
```
|
||||
|
||||
### 4.4 매핑 테이블 마이그레이션
|
||||
|
||||
```php
|
||||
// bending_item_mappings 테이블
|
||||
Schema::create('bending_item_mappings', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('tenant_id');
|
||||
$table->string('prod_code', 2)->comment('제품코드: R,S,G,B,T,L,C');
|
||||
$table->string('spec_code', 2)->comment('종류코드: M,S,I,E...');
|
||||
$table->string('length_code', 2)->comment('모양&길이코드: 53,42...');
|
||||
$table->unsignedBigInteger('item_id')->comment('매핑된 품목 ID');
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['tenant_id', 'prod_code', 'spec_code', 'length_code']);
|
||||
$table->foreign('item_id')->references('id')->on('items');
|
||||
$table->foreign('tenant_id')->references('id')->on('tenants');
|
||||
});
|
||||
```
|
||||
|
||||
### 4.5 백엔드 파일 목록
|
||||
|
||||
| 파일 | 작업 | 설명 |
|
||||
|------|------|------|
|
||||
| `app/Http/Controllers/Api/V1/BendingController.php` | 신규 | 코드맵, 품목매핑 API |
|
||||
| `app/Services/BendingCodeService.php` | 신규 | 코드 체계 관리, 품목 매핑 로직 |
|
||||
| `app/Http/Controllers/Api/V1/BendingController.php` | 신규 | 코드맵, 품목매핑, LOT 채번 API |
|
||||
| `app/Services/BendingCodeService.php` | 신규 | 코드 체계 관리, 품목 매핑, LOT 일련번호 생성 |
|
||||
| `app/Models/Production/BendingItemMapping.php` | 신규 | 매핑 테이블 모델 |
|
||||
| `database/migrations/xxx_create_bending_item_mappings_table.php` | 신규 | 매핑 테이블 마이그레이션 |
|
||||
| `app/Http/Requests/Order/StoreOrderRequest.php` | 수정 | bending_lot validation 추가 |
|
||||
| `app/Http/Requests/Order/UpdateOrderRequest.php` | 수정 | 동일 |
|
||||
| `routes/api/v1/production.php` | 수정 | bending 라우트 추가 |
|
||||
@@ -330,14 +372,14 @@ GET /api/v1/stock-lots?material={materialName}&status=available
|
||||
|
||||
### 5.1 컴포넌트 구조
|
||||
|
||||
> 일반 재고생산은 고려하지 않는다. 재고생산 = 절곡품 LOT 입력으로 통일한다.
|
||||
|
||||
```
|
||||
src/components/stocks/
|
||||
├── StockProductionList.tsx # 기존 (목록)
|
||||
├── StockProductionDetail.tsx # 기존 (상세)
|
||||
├── StockProductionForm.tsx # 수정: 모드 분기
|
||||
│ # - mode='order': 기존 수주형 입력
|
||||
│ # - mode='bending': 절곡품 LOT 입력 (신규)
|
||||
├── BendingLotForm.tsx # 신규: 절곡품 LOT 등록 폼
|
||||
├── StockProductionDetail.tsx # 기존 (상세) — LOT 정보 표시 추가
|
||||
├── StockProductionForm.tsx # 전면 교체: BendingLotForm 기반
|
||||
├── BendingLotForm.tsx # 신규: 절곡품 LOT 등록 폼 (핵심)
|
||||
├── RawMaterialLotModal.tsx # 신규: 원자재 LOT 선택 모달
|
||||
├── FabricLotModal.tsx # 신규: 원단 LOT 선택 모달
|
||||
└── actions.ts # 수정: bending API 함수 추가
|
||||
@@ -360,11 +402,13 @@ useEffect(() => {
|
||||
setLengthCode('');
|
||||
}, [prodCode]);
|
||||
|
||||
// LOT 번호 자동 생성
|
||||
// LOT 번호 자동 생성 (일련번호는 백엔드에서 부여)
|
||||
// 프론트에서는 프리뷰용으로 base 부분만 표시
|
||||
useEffect(() => {
|
||||
if (prodCode && specCode && lengthCode && regDate) {
|
||||
const dateCode = generateDateCode(regDate);
|
||||
setLotNumber(`${prodCode}${specCode}${dateCode}-${lengthCode}`);
|
||||
setLotNumberBase(`${prodCode}${specCode}${dateCode}-${lengthCode}`);
|
||||
// 실제 LOT: GI6317-53-001 (suffix는 저장 시 API가 부여)
|
||||
}
|
||||
}, [prodCode, specCode, lengthCode, regDate]);
|
||||
|
||||
@@ -421,9 +465,10 @@ function transformToStockOrder(form: BendingLotFormData): StockOrderFormData {
|
||||
| `src/components/stocks/BendingLotForm.tsx` | 신규 | 절곡품 LOT 등록 폼 |
|
||||
| `src/components/stocks/RawMaterialLotModal.tsx` | 신규 | 원자재 LOT 선택 모달 |
|
||||
| `src/components/stocks/FabricLotModal.tsx` | 신규 | 원단 LOT 선택 모달 |
|
||||
| `src/components/stocks/StockProductionForm.tsx` | 수정 | 절곡품/일반 모드 분기 |
|
||||
| `src/components/stocks/StockProductionForm.tsx` | 전면 교체 | BendingLotForm 기반으로 교체 |
|
||||
| `src/components/stocks/StockProductionDetail.tsx` | 수정 | LOT 정보(bending_lot) 표시 추가 |
|
||||
| `src/components/stocks/actions.ts` | 수정 | bending API 함수 추가 |
|
||||
| `src/app/[locale]/(protected)/sales/stocks/page.tsx` | 수정 | `?mode=new-bending` 라우트 추가 |
|
||||
| `src/app/[locale]/(protected)/sales/stocks/page.tsx` | 수정 | 신규 등록 시 BendingLotForm 사용 |
|
||||
|
||||
---
|
||||
|
||||
@@ -456,19 +501,21 @@ function transformToStockOrder(form: BendingLotFormData): StockOrderFormData {
|
||||
|
||||
### Phase 1: 백엔드 API (API 프로젝트)
|
||||
|
||||
1. `BendingCodeService` — 코드 체계 관리 서비스
|
||||
2. `BendingController` — 코드맵 조회 + 품목 매핑 API
|
||||
3. `StoreOrderRequest` 수정 — bending_lot validation
|
||||
4. 라우트 등록 + Swagger 문서
|
||||
1. `bending_item_mappings` 마이그레이션 + 모델
|
||||
2. `BendingCodeService` — 코드 체계 관리, 품목 매핑, LOT 일련번호 생성
|
||||
3. `BendingController` — 코드맵 조회 + 품목 매핑 + LOT 채번 API
|
||||
4. `StoreOrderRequest` / `UpdateOrderRequest` 수정 — bending_lot validation
|
||||
5. 라우트 등록 + Swagger 문서
|
||||
6. 매핑 데이터 시딩 (기존 `BD-*` 품목과 연결)
|
||||
|
||||
### Phase 2: 프론트엔드 (React 프로젝트)
|
||||
|
||||
1. `actions.ts` — bending API 함수 추가
|
||||
2. `BendingLotForm.tsx` — 절곡품 LOT 등록 폼
|
||||
2. `BendingLotForm.tsx` — 절곡품 LOT 등록 폼 (핵심)
|
||||
3. `RawMaterialLotModal.tsx` — 원자재 LOT 선택
|
||||
4. `FabricLotModal.tsx` — 원단 LOT 선택
|
||||
5. `StockProductionForm.tsx` 수정 — 모드 분기
|
||||
6. 페이지 라우트 수정
|
||||
5. `StockProductionForm.tsx` — BendingLotForm 기반으로 전면 교체
|
||||
6. `StockProductionDetail.tsx` — LOT 정보 표시 추가
|
||||
|
||||
### Phase 3: 연동 검증
|
||||
|
||||
@@ -479,34 +526,15 @@ function transformToStockOrder(form: BendingLotFormData): StockOrderFormData {
|
||||
|
||||
---
|
||||
|
||||
## 8. 검토 사항
|
||||
## 8. 확정 결정 사항
|
||||
|
||||
### 8.1 결정 필요
|
||||
|
||||
| 항목 | 질문 | 제안 |
|
||||
| 항목 | 결정 | 비고 |
|
||||
|------|------|------|
|
||||
| **LOT 중복** | 동일 LOT 번호가 생길 수 있는가? (같은 날 같은 조합) | 일련번호 suffix 추가 (`GI6317-53-001`) 또는 하루에 한 건만 허용 |
|
||||
| **items 매핑** | 모든 제품-종류-길이 조합에 대응하는 품목이 items에 존재하는가? | BendingItemSeeder로 미리 생성, 없으면 자동 생성 |
|
||||
| **모양&길이 확장** | 새 길이 규격이 추가되면? | API 코드맵에서 관리, DB classifications 테이블 활용 가능 |
|
||||
| **일반 재고생산** | 절곡품 외 다른 재고생산도 있는가? | 기존 폼 유지, 등록 시 "절곡품/일반" 선택 |
|
||||
| **원자재 LOT 필수** | 원자재 LOT 입력은 필수인가? | 레거시에서는 선택 사항, SAM에서도 선택 권장 |
|
||||
|
||||
### 8.2 items 테이블 매핑 전략
|
||||
|
||||
현재 `items` 테이블에 `BD-*` 접두사로 절곡 품목이 등록되어 있다.
|
||||
모든 제품-종류-길이 조합에 대응하는 품목이 존재하지 않을 수 있다.
|
||||
|
||||
**전략 A (권장)**: 매핑 테이블 사용
|
||||
- `bending_item_mappings` 테이블 신규: `prod_code, spec_code, length_code → item_id`
|
||||
- 관리자가 MNG에서 매핑 관리
|
||||
|
||||
**전략 B**: 코드 규칙 기반 유추
|
||||
- `BD-{prodPrefix}{specCode}-{lengthCode}` 패턴으로 items 검색
|
||||
- 예: prod=R, spec=M, length=42 → `BD-RM-42` 검색
|
||||
|
||||
**전략 C**: 품목 자동 등록
|
||||
- 매핑되는 품목이 없으면 items에 자동 생성
|
||||
- 품목명: `{제품명} {종류명} {길이}mm`
|
||||
| **LOT 중복** | 일련번호 suffix 사용 (`-001`, `-002`...) | 같은 날 같은 조합이면 순번 증가. 백엔드에서 자동 부여 |
|
||||
| **items 매핑** | **전략 A: 매핑 테이블** (`bending_item_mappings`) | `prod_code + spec_code + length_code → item_id` |
|
||||
| **일반 재고생산** | 고려하지 않음 | 재고생산 = 절곡품 LOT 입력으로 통일. 모드 분기 불필요 |
|
||||
| **모양&길이 확장** | API 코드맵에서 관리 | 추후 DB `classifications` 테이블 활용 가능 |
|
||||
| **원자재 LOT** | 선택 사항 (nullable) | 레거시와 동일하게 선택 권장 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user