Files
sam-react-prod/src/types/item.ts
byeongcheolryu ded0bc2439 fix: TypeScript 타입 오류 수정 및 설정 페이지 추가
- BOMItem Omit 타입 시그니처 통일 (useTemplateManagement, SectionsTab, ItemMasterContext)
- HeadersInit → Record<string, string> 타입 변경
- Zustand useShallow 마이그레이션 (zustand/react/shallow)
- DataTable, ListPageTemplate 제네릭 타입 제약 추가
- 설정 관리 페이지 추가 (직급, 직책, 휴가정책, 근무일정, 권한)
- HR 관리 페이지 추가 (급여, 휴가)
- 단가관리 페이지 리팩토링

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 18:07:47 +09:00

353 lines
11 KiB
TypeScript

/**
* 품목 관리 타입 정의
*
* React 프로젝트에서 마이그레이션
* Source: sma-react-v2.0/src/components/contexts/DataContext.tsx
*/
// ===== 기본 타입 =====
/**
* 품목 유형
* - FG: Finished Goods (완제품)
* - PT: Parts (부품)
* - SM: Sub-Materials (부자재)
* - RM: Raw Materials (원자재)
* - CS: Consumables (소모품)
*/
export type ItemType = 'FG' | 'PT' | 'SM' | 'RM' | 'CS';
/**
* 제품 카테고리
*/
export type ProductCategory = 'SCREEN' | 'STEEL';
/**
* 부품 유형
* - ASSEMBLY: 조립 부품
* - BENDING: 절곡 부품
* - PURCHASED: 구매 부품
*/
export type PartType = 'ASSEMBLY' | 'BENDING' | 'PURCHASED';
/**
* 부품 용도
*/
export type PartUsage =
| 'GUIDE_RAIL' // 가이드레일
| 'BOTTOM_FINISH' // 하단마감재
| 'CASE' // 케이스
| 'DOOR' // 도어
| 'BRACKET' // 브라켓
| 'GENERAL'; // 일반
// ===== 절곡품 전개도 =====
/**
* 절곡품 전개도 상세 데이터
*/
export interface BendingDetail {
id: string;
no: number; // 번호
input: number; // 입력값
elongation: number; // 연신율 (기본값 -1)
calculated: number; // 연신율 계산 후 값
sum: number; // 합계
shaded: boolean; // 음영 여부
aAngle?: number; // A각
}
// ===== BOM (자재명세서) =====
/**
* 부품구성표 (Bill of Materials)
* 제품의 하위 구성 품목 정보
*/
export interface BOMLine {
id: string;
childItemCode: string; // 하위 품목 코드
childItemName: string; // 하위 품목명
specification?: string; // 규격
material?: string; // 재질
quantity: number; // 기준 수량
unit: string; // 단위
unitPrice?: number; // 단가
quantityFormula?: string; // 수량 계산식 (예: "W * 2", "H + 100")
note?: string; // 비고
width?: number; // 폭 (절곡품)
// 절곡품 관련 (하위 절곡 부품용)
isBending?: boolean; // 절곡품 여부
bendingDiagram?: string; // 전개도 이미지 URL
bendingDetails?: BendingDetail[]; // 전개도 상세 데이터
}
// ===== 품목 수정 이력 =====
/**
* 품목 수정 이력
*/
export interface ItemRevision {
revisionNumber: number; // 수정 차수 (1차, 2차, 3차...)
revisionDate: string; // 수정일
revisionBy: string; // 수정자
revisionReason?: string; // 수정 사유
previousData: any; // 이전 버전의 전체 데이터
}
// ===== 품목 마스터 (메인) =====
/**
* 품목 마스터 데이터
* 모든 품목 유형(FG/PT/SM/RM/CS)을 포괄하는 통합 인터페이스
*/
export interface ItemMaster {
// === 공통 필드 (모든 품목 유형) ===
id: string;
itemCode: string; // 품목 코드 (예: "KD-FG-001")
itemName: string; // 품목명
itemType: ItemType; // 품목 유형
unit: string; // 단위 (EA, SET, KG, M 등)
specification?: string; // 규격
isActive?: boolean; // 활성/비활성
// === 분류 ===
category1?: string; // 대분류
category2?: string; // 중분류
category3?: string; // 소분류
// === 가격 정보 ===
purchasePrice?: number; // 구매 단가
salesPrice?: number; // 판매 단가
marginRate?: number; // 마진율
processingCost?: number; // 가공비
laborCost?: number; // 노무비
installCost?: number; // 설치비
// === BOM (자재명세서) ===
bom?: BOMLine[]; // 하위 품목 구성
bomCategories?: string[]; // BOM 카테고리
// === 제품(FG) 전용 필드 ===
productName?: string; // 상품명 (고객용)
productCategory?: ProductCategory; // 제품 카테고리
lotAbbreviation?: string; // 로트 약자 (예: "KD")
note?: string; // 비고
description?: string; // 설명
// === 부품(PT) 전용 필드 ===
partType?: PartType; // 부품 유형
partUsage?: PartUsage; // 부품 용도
// 조립 부품 관련
installationType?: string; // 설치 유형 (벽면형/측면형)
assemblyType?: string; // 종류 (M/T/C/D/S/U)
sideSpecWidth?: string; // 측면 규격 가로 (mm)
sideSpecHeight?: string; // 측면 규격 세로 (mm)
assemblyLength?: string; // 길이 (2438/3000/3500/4000/4300)
// 가이드레일 관련
guideRailModelType?: string; // 가이드레일 모델 유형
guideRailModel?: string; // 가이드레일 모델
// 절곡품 관련
bendingDiagram?: string; // 전개도 이미지 URL
bendingDetails?: BendingDetail[]; // 전개도 상세 데이터
material?: string; // 재질 (EGI 1.55T, SUS 1.2T)
length?: string; // 길이/목함 (mm)
bendingLength?: string; // 절곡품 길이 규격
// 구매 부품 관련
electricOpenerPower?: string; // 전동개폐기 전원 (220V/380V)
electricOpenerCapacity?: string; // 전동개폐기 용량 (150/300/400/500/600/800/1000 KG)
motorVoltage?: string; // 모터 전압 (220V/380V)
motorCapacity?: string; // 모터 용량 (kg)
chainSpec?: string; // 체인 규격
// === 인정 정보 (제품/부품) ===
certificationNumber?: string; // 인정번호
certificationStartDate?: string; // 인정 유효기간 시작일
certificationEndDate?: string; // 인정 유효기간 종료일
specificationFile?: string; // 시방서 파일 URL
specificationFileName?: string; // 시방서 파일명
certificationFile?: string; // 인정서 파일 URL
certificationFileName?: string; // 인정서 파일명
// === 메타데이터 ===
safetyStock?: number; // 안전재고
leadTime?: number; // 리드타임
isVariableSize?: boolean; // 가변 크기 여부
// 버전 관리
currentRevision: number; // 현재 차수 (0 = 최초, 1 = 1차 수정...)
revisions?: ItemRevision[]; // 수정 이력
isFinal: boolean; // 최종 확정 여부
finalizedDate?: string; // 최종 확정일
finalizedBy?: string; // 최종 확정자
createdAt: string;
updatedAt?: string;
}
// ===== API 응답 타입 =====
/**
* Laravel API 응답 기본 구조
*/
export interface ApiResponse<T> {
success: boolean;
data: T;
message?: string;
errors?: Record<string, string[]>;
}
/**
* 페이지네이션 응답
*/
export interface PaginatedResponse<T> {
data: T[];
current_page: number;
last_page: number;
per_page: number;
total: number;
}
/**
* 품목 목록 조회 파라미터
*/
export interface FetchItemsParams {
itemType?: ItemType;
search?: string;
category1?: string;
category2?: string;
category3?: string;
isActive?: boolean;
page?: number;
per_page?: number;
}
/**
* 품목 생성/수정 데이터
*/
export type CreateItemData = Omit<ItemMaster, 'id' | 'createdAt' | 'updatedAt' | 'currentRevision' | 'revisions' | 'isFinal'>;
export type UpdateItemData = Partial<CreateItemData>;
// ===== 동적 템플릿 시스템 타입 (선택적) =====
/**
* 필드 표시 조건
*/
export interface FieldDisplayCondition {
dependsOn: string; // 의존하는 필드 키
showWhen: string | string[]; // 표시 조건 값
hideWhen?: string | string[]; // 숨김 조건 값
}
/**
* 필드 속성
*/
export interface ItemFieldProperty {
id?: string;
key?: string;
label?: string;
type?: 'textbox' | 'dropdown' | 'checkbox' | 'number' | 'date' | 'textarea';
inputType: 'textbox' | 'dropdown' | 'checkbox' | 'number' | 'date' | 'textarea' | 'section';
required: boolean;
row: number;
col: number;
options?: string[];
defaultValue?: string;
placeholder?: string;
multiColumn?: boolean;
columnCount?: number;
columnNames?: string[];
}
/**
* 필드 정의
*/
export interface ItemField {
id: string;
name: string; // 항목명
fieldKey: string; // 필드 키
property: ItemFieldProperty; // 속성
displayCondition?: FieldDisplayCondition; // 조건부 표시
}
/**
* 섹션 정의
*/
export interface ItemSection {
id: string;
title: string; // 섹션 제목
description?: string; // 설명
category?: string[]; // 카테고리 조건
fields: ItemField[]; // 섹션에 포함된 항목들
type?: 'fields' | 'bom'; // 섹션 타입
order: number; // 섹션 순서
isCollapsible: boolean; // 접기/펼치기 가능 여부
isCollapsed: boolean; // 기본 접힘 상태
}
/**
* 페이지 템플릿 정의
*/
export interface ItemPage {
id: string;
pageName: string; // 페이지명
itemType: ItemType; // 품목 유형
sections: ItemSection[]; // 페이지 내 섹션들
isActive: boolean; // 사용 여부
absolutePath?: string; // 절대경로
createdAt: string;
updatedAt?: string;
}
// ===== 유틸리티 타입 =====
/**
* 품목 코드 체계
* 형식: {업체코드}-{품목유형}-{일련번호}
* 예: KD-FG-001, KD-PT-001
*/
export type ItemCodeFormat = `${string}-${ItemType}-${string}`;
/**
* 품목 유형 라벨 맵
*/
export const ITEM_TYPE_LABELS: Record<ItemType, string> = {
FG: '제품',
PT: '부품',
SM: '부자재',
RM: '원자재',
CS: '소모품',
} as const;
/**
* 제품 카테고리 라벨
*/
export const PRODUCT_CATEGORY_LABELS: Record<ProductCategory, string> = {
SCREEN: '스크린',
STEEL: '철재',
} as const;
/**
* 부품 유형 라벨
*/
export const PART_TYPE_LABELS: Record<PartType, string> = {
ASSEMBLY: '조립 부품',
BENDING: '절곡 부품',
PURCHASED: '구매 부품',
} as const;
/**
* 부품 용도 라벨
*/
export const PART_USAGE_LABELS: Record<PartUsage, string> = {
GUIDE_RAIL: '가이드레일',
BOTTOM_FINISH: '하단마감재',
CASE: '케이스',
DOOR: '도어',
BRACKET: '브라켓',
GENERAL: '일반',
} as const;