- 완료된 계획 문서 12개 → plans/archive/ 이동 - 완료된 하위 계획 2개 → plans/sub/archive/ 이동 - 새 계획 문서 추가: - 5130-bom-migration-plan.md (완료) - 5130-sam-data-migration-plan.md (완료) - bidding-api-implementation-plan.md (완료) - dashboard-api-integration-plan.md - order-workorder-shipment-integration-plan.md - dev-toolbar-plan.md - AI 리포트 키워드 색상체계 가이드 v1.4 추가 - index_plans.md 업데이트
446 lines
17 KiB
Markdown
446 lines
17 KiB
Markdown
# 5130 → SAM BOM 데이터 마이그레이션 계획
|
|
|
|
> **작성일**: 2025-01-20
|
|
> **목적**: 5130 레거시 시스템의 BOM 데이터를 SAM items 테이블의 bom 컬럼에 마이그레이션
|
|
> **기준 문서**: `api/app/Services/Quote/FormulaEvaluatorService.php`
|
|
> **상태**: ✅ 완료 (Serena ID: 5130-bom-migration-state)
|
|
|
|
---
|
|
|
|
## 📍 현재 진행 상태
|
|
|
|
| 항목 | 내용 |
|
|
|------|------|
|
|
| **마지막 완료 작업** | BOM 마이그레이션 실행 완료 (61건) |
|
|
| **다음 작업** | 견적 페이지에서 실제 테스트 (사용자 수동 확인) |
|
|
| **진행률** | 4/4 (100%) |
|
|
| **마지막 업데이트** | 2025-01-20 |
|
|
|
|
---
|
|
|
|
## 1. 개요
|
|
|
|
### 1.1 배경
|
|
|
|
5130 레거시 시스템에서 SAM으로 품목(items) 마이그레이션이 완료되었으나, 완제품(FG)의 BOM 데이터가 마이그레이션되지 않아 다음 문제가 발생:
|
|
|
|
```
|
|
문제 현상:
|
|
- 견적 페이지에서 "국민방화스크린 (일체형) (S0001)" 선택 후 자동 견적 산출 → 합계 0원
|
|
- 원인: S0001의 bom 컬럼이 NULL
|
|
- items 테이블에서 확인: SELECT bom FROM items WHERE code = 'S0001' → NULL
|
|
```
|
|
|
|
**기존 마이그레이션 상태:**
|
|
- Items: 608건 (KDunitprice → items)
|
|
- Orders: 24,424건
|
|
- Order Items: 43,900건
|
|
- ❌ BOM 데이터: 마이그레이션 안됨
|
|
|
|
### 1.2 기준 원칙
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ 🎯 핵심 원칙 │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ 1. FormulaEvaluatorService 호환 BOM JSON 형식 생성 │
|
|
│ 2. 동적 수량 계산을 위한 quantityFormula 필드 지원 │
|
|
│ 3. childItemCode 기반 참조 (child_item_id 아님) │
|
|
│ 4. 기존 SAM BOM 패턴과 일관성 유지 │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### 1.3 변경 승인 정책
|
|
|
|
| 분류 | 예시 | 승인 |
|
|
|------|------|------|
|
|
| ✅ 즉시 가능 | BOM JSON 데이터 추가, 매핑 테이블 생성 | 불필요 |
|
|
| ⚠️ 컨펌 필요 | 기존 items 데이터 수정, 새 마이그레이션 스크립트 | **필수** |
|
|
| 🔴 금지 | items 테이블 구조 변경, 기존 BOM 삭제 | 별도 협의 |
|
|
|
|
### 1.4 준수 규칙
|
|
- `docs/quickstart/quick-start.md` - 빠른 시작 가이드
|
|
- `docs/standards/quality-checklist.md` - 품질 체크리스트
|
|
- `api/app/Services/Quote/FormulaEvaluatorService.php` - BOM 계산 로직
|
|
|
|
---
|
|
|
|
## 2. 데이터 구조 분석
|
|
|
|
### 2.1 5130 BOM 구조
|
|
|
|
```
|
|
5130 DB (chandj)
|
|
├── KDunitprice (품목 마스터)
|
|
│ ├── prodcode: 품목 코드
|
|
│ ├── item_name: 품목명
|
|
│ └── item_div: [제품], [상품], [부재료], [원재료], [반제품]
|
|
│
|
|
├── models (모델 마스터)
|
|
│ ├── model_id: PK
|
|
│ ├── model_name: KSS01, KSE01, KWE01... (모델 코드)
|
|
│ ├── major_category: 스크린 | 철재
|
|
│ ├── finishing_type: SUS마감 | EGI마감
|
|
│ └── guiderail_type: 벽면형 | 측면형
|
|
│
|
|
├── parts (1단계 BOM - 모델별 부품)
|
|
│ ├── part_id: PK
|
|
│ ├── model_id: FK → models
|
|
│ ├── part_name: 가이드레일, 하단마감재 등
|
|
│ ├── spec: 120*70, 60*40 등
|
|
│ ├── quantity: 수량
|
|
│ ├── unit: SET, EA 등
|
|
│ └── unitprice: 단가 (문자열, 콤마 포함)
|
|
│
|
|
└── parts_sub (2단계 BOM - 부품별 원자재)
|
|
├── subpart_id: PK
|
|
├── part_id: FK → parts
|
|
├── subpart_name: 1번(마감제), 2번(본체) 등
|
|
├── material: SUS 1.2T, EGI 1.55T 등
|
|
├── quantity: 수량
|
|
├── bendSum, plateSum, finalSum: 가공 관련
|
|
└── unitPrice, computedPrice, lineTotal: 금액
|
|
```
|
|
|
|
**5130 model_id별 데이터 현황:**
|
|
| model_id | model_name | category | finishing | guiderail | parts 수 |
|
|
|----------|------------|----------|-----------|-----------|----------|
|
|
| 12 | KSS01 | 스크린 | SUS마감 | 벽면형 | 2 |
|
|
| 13 | KSS01 | 스크린 | SUS마감 | 측면형 | 2 |
|
|
| 14 | KSE01 | 스크린 | SUS마감 | 벽면형 | 2 |
|
|
| ... | ... | ... | ... | ... | ... |
|
|
|
|
**5130 KDunitprice item_div 분포:**
|
|
| item_div | 건수 | SAM item_type 매핑 |
|
|
|----------|------|-------------------|
|
|
| [제품] | 194건 | FG (완제품) |
|
|
| [상품] | 260건 | SM (부자재) |
|
|
| [부재료] | 48건 | SM (부자재) |
|
|
| [원재료] | 24건 | RM (원자재) |
|
|
| [반제품] | 73건 | SF (반제품) |
|
|
| [무형상품] | 4건 | CS (서비스) |
|
|
|
|
### 2.2 SAM BOM 구조
|
|
|
|
```sql
|
|
-- SAM items 테이블 BOM 컬럼
|
|
items.bom: JSON
|
|
```
|
|
|
|
**SAM BOM JSON 형식 (FormulaEvaluatorService 호환):**
|
|
```json
|
|
[
|
|
{
|
|
"childItemCode": "SF-SCR-F01", // 필수: 하위 품목 코드
|
|
"quantity": 1, // 필수: 기본 수량
|
|
"quantityFormula": "W*H/1000000", // 선택: 동적 수량 계산식
|
|
"unit": "M2", // 선택: 단위
|
|
"note": "스크린 원단" // 선택: 비고
|
|
},
|
|
{
|
|
"childItemCode": "SF-SCR-M01",
|
|
"quantity": 1,
|
|
"quantityFormula": "",
|
|
"unit": "EA",
|
|
"note": "소형용 모터"
|
|
}
|
|
]
|
|
```
|
|
|
|
**기존 SAM BOM 예시 (FG-SCR-001):**
|
|
```json
|
|
[
|
|
{"unit":"M2","quantity":1,"childItemCode":"SF-SCR-F01","quantityFormula":"W*H/1000000"},
|
|
{"unit":"M","quantity":1,"childItemCode":"SF-SCR-F02","quantityFormula":"H/1000"},
|
|
{"unit":"EA","quantity":1,"childItemCode":"SF-SCR-M01","quantityFormula":"","note":"소형용"},
|
|
{"unit":"EA","quantity":20,"childItemCode":"SM-B002","quantityFormula":"","note":"조립용"}
|
|
]
|
|
```
|
|
|
|
### 2.3 핵심 차이점
|
|
|
|
| 항목 | 5130 | SAM |
|
|
|------|------|-----|
|
|
| **BOM 저장 위치** | parts/parts_sub 테이블 | items.bom JSON 컬럼 |
|
|
| **연결 기준** | model_id (모델 기준) | childItemCode (품목 코드 기준) |
|
|
| **수량 계산** | 고정값 + estimate.detailJson | quantityFormula 동적 계산 |
|
|
| **단가 계산** | parts.unitprice 고정 | FormulaEvaluatorService 동적 |
|
|
| **계층 구조** | 2단계 (parts → parts_sub) | 1단계 (flat JSON array) |
|
|
|
|
---
|
|
|
|
## 3. 마이그레이션 전략
|
|
|
|
### 3.1 접근 방식: 수동 매핑 + 템플릿 기반
|
|
|
|
5130의 BOM 구조와 SAM의 BOM 구조가 근본적으로 다르기 때문에, 자동 변환이 아닌 **수동 매핑 + 템플릿 기반** 접근 필요:
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ 전략: 완제품(FG) 유형별 BOM 템플릿 정의 │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ 1. SCREEN 완제품 → screen_bom_template │
|
|
│ 2. STEEL 완제품 → steel_bom_template │
|
|
│ 3. BENDING 완제품 → bending_bom_template │
|
|
│ │
|
|
│ 각 템플릿은 FormulaEvaluatorService 호환 JSON 형식으로 정의 │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### 3.2 완제품-모델 매핑
|
|
|
|
**매핑 대상 (SAM items WHERE item_type='FG' AND source='5130'):**
|
|
```sql
|
|
-- SAM에서 5130에서 마이그레이션된 완제품 목록
|
|
SELECT id, code, name, item_category
|
|
FROM items
|
|
WHERE item_type = 'FG'
|
|
AND (legacy_code IS NOT NULL OR code LIKE 'S%');
|
|
```
|
|
|
|
**주요 완제품 매핑 예시:**
|
|
| SAM code | SAM name | item_category | 5130 model |
|
|
|----------|----------|---------------|------------|
|
|
| S0001 | 국민방화스크린(일체형) | SCREEN | KSS01 (스크린/SUS/벽면형) |
|
|
| S0002 | 국민방화스크린(분리형) | SCREEN | KSE01 (스크린/SUS/벽면형) |
|
|
| ... | ... | ... | ... |
|
|
|
|
### 3.3 BOM 템플릿 정의
|
|
|
|
**SCREEN 완제품 BOM 템플릿:**
|
|
```json
|
|
[
|
|
{"childItemCode": "RM-SCR-FABRIC", "quantity": 1, "quantityFormula": "W*H/1000000", "unit": "M2", "note": "스크린 원단"},
|
|
{"childItemCode": "PT-SCR-GUIDE", "quantity": 1, "quantityFormula": "H/1000", "unit": "M", "note": "가이드레일"},
|
|
{"childItemCode": "PT-SCR-BOTTOM", "quantity": 1, "quantityFormula": "W/1000", "unit": "M", "note": "하단바"},
|
|
{"childItemCode": "PT-SCR-CASE", "quantity": 1, "quantityFormula": "W/1000", "unit": "M", "note": "케이스"},
|
|
{"childItemCode": "PT-SCR-MOTOR", "quantity": 1, "quantityFormula": "", "unit": "EA", "note": "모터"}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
## 4. 작업 절차
|
|
|
|
### 4.1 Phase 1: 하위 품목 확인 및 생성
|
|
|
|
| # | 작업 항목 | 상태 | 비고 |
|
|
|---|----------|:----:|------|
|
|
| 1.1 | BOM에 필요한 하위 품목(SF, PT, RM) 목록 정의 | ✅ | 52개 품목 정의됨 |
|
|
| 1.2 | SAM items 테이블에 하위 품목 존재 여부 확인 | ✅ | 52개 모두 존재 확인 |
|
|
| 1.3 | 누락된 하위 품목 생성 (필요시) | ✅ | 누락 품목 없음 (생성 불필요) |
|
|
|
|
### 4.2 Phase 2: BOM 템플릿 정의
|
|
|
|
| # | 작업 항목 | 상태 | 비고 |
|
|
|---|----------|:----:|------|
|
|
| 2.1 | SCREEN 완제품용 BOM 템플릿 정의 | ✅ | FG-SCR-001 (14개 항목) |
|
|
| 2.2 | STEEL 완제품용 BOM 템플릿 정의 | ✅ | FG-STL-001 (12개 항목) |
|
|
| 2.3 | BENDING 완제품용 BOM 템플릿 정의 | ✅ | FG-BND-001 (6개 항목) |
|
|
|
|
### 4.3 Phase 3: 마이그레이션 스크립트 작성
|
|
|
|
| # | 작업 항목 | 상태 | 비고 |
|
|
|---|----------|:----:|------|
|
|
| 3.1 | Migrate5130Bom 커맨드 생성 | ✅ | `api/app/Console/Commands/Migrate5130Bom.php` |
|
|
| 3.2 | 완제품-템플릿 매핑 로직 구현 | ✅ | item_category 기반 매핑 |
|
|
| 3.3 | items.bom 컬럼 업데이트 로직 구현 | ✅ | DB::table 직접 업데이트 |
|
|
| 3.4 | 검증 로직 구현 | ✅ | dry-run, verbose 옵션 지원 |
|
|
|
|
### 4.4 Phase 4: 검증 및 테스트
|
|
|
|
| # | 작업 항목 | 상태 | 비고 |
|
|
|---|----------|:----:|------|
|
|
| 4.1 | Migrate5130Bom 커맨드 실행 | ✅ | 61건 처리 완료 |
|
|
| 4.2 | 견적 페이지에서 실제 테스트 | ⏳ | 사용자 수동 확인 필요 |
|
|
| 4.3 | 결과 문서화 | ✅ | 본 문서 업데이트 |
|
|
|
|
---
|
|
|
|
## 5. 기술 상세
|
|
|
|
### 5.1 FormulaEvaluatorService BOM 처리 로직
|
|
|
|
```php
|
|
// api/app/Services/Quote/FormulaEvaluatorService.php
|
|
|
|
// BOM JSON 필드 사용 위치:
|
|
// 1. getBomItems() - bom JSON 파싱
|
|
// 2. calculateBomQuantity() - quantityFormula 평가
|
|
// 3. childItemCode로 하위 품목 조회
|
|
|
|
// 주요 변수:
|
|
// - W0, H0: 개구부 치수 (입력값)
|
|
// - W1, H1: 제작 치수 (계산값)
|
|
// - W, H: W1, H1과 동일
|
|
// - M: 면적 (m²)
|
|
// - K: 중량 (kg)
|
|
```
|
|
|
|
### 5.2 마이그레이션 스크립트 구조
|
|
|
|
```php
|
|
// api/app/Console/Commands/Migrate5130Bom.php
|
|
|
|
class Migrate5130Bom extends Command
|
|
{
|
|
protected $signature = 'migration:migrate-5130-bom
|
|
{--dry-run : 실제 변경 없이 시뮬레이션}
|
|
{--code= : 특정 품목 코드만 처리}';
|
|
|
|
// 1. item_category별 BOM 템플릿 정의
|
|
private array $bomTemplates = [
|
|
'SCREEN' => [...],
|
|
'STEEL' => [...],
|
|
'BENDING' => [...]
|
|
];
|
|
|
|
// 2. 완제품 조회 (5130 마이그레이션된 FG)
|
|
// 3. 템플릿 기반 BOM JSON 생성
|
|
// 4. items.bom 컬럼 업데이트
|
|
}
|
|
```
|
|
|
|
### 5.3 검증 쿼리
|
|
|
|
```sql
|
|
-- 마이그레이션 전: BOM이 NULL인 완제품
|
|
SELECT code, name, item_category
|
|
FROM items
|
|
WHERE item_type = 'FG'
|
|
AND item_category IN ('SCREEN', 'STEEL', 'BENDING')
|
|
AND (bom IS NULL OR bom = '[]');
|
|
|
|
-- 마이그레이션 후: BOM이 있는 완제품
|
|
SELECT code, name, item_category, JSON_LENGTH(bom) as bom_count
|
|
FROM items
|
|
WHERE item_type = 'FG'
|
|
AND item_category IN ('SCREEN', 'STEEL', 'BENDING')
|
|
AND bom IS NOT NULL
|
|
AND JSON_LENGTH(bom) > 0;
|
|
```
|
|
|
|
---
|
|
|
|
## 6. 컨펌 대기 목록
|
|
|
|
> 모든 승인 항목 완료
|
|
|
|
| # | 항목 | 변경 내용 | 영향 범위 | 상태 |
|
|
|---|------|----------|----------|------|
|
|
| 1 | BOM 템플릿 확정 | SCREEN/STEEL/BENDING별 템플릿 | 견적 계산 | ✅ 완료 |
|
|
| 2 | 하위 품목 코드 확정 | childItemCode 명명 규칙 | items 테이블 | ✅ 완료 |
|
|
| 3 | 마이그레이션 실행 | items.bom 업데이트 | 완제품 61건 | ✅ 완료 |
|
|
|
|
---
|
|
|
|
## 7. 변경 이력
|
|
|
|
| 날짜 | 항목 | 변경 내용 | 파일 | 승인 |
|
|
|------|------|----------|------|------|
|
|
| 2025-01-20 | 초안 | 계획 문서 작성 | - | - |
|
|
| 2025-01-20 | 분석 | 5130/SAM BOM 구조 분석 완료 | - | - |
|
|
| 2025-01-20 | 스크립트 | Migrate5130Bom 커맨드 생성 | `api/app/Console/Commands/Migrate5130Bom.php` | ✅ |
|
|
| 2025-01-20 | 실행 | BOM 마이그레이션 실행 (61건) | items.bom 컬럼 | ✅ |
|
|
| 2025-01-20 | 문서화 | 결과 문서화 완료 | 본 문서 | ✅ |
|
|
|
|
---
|
|
|
|
## 8. 참고 문서
|
|
|
|
- **FormulaEvaluatorService**: `api/app/Services/Quote/FormulaEvaluatorService.php`
|
|
- **기존 마이그레이션**: `api/app/Console/Commands/Migrate5130PriceItems.php`
|
|
- **검증 커맨드**: `api/app/Console/Commands/Verify5130Calculation.php`
|
|
- **품질 체크리스트**: `docs/standards/quality-checklist.md`
|
|
|
|
---
|
|
|
|
## 9. 세션 및 메모리 관리 정책 (Serena Optimized)
|
|
|
|
### 9.1 세션 시작 시 (Load Strategy)
|
|
```javascript
|
|
// 순차적 로드
|
|
read_memory("5130-bom-migration-state") // 1. 상태 파악
|
|
read_memory("5130-bom-migration-rules") // 2. 규칙 확인
|
|
read_memory("5130-bom-migration-mappings") // 3. 매핑 확인
|
|
```
|
|
|
|
### 9.2 Serena 메모리 구조
|
|
- `5130-bom-migration-state`: { phase, progress, next_step, last_decision }
|
|
- `5130-bom-migration-rules`: BOM 템플릿 정의, 변환 규칙
|
|
- `5130-bom-migration-mappings`: 완제품-모델 매핑 테이블
|
|
|
|
---
|
|
|
|
## 10. 검증 결과
|
|
|
|
> 2025-01-20 마이그레이션 실행 완료
|
|
|
|
### 10.1 마이그레이션 실행 결과
|
|
|
|
```
|
|
📊 카테고리별 BOM 적용 현황 (tenant_id=287):
|
|
SCREEN: 35건
|
|
STEEL: 11건
|
|
BENDING: 15건
|
|
|
|
✅ BOM 적용 완료: 61건
|
|
⏳ BOM 미적용: 0건
|
|
```
|
|
|
|
### 10.2 테스트 케이스
|
|
|
|
| 입력값 | 예상 결과 | 실제 결과 | 상태 |
|
|
|--------|----------|----------|------|
|
|
| S0001 BOM JSON 확인 | childItemCode 5개 이상 | 14개 항목 적용됨 | ✅ |
|
|
| S0001 + W0=2500, H0=2000 | 견적 금액 > 0 | 사용자 확인 필요 | ⏳ |
|
|
|
|
### 10.3 성공 기준 달성 현황
|
|
|
|
| 기준 | 달성 | 비고 |
|
|
|------|------|------|
|
|
| 완제품 BOM NULL → JSON 변환 | ✅ | 61건 변환 완료 |
|
|
| BOM JSON 형식 호환 | ✅ | FormulaEvaluatorService 호환 형식 |
|
|
| 견적 계산 정상 동작 | ⏳ | 사용자 수동 확인 필요 |
|
|
|
|
### 10.4 BOM 템플릿 상세
|
|
|
|
| 카테고리 | 소스 템플릿 | BOM 항목 수 | 적용 완제품 수 |
|
|
|----------|------------|------------|--------------|
|
|
| SCREEN | FG-SCR-001 | 14개 | 35건 |
|
|
| STEEL | FG-STL-001 | 12개 | 11건 |
|
|
| BENDING | FG-BND-001 | 6개 | 15건 |
|
|
|
|
---
|
|
|
|
## 11. 자기완결성 점검 결과
|
|
|
|
> Phase 5.5에서 수행된 자기완결성 점검 결과
|
|
|
|
### 11.1 체크리스트 검증
|
|
|
|
| # | 검증 항목 | 상태 | 비고 |
|
|
|---|----------|:----:|------|
|
|
| 1 | 작업 목적이 명확한가? | ✅ | S0001 등 BOM NULL → 견적 0원 문제 해결 |
|
|
| 2 | 성공 기준이 정의되어 있는가? | ✅ | 섹션 10.2 참조 |
|
|
| 3 | 작업 범위가 구체적인가? | ✅ | SCREEN/STEEL/BENDING 완제품 대상 |
|
|
| 4 | 의존성이 명시되어 있는가? | ✅ | FormulaEvaluatorService, 하위 품목 |
|
|
| 5 | 참고 파일 경로가 정확한가? | ✅ | 섹션 8 참조 |
|
|
| 6 | 단계별 절차가 실행 가능한가? | ✅ | 섹션 4 참조 |
|
|
| 7 | 검증 방법이 명시되어 있는가? | ✅ | 섹션 10.1 참조 |
|
|
| 8 | 모호한 표현이 없는가? | ✅ | 구체적 수치/조건 명시 |
|
|
|
|
### 11.2 새 세션 시뮬레이션 테스트
|
|
|
|
| 질문 | 답변 가능 | 참조 섹션 |
|
|
|------|:--------:|----------|
|
|
| Q1. 이 작업의 목적은 무엇인가? | ✅ | 1.1 배경 |
|
|
| Q2. 어디서부터 시작해야 하는가? | ✅ | 4. 작업 절차 |
|
|
| Q3. 어떤 파일을 수정해야 하는가? | ✅ | 5.2 마이그레이션 스크립트 |
|
|
| Q4. 작업 완료 확인 방법은? | ✅ | 10. 검증 결과 |
|
|
| Q5. 막혔을 때 참고 문서는? | ✅ | 8. 참고 문서 |
|
|
|
|
**결과**: 5/5 통과 → ✅ 자기완결성 확보
|
|
|
|
---
|
|
|
|
*이 문서는 /plan 스킬로 생성되었습니다.* |