# 품목관리 하드코딩 내역 종합 문서 > **MVP용 프론트엔드 구현** - 추후 품목기준관리 설정 또는 백엔드 API로 이관 필요 ## 개요 품목기준관리에서 동적으로 설정해야 하지만 아직 해당 기능이 없어 프론트엔드에 하드코딩된 기능 목록입니다. --- ## 하드코딩 항목 요약 | # | 항목 | 파일 위치 | 우선순위 | 상태 | |---|------|----------|---------|------| | 1 | 품목유형 등록 (FG/PT/SM/RM/CS) | `ItemTypeSelect.tsx` | 🔴 High | 하드코딩 | | 2 | 품목코드/품목명 자동생성 | `itemCodeGenerator.ts`, `DynamicItemForm/index.tsx` | 🔴 High | 하드코딩 | | 3 | 전개도/바라시 섹션 (조립/절곡) | `DynamicItemForm/index.tsx` | 🟡 Medium | 하드코딩 | | 4 | BOM 섹션 내부 구조 | `DynamicBOMSection.tsx` | 🟡 Medium | 하드코딩 | | 5 | 부품유형 판별 로직 | `DynamicItemForm/index.tsx` | 🟢 Low | 하드코딩 | | 6 | FG(제품) 시방서/인정서 파일업로드 | `DynamicItemForm/index.tsx` | 🟡 Medium | 하드코딩 | --- ## 1. 품목유형 등록 (FG/PT/SM/RM/CS) ### 파일 위치 `src/components/items/ItemTypeSelect.tsx` ### 하드코딩 내용 ```typescript const ITEM_TYPE_LABELS_WITH_ENGLISH: Record = { FG: '제품 (Finished Goods)', PT: '부품 (Part)', SM: '부자재 (Sub Material)', RM: '원자재 (Raw Material)', CS: '소모품 (Consumables)', }; ``` ### 문제점 - 품목유형 추가/수정/삭제 불가 - 각 유형별 표시 순서 고정 - 영문명 커스터마이징 불가 ### 마이그레이션 방안 ```yaml Phase 1: 품목기준관리 API 확장 - item_types 테이블 생성 - GET /api/v1/item-master/types 엔드포인트 추가 - 응답: { code: 'FG', name: '제품', englishName: 'Finished Goods', sortOrder: 1 } Phase 2: 프론트엔드 연동 - ItemTypeSelect에서 API 호출 - 품목기준관리에 품목유형 관리 UI 추가 ``` --- ## 2. 품목코드/품목명 자동생성 ### 파일 위치 - **부품(PT)**: `src/components/items/DynamicItemForm/utils/itemCodeGenerator.ts` - **제품(FG)**: `src/components/items/DynamicItemForm/index.tsx` (Lines: 1430-1444) ### 2-0. 제품(FG) 품목코드 규칙 ```typescript // 제품(FG)의 품목코드는 품목명과 동일 (조합식 없음) // DynamicItemForm/index.tsx에서 직접 처리 {/* FG(제품) 전용: 품목명 필드 다음에 품목코드 자동생성 */} {isItemNameField && selectedItemType === 'FG' && (

* 제품(FG)의 품목코드는 품목명과 동일하게 설정됩니다

)} ``` **제품(FG) 특징**: - 품목코드 = 품목명 (단순 복사) - 조합식이나 영문약어 매핑 없음 - `isItemNameField` 플래그로 품목명 필드 다음에 자동으로 표시 ### 2-1. 영문약어 매핑 테이블 ```typescript export const ITEM_CODE_PREFIX_MAP: Record = { // 부품 - 조립품 '가이드레일': 'GR', '케이스': 'CASE', '브라켓': 'BRK', // 부품 - 구매품 '모터': 'MOTOR', '제어기': 'CTL', '전동개폐기': 'OPENER', '스위치': 'SW', '센서': 'SENSOR', '리모컨': 'REMOTE', // 부품 - 절곡품 '레일': 'RAIL', '커버': 'COVER', '플레이트': 'PLATE', // 제품 '스크린': 'SCREEN', '셔터': 'SHUTTER', '방화스크린': 'FIRE-SCR', '롤스크린': 'ROLL-SCR', // 원자재 '알루미늄': 'ALU', '스틸': 'STEEL', '철판': 'STEEL', // 부자재/소모품 '볼트': 'BOLT', '너트': 'NUT', '와셔': 'WASHER', '나사': 'SCREW', }; ``` ### 2-2. 절곡품 코드 체계 ```typescript export const BENDING_CODE_SYSTEM = { // 품목명코드 (category2) 품목명코드: { 'R': '가이드레일', 'S': '스크린', 'C': '케이스', 'B': '박스', 'T': '트림', 'L': '라스틱', 'G': '기타', }, // 종류코드 (category3) 종류코드: { 'M': '마감', 'T': '티', 'C': '채널', 'D': '단면', 'S': '상부', 'U': '하부', 'F': '플랫', 'P': '피스', 'L': '리드', 'B': '브라켓', 'E': '엔드', 'I': '이음', 'A': '각재', }, // 길이코드 매핑 (mm → 코드) 길이코드: { 1219: '12', 2438: '24', 3000: '30', 3500: '35', 4000: '40', 4150: '41', 4200: '42', 4300: '43', }, }; ``` ### 2-3. 조립품 설치유형 매핑 ```typescript export const INSTALLATION_TYPE_MAP: Record = { 'standard': '표준형', 'top': '상부형', 'bottom': '하부형', 'side': '측면형', 'custom': '맞춤형', }; ``` ### 자동생성 함수 목록 | 함수명 | 용도 | 형식 예시 | |--------|------|----------| | `generateItemCode` | PT 품목코드 | `GR-001`, `MOTOR-002` | | `generateBendingItemCode` | 절곡품 품목코드 | `RC24` (가이드레일 채널 2438mm) | | `generateAssemblyItemName` | 조립품 품목명 | `가이드레일표준형50*60*24` | | `generateBendingItemName` | 절곡품 품목명 | `가이드레일 채널 50×30` | | `generatePurchasedItemName` | 구매품 품목명 | `모터 0.4KW` | ### 마이그레이션 방안 ```yaml Phase 1: 품목기준관리 설정 확장 - 영문약어 필드 추가 (품목명 필드 옵션에 매핑) - 코드생성규칙 설정 UI 추가 Phase 2: 백엔드 이관 - 품목 저장 시 백엔드에서 코드 자동 생성 - 순번 관리를 DB 시퀀스로 변경 (동시성 처리) ``` --- ## 3. 전개도/바라시 섹션 (조립/절곡) ### 파일 위치 `src/components/items/DynamicItemForm/index.tsx` (Lines: 1474-1560) ### 하드코딩 내용 #### 3-1. 조립품 전개도 섹션 (바라시) ```typescript {/* 조립품 전개도 섹션 (PT - 조립 부품 전용) */} {selectedItemType === 'PT' && isAssemblyPart && assemblyItemNameKey && ( )} ``` #### 3-2. 절곡품 전개도 섹션 ```typescript {/* 절곡품 전개도 섹션 (PT - 절곡 부품 전용) */} {selectedItemType === 'PT' && isBendingPart && bendingFields.material && ( )} ``` ### 문제점 - 전개도 섹션 표시 조건이 코드에 고정 - 조립/절곡 외 다른 부품유형에 전개도 추가 불가 - 전개도 섹션 필드 구성 변경 불가 ### 데이터 구조 (저장 시) ```typescript // 절곡품 { bending_diagram: string | null, // 전개도 이미지 Base64 bending_details: BendingDetail[], // 전개도 상세 (좌표, 길이 등) width_sum: string | null, // 폭 합계 shape_and_length: string | null, // 모양 & 길이 } // 조립품 (동일 필드 사용) { bending_diagram: string | null, width_sum: string | null, shape_and_length: string | null, } ``` ### 마이그레이션 방안 ```yaml Phase 1: 품목기준관리에 "특수 섹션" 설정 추가 - 섹션 유형: 일반, 전개도, BOM 선택 가능 - 전개도 섹션 표시 조건 설정 (부품유형별) Phase 2: 동적 렌더링 연동 - 품목기준관리 설정에 따라 전개도 섹션 표시 - 필드 구성도 동적으로 변경 가능 ``` --- ## 4. BOM 섹션 내부 구조 ### 파일 위치 `src/components/items/DynamicItemForm/sections/DynamicBOMSection.tsx` ### 하드코딩 내용 #### 4-1. BOM 라인 기본 구조 ```typescript const newLine: BOMLine = { id: `bom-${Date.now()}`, childItemCode: '', childItemName: '', quantity: 1, unit: 'EA', // 기본 단위 고정 specification: '', material: '', note: '', partType: '', bendingDiagram: '', }; ``` #### 4-2. BOM 테이블 컬럼 구조 ```typescript // 고정된 컬럼들 품목코드 품목명 규격 재질 수량 단위 비고 ``` #### 4-3. 품목 검색 결과 매핑 ```typescript const mappedItems: SearchedItem[] = rawItems.map((item) => ({ id: String(item.id), itemCode: (item.code ?? item.item_code ?? '') as string, itemName: (item.name ?? item.item_name ?? '') as string, specification: (item.specification ?? '') as string, material: (item.material ?? '') as string, unit: (item.unit ?? 'EA') as string, partType: (item.part_type ?? '') as string, bendingDiagram: (item.bending_diagram ?? '') as string, })); ``` ### 문제점 - BOM 컬럼 추가/삭제/순서변경 불가 - 기본 단위 'EA' 고정 - BOM 필드별 필수여부 설정 불가 - 절곡품 전개도 표시 영역 고정 ### 마이그레이션 방안 ```yaml Phase 1: 품목기준관리에 "BOM 섹션 설정" 추가 - BOM 컬럼 구성 설정 (표시/숨김, 순서) - 기본값 설정 (단위, 수량 등) Phase 2: 동적 BOM 렌더링 - 품목기준관리 설정에 따라 BOM 테이블 렌더링 - 컬럼별 width, 정렬 등 설정 가능 ``` --- ## 5. 부품유형 판별 로직 ### 파일 위치 `src/components/items/DynamicItemForm/index.tsx` (Lines: 444-505) ### 하드코딩 내용 ```typescript // part_type 필드 탐지 (field_key 기반) const isPartType = fieldKey.includes('part_type') || lowerKey.includes('부품유형') || lowerKey.includes('부품_유형') || fieldName.includes('부품유형') || fieldName.includes('부품 유형'); // 부품유형별 판별 (값 기반) const isBending = currentPartType.includes('절곡') || currentPartType.toUpperCase() === 'BENDING'; const isAssembly = currentPartType.includes('조립') || currentPartType.toUpperCase() === 'ASSEMBLY'; const isPurchased = currentPartType.includes('구매') || currentPartType.toUpperCase() === 'PURCHASED'; ``` ### 문제점 - 부품유형 키워드 매칭이 코드에 고정 - 새로운 부품유형 추가 시 코드 수정 필요 - 다국어 지원 어려움 ### 마이그레이션 방안 ```yaml Phase 1: 품목기준관리에 "부품유형 설정" 추가 - 부품유형 목록 관리 (절곡, 조립, 구매 등) - 각 부품유형별 특수 처리 설정 Phase 2: 동적 부품유형 판별 - API에서 부품유형 목록과 매칭 키워드 제공 - 코드 기반 판별에서 설정 기반 판별로 전환 ``` --- ## 6. FG(제품) 시방서/인정서 파일업로드 ### 파일 위치 `src/components/items/DynamicItemForm/index.tsx` (Lines: 1446-1494) ### 하드코딩 내용 #### 6-1. 파일업로드 상태 관리 ```typescript // FG(제품) 전용 파일 업로드 상태 관리 const [specificationFile, setSpecificationFile] = useState(null); const [certificationFile, setCertificationFile] = useState(null); ``` #### 6-2. 인정 유효기간 종료일 필드 감지 ```typescript // 인정 유효기간 종료일 필드인지 체크 (FG 시방서/인정서 파일 업로드 위치) const isCertEndDateField = fieldKey.includes('certification_end') || fieldKey.includes('인정_유효기간_종료') || fieldName.includes('인정 유효기간 종료') || fieldName.includes('유효기간 종료'); ``` #### 6-3. 시방서/인정서 파일업로드 UI ```typescript {/* FG(제품) 전용: 인정 유효기간 종료일 다음에 시방서/인정서 파일 업로드 */} {isCertEndDateField && selectedItemType === 'FG' && (
{/* 시방서 파일 업로드 */}
{ const file = e.target.files?.[0] || null; setSpecificationFile(file); }} disabled={isSubmitting} className="cursor-pointer" /> {specificationFile && (

선택된 파일: {specificationFile.name}

)}
{/* 인정서 파일 업로드 */}
{ const file = e.target.files?.[0] || null; setCertificationFile(file); }} disabled={isSubmitting} className="cursor-pointer" /> {certificationFile && (

선택된 파일: {certificationFile.name}

)}
)} ``` ### 표시 위치 - **조건**: `selectedItemType === 'FG'` (제품 유형일 때만) - **위치**: 인정 유효기간 종료일 필드 바로 다음 - **파일 형식**: PDF만 허용 (`accept=".pdf"`) ### 문제점 - FG 유형 고정 (다른 품목유형에는 표시 안됨) - 인정 유효기간 종료일 필드명 매칭이 하드코딩 - 파일 업로드 필드가 품목기준관리에서 설정 불가 ### 마이그레이션 방안 ```yaml Phase 1: 품목기준관리에 "파일 첨부 필드" 유형 추가 - 필드 타입: file, image, document 등 - 허용 확장자 설정 (PDF, DOC, 이미지 등) - 품목유형별 표시 조건 설정 Phase 2: 동적 파일업로드 렌더링 - 품목기준관리 설정에 따라 파일 필드 동적 표시 - 백엔드 파일 저장 API 연동 ``` --- ## 추가 하드코딩 발견 사항 ### 속성 옵션 상태 **파일**: `src/components/items/ItemMasterDataManagement/hooks/useAttributeManagement.ts:77` ```typescript // 속성 옵션 상태 (기본값 하드코딩 - TODO: 나중에 백엔드 API로 대체) ``` ### BOM 가격 정보 **파일**: `src/components/items/ItemForm/hooks/useBOMManagement.ts:89` ```typescript unitPrice: 0, // TODO: pricing에서 가져오기 ``` --- ## 종합 마이그레이션 로드맵 ### Phase 1: 품목기준관리 API 확장 (백엔드) 1. `item_types` 테이블 - 품목유형 관리 2. `code_generation_rules` 테이블 - 코드 생성 규칙 3. `special_sections` 설정 - 전개도/BOM 섹션 설정 4. `part_types` 테이블 - 부품유형 관리 ### Phase 2: 품목기준관리 UI 확장 (프론트엔드) 1. 품목유형 관리 탭 추가 2. 코드생성규칙 설정 UI 3. 특수 섹션 설정 UI 4. 부품유형 관리 UI ### Phase 3: 동적 렌더링 연동 1. 품목유형 API 연동 (ItemTypeSelect) 2. 코드 자동생성 API 연동 (itemCodeGenerator 대체) 3. 전개도 섹션 동적 렌더링 4. BOM 섹션 동적 렌더링 ### Phase 4: 프론트엔드 하드코딩 제거 1. 상수 파일들 제거 2. 판별 로직 설정 기반으로 전환 3. 테스트 및 검증 --- ## 관련 파일 목록 | 파일 | 하드코딩 항목 | |------|-------------| | `src/components/items/ItemTypeSelect.tsx` | 품목유형 목록 | | `src/components/items/DynamicItemForm/utils/itemCodeGenerator.ts` | PT 코드 생성 규칙, 매핑 테이블 | | `src/components/items/DynamicItemForm/index.tsx` | FG 품목코드, FG 시방서/인정서 파일업로드, 전개도 섹션, 부품유형 판별 | | `src/components/items/DynamicItemForm/sections/DynamicBOMSection.tsx` | BOM 구조 | | `src/components/items/DynamicItemForm/types.ts` | BOMLine 타입 정의 | > **참고**: `src/components/items/ItemForm/forms/ProductForm.tsx`는 현재 사용되지 않음 (레거시) --- ## 변경 이력 | 날짜 | 내용 | |-----|------| | 2025-12-03 | 품목코드/품목명 자동생성 문서화 | | 2025-12-04 | 전체 하드코딩 항목 종합 문서로 확장 | | 2025-12-04 | 품목유형, 전개도/바라시, BOM 섹션 추가 | | 2025-12-04 | 제품(FG) 품목코드 규칙 추가 (품목명=품목코드) - DynamicItemForm으로 이동 | | 2025-12-04 | FG 전용 시방서/인정서 파일업로드 추가 |